Skip to content

Commit 19deb43

Browse files
authored
Merge pull request #4860 from JoeRobich/relative-runsettings
Support relative paths with omnisharp.testRunSettings
2 parents 93be0a7 + fc1b074 commit 19deb43

File tree

5 files changed

+165
-11
lines changed

5 files changed

+165
-11
lines changed

package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,14 @@
836836
"default": false,
837837
"description": "(EXPERIMENTAL) Enables support for resolving completion edits asynchronously. This can speed up time to show the completion list, particularly override and partial method completion lists, at the cost of slight delays after inserting a completion item. Most completion items will have no noticeable impact with this feature, but typing immediately after inserting an override or partial method completion, before the insert is completed, can have unpredictable results."
838838
},
839+
"omnisharp.testRunSettings": {
840+
"type": [
841+
"string",
842+
"null"
843+
],
844+
"default": null,
845+
"description": "Path to the .runsettings file which should be used when running unit tests."
846+
},
839847
"razor.plugin.path": {
840848
"type": [
841849
"string",

src/features/dotnetTest.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export default class TestManager extends AbstractProvider {
172172
public async discoverTests(fileName: string, testFrameworkName: string, noBuild: boolean): Promise<protocol.V2.TestInfo[]> {
173173

174174
let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
175-
let runSettings = vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
175+
let runSettings = this._getRunSettings(fileName);
176176

177177
const request: protocol.V2.DiscoverTestsRequest = {
178178
FileName: fileName,
@@ -191,8 +191,21 @@ export default class TestManager extends AbstractProvider {
191191
}
192192
}
193193

194-
private _getRunSettings(): string | undefined {
195-
return vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
194+
private _getRunSettings(filename: string): string | undefined {
195+
const testSettingsPath = vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
196+
if (!testSettingsPath) {
197+
return undefined;
198+
}
199+
200+
if (path.isAbsolute(testSettingsPath)) {
201+
return testSettingsPath;
202+
}
203+
204+
// Path is relative to the workspace. Create absolute path.
205+
const fileUri = vscode.Uri.file(filename);
206+
const workspaceFolder = vscode.workspace.getWorkspaceFolder(fileUri);
207+
208+
return path.join(workspaceFolder.uri.fsPath, testSettingsPath);
196209
}
197210

198211
public async runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, noBuild: boolean = false) {
@@ -204,7 +217,7 @@ export default class TestManager extends AbstractProvider {
204217
});
205218

206219
let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
207-
let runSettings = this._getRunSettings();
220+
let runSettings = this._getRunSettings(fileName);
208221

209222
try {
210223
let results = await this._runTest(fileName, testMethod, runSettings, testFrameworkName, targetFrameworkVersion, noBuild);
@@ -228,7 +241,7 @@ export default class TestManager extends AbstractProvider {
228241
});
229242

230243
let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
231-
let runSettings = this._getRunSettings();
244+
let runSettings = this._getRunSettings(fileName);
232245

233246
try {
234247
let results = await this._runTestsInClass(fileName, runSettings, testFrameworkName, targetFrameworkVersion, methodsInClass, noBuild);
@@ -269,7 +282,7 @@ export default class TestManager extends AbstractProvider {
269282
});
270283

271284
let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName);
272-
let runSettings = this._getRunSettings();
285+
let runSettings = this._getRunSettings(fileName);
273286

274287
const request: protocol.V2.RunTestsInContextRequest = {
275288
FileName: fileName,
@@ -395,7 +408,7 @@ export default class TestManager extends AbstractProvider {
395408
this._eventStream.post(new DotNetTestDebugStart(testMethod));
396409

397410
let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName);
398-
let runSettings = this._getRunSettings();
411+
let runSettings = this._getRunSettings(fileName);
399412

400413
try {
401414
let config = await this._getLaunchConfigurationForVSTest(fileName, testMethod, runSettings, testFrameworkName, targetFrameworkVersion, debugEventListener, noBuild);
@@ -415,7 +428,7 @@ export default class TestManager extends AbstractProvider {
415428
this._eventStream.post(new DotNetTestsInClassDebugStart(className));
416429

417430
let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName);
418-
let runSettings = this._getRunSettings();
431+
let runSettings = this._getRunSettings(fileName);
419432

420433
try {
421434
let config = await this._getLaunchConfigurationForVSTestClass(fileName, methodsToRun, runSettings, testFrameworkName, targetFrameworkVersion, debugEventListener, noBuild);
@@ -440,7 +453,7 @@ export default class TestManager extends AbstractProvider {
440453

441454
let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName);
442455

443-
let runSettings = this._getRunSettings();
456+
let runSettings = this._getRunSettings(fileName);
444457

445458
try {
446459
let config = await this._getLaunchConfigurationForVSTestInContext(fileName, active.line, active.character, runSettings, targetFrameworkVersion, debugEventListener);

test/featureTests/processPicker.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ suite("Remote Process Picker: Validate quoting arguments.", () => {
192192
const process3: Process = parsedOutput[2];
193193
const process4: Process = parsedOutput[3];
194194

195-
var should = require('chai').should();
195+
const should = require('chai').should();
196196
should.not.exist(process1.commandLine);
197197
process1.name.should.equal('System Idle Process');
198198
process1.pid.should.equal('0');
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import * as path from 'path';
8+
9+
import { should, expect } from 'chai';
10+
import { activateCSharpExtension, isSlnWithCsproj } from './integrationHelpers';
11+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
12+
import { EventStream } from '../../src/EventStream';
13+
import { EventType } from '../../src/omnisharp/EventType';
14+
import { BaseEvent, OmnisharpRequestMessage } from '../../src/omnisharp/loggingEvents';
15+
import { poll } from './poll';
16+
import { V2 } from '../../src/omnisharp/protocol';
17+
18+
const chai = require('chai');
19+
chai.use(require('chai-arrays'));
20+
chai.use(require('chai-fs'));
21+
22+
async function waitActivityToSettle(stream: EventStream, timeout: number): Promise<void> {
23+
let event: BaseEvent = { type: 0 };
24+
25+
const subscription = stream.subscribe((e: BaseEvent) => event = e);
26+
27+
await poll(() => event, timeout, 500, e => !e || (event = null));
28+
29+
subscription.unsubscribe();
30+
}
31+
32+
async function waitForEvent<T extends BaseEvent>(stream: EventStream, captureType: EventType, stopCondition: (e: T) => boolean, timeout: number): Promise<T> {
33+
let event: T = null;
34+
35+
const subscription = stream.subscribe((e: BaseEvent) => {
36+
if (e.type === captureType) {
37+
const tEvent = <T>e;
38+
39+
if (stopCondition(tEvent)) {
40+
event = tEvent;
41+
subscription.unsubscribe();
42+
}
43+
}
44+
});
45+
46+
await poll(() => event, timeout, 500, e => !!e);
47+
48+
return event;
49+
}
50+
51+
suite(`DotnetTest: ${testAssetWorkspace.description}`, function () {
52+
let fileUri: vscode.Uri;
53+
let eventStream: EventStream;
54+
55+
suiteSetup(async function () {
56+
should();
57+
58+
// These tests only run on the slnWithCsproj solution
59+
if (!isSlnWithCsproj(vscode.workspace)) {
60+
this.skip();
61+
}
62+
else {
63+
const activation = await activateCSharpExtension();
64+
await testAssetWorkspace.restoreAndWait(activation);
65+
66+
eventStream = activation.eventStream;
67+
68+
let fileName = 'UnitTest1.cs';
69+
let projectDirectory = testAssetWorkspace.projects[2].projectDirectoryPath;
70+
let filePath = path.join(projectDirectory, fileName);
71+
fileUri = vscode.Uri.file(filePath);
72+
73+
await vscode.commands.executeCommand("vscode.open", fileUri);
74+
75+
await waitActivityToSettle(eventStream, 90 * 1000);
76+
}
77+
});
78+
79+
suiteTeardown(async () => {
80+
await testAssetWorkspace.cleanupWorkspace();
81+
});
82+
83+
test("Undefined runsettings path is unchanged", async function () {
84+
const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
85+
await omnisharpConfig.update('testRunSettings', undefined);
86+
87+
const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);
88+
89+
await vscode.commands.executeCommand('dotnet.test.runTestsInContext');
90+
91+
const event = await eventWaiter;
92+
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;
93+
94+
expect(runTestsRequest.RunSettings).to.be.undefined;
95+
});
96+
97+
test("Absolute runsettings path is unchanged", async function () {
98+
const relativeRunSettingsPath = `.\\settings\\TestSettings.runsettings`.replace("\\", path.sep);
99+
const absoluteRunSettingsPath = path.join(process.cwd(), relativeRunSettingsPath);
100+
101+
const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
102+
await omnisharpConfig.update('testRunSettings', absoluteRunSettingsPath);
103+
104+
const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);
105+
106+
await vscode.commands.executeCommand('dotnet.test.runTestsInContext');
107+
108+
const event = await eventWaiter;
109+
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;
110+
111+
expect(runTestsRequest.RunSettings).to.be.equal(absoluteRunSettingsPath);
112+
});
113+
114+
test("Relative runsettings path is made absolute", async function () {
115+
const endingPath = 'settings\\TestSettings.runsettings'.replace("\\", path.sep);
116+
const relativeRunSettingPath = `.\\${endingPath}`.replace("\\", path.sep);
117+
118+
const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
119+
await omnisharpConfig.update('testRunSettings', relativeRunSettingPath);
120+
121+
const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);
122+
123+
await vscode.commands.executeCommand('dotnet.test.runTestsInContext');
124+
125+
const event = await eventWaiter;
126+
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;
127+
128+
expect(runTestsRequest.RunSettings).to.be.not.null;
129+
expect(runTestsRequest.RunSettings.endsWith(endingPath), "Path includes relative path").to.be.true;
130+
expect(path.isAbsolute(runTestsRequest.RunSettings), "Path is absolute").to.be.true;
131+
});
132+
});
133+

test/releaseTests/offlinePackage.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ suite("Offline packaging of VSIX", function () {
4242

4343
test(`Given Platform: ${platformInfo.platform} and Architecture: ${platformInfo.architecture}, the vsix file is created`, () => {
4444
const expectedVsixName = getPackageName(packageJson, packageId);
45-
const vsixFile = vsixFiles.find(file => file.endsWith(expectedVsixName))
45+
const vsixFile = vsixFiles.find(file => file.endsWith(expectedVsixName));
4646
expect(vsixFile, `offline packaging did not build package ${expectedVsixName}`)
4747
.to.not.be.null;
4848
});

0 commit comments

Comments
 (0)