Skip to content

Commit f01e4f8

Browse files
Ensure that we save files before running or debugging tests
1 parent dc1908d commit f01e4f8

File tree

1 file changed

+69
-53
lines changed

1 file changed

+69
-53
lines changed

src/features/dotnetTest.ts

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import * as path from 'path';
1717
let _testOutputChannel: vscode.OutputChannel = undefined;
1818

1919
function getTestOutputChannel(): vscode.OutputChannel {
20-
if (_testOutputChannel == undefined) {
20+
if (_testOutputChannel === undefined) {
2121
_testOutputChannel = vscode.window.createOutputChannel(".NET Test Log");
2222
}
2323

@@ -36,59 +36,74 @@ export function registerDotNetTestDebugCommand(server: OmniSharpServer): vscode.
3636
(testMethod, fileName, testFrameworkName) => debugDotnetTest(testMethod, fileName, testFrameworkName, server));
3737
}
3838

39-
// Run test through dotnet-test command. This function can be moved to a separate structure
40-
export function runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, server: OmniSharpServer) {
41-
const output = getTestOutputChannel();
42-
43-
output.show();
44-
output.appendLine(`Running test ${testMethod}...`);
45-
46-
const disposable = server.onTestMessage(e => {
47-
output.appendLine(e.Message);
48-
});
39+
function saveDirtyFiles(): Promise<boolean> {
40+
return Promise.resolve(
41+
vscode.workspace.saveAll(/*includeUntitled*/ false));
42+
}
4943

44+
function runTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string): Promise<protocol.V2.DotNetTestResult[]> {
5045
const request: protocol.V2.RunTestRequest = {
5146
FileName: fileName,
5247
MethodName: testMethod,
5348
TestFrameworkName: testFrameworkName
5449
};
5550

56-
serverUtils.runTest(server, request)
57-
.then(response => {
58-
const totalTests = response.Results.length;
51+
return serverUtils.runTest(server, request)
52+
.then(response => response.Results);
53+
}
5954

60-
let totalPassed = 0, totalFailed = 0, totalSkipped = 0;
61-
for (let result of response.Results) {
62-
switch (result.Outcome) {
63-
case protocol.V2.TestOutcomes.Failed:
64-
totalFailed += 1;
65-
break;
66-
case protocol.V2.TestOutcomes.Passed:
67-
totalPassed += 1;
68-
break;
69-
case protocol.V2.TestOutcomes.Skipped:
70-
totalSkipped += 1;
71-
break;
72-
}
73-
}
55+
function reportResults(results: protocol.V2.DotNetTestResult[], output: vscode.OutputChannel): Promise<void> {
56+
const totalTests = results.length;
57+
58+
let totalPassed = 0, totalFailed = 0, totalSkipped = 0;
59+
for (let result of results) {
60+
switch (result.Outcome) {
61+
case protocol.V2.TestOutcomes.Failed:
62+
totalFailed += 1;
63+
break;
64+
case protocol.V2.TestOutcomes.Passed:
65+
totalPassed += 1;
66+
break;
67+
case protocol.V2.TestOutcomes.Skipped:
68+
totalSkipped += 1;
69+
break;
70+
}
71+
}
7472

75-
output.appendLine('');
76-
output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`);
77-
output.appendLine('');
73+
output.appendLine('');
74+
output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`);
75+
output.appendLine('');
7876

79-
disposable.dispose();
80-
},
81-
reason => {
77+
return Promise.resolve();
78+
}
79+
80+
// Run test through dotnet-test command. This function can be moved to a separate structure
81+
export function runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, server: OmniSharpServer) {
82+
const output = getTestOutputChannel();
83+
84+
output.show();
85+
output.appendLine(`Running test ${testMethod}...`);
86+
output.appendLine('');
87+
88+
const listener = server.onTestMessage(e => {
89+
output.appendLine(e.Message);
90+
});
91+
92+
saveDirtyFiles()
93+
.then(_ => runTest(server, fileName, testMethod, testFrameworkName))
94+
.then(results => reportResults(results, output))
95+
.then(() => listener.dispose())
96+
.catch(reason => {
97+
listener.dispose();
8298
vscode.window.showErrorMessage(`Failed to run test because ${reason}.`);
83-
disposable.dispose();
8499
});
85100
}
86101

87102
function createLaunchConfiguration(program: string, args: string, cwd: string, debuggerEventsPipeName: string) {
88103
let debugOptions = vscode.workspace.getConfiguration('csharp').get('unitTestDebugingOptions');
89104

90105
// Get the initial set of options from the workspace setting
91-
let result:any;
106+
let result: any;
92107
if (typeof debugOptions === "object") {
93108
// clone the options object to avoid changing it
94109
result = JSON.parse(JSON.stringify(debugOptions));
@@ -110,7 +125,7 @@ function createLaunchConfiguration(program: string, args: string, cwd: string, d
110125

111126
function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise<any> {
112127
// Listen for test messages while getting start info.
113-
const disposable = server.onTestMessage(e => {
128+
const listener = server.onTestMessage(e => {
114129
output.appendLine(e.Message);
115130
});
116131

@@ -122,14 +137,14 @@ function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: stri
122137

123138
return serverUtils.debugTestGetStartInfo(server, request)
124139
.then(response => {
125-
disposable.dispose();
140+
listener.dispose();
126141
return createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath());
127142
});
128143
}
129144

130145
function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, output: vscode.OutputChannel): Promise<any> {
131146
// Listen for test messages while getting start info.
132-
const disposable = server.onTestMessage(e => {
147+
const listener = server.onTestMessage(e => {
133148
output.appendLine(e.Message);
134149
});
135150

@@ -141,17 +156,17 @@ function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: stri
141156

142157
return serverUtils.getTestStartInfo(server, request)
143158
.then(response => {
144-
disposable.dispose();
159+
listener.dispose();
145160
return createLaunchConfiguration(response.Executable, response.Argument, response.WorkingDirectory, null);
146161
});
147162
}
148163

149164

150165
function getLaunchConfiguration(server: OmniSharpServer, debugType: string, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise<any> {
151166
switch (debugType) {
152-
case "legacy":
167+
case 'legacy':
153168
return getLaunchConfigurationForLegacy(server, fileName, testMethod, testFrameworkName, output);
154-
case "vstest":
169+
case 'vstest':
155170
return getLaunchConfigurationForVSTest(server, fileName, testMethod, testFrameworkName, debugEventListener, output);
156171

157172
default:
@@ -168,21 +183,24 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew
168183

169184
const output = getTestOutputChannel();
170185

171-
output.appendLine(`Debugging method '${testMethod}'.`);
186+
output.show();
187+
output.appendLine(`Debugging method '${testMethod}'...`);
188+
output.appendLine('');
172189

173-
return serverUtils.requestProjectInformation(server, { FileName: fileName })
190+
return saveDirtyFiles()
191+
.then(_ => serverUtils.requestProjectInformation(server, { FileName: fileName }))
174192
.then(projectInfo => {
175193
if (projectInfo.DotNetProject) {
176-
debugType = "legacy";
194+
debugType = 'legacy';
177195
return Promise.resolve();
178196
}
179197
else if (projectInfo.MsBuildProject) {
180-
debugType = "vstest";
198+
debugType = 'vstest';
181199
debugEventListener = new DebugEventListener(fileName, server, output);
182200
return debugEventListener.start();
183201
}
184202
else {
185-
throw new Error();
203+
throw new Error('Expected project.json or .csproj project.');
186204
}
187205
})
188206
.then(() => getLaunchConfiguration(server, debugType, fileName, testMethod, testFrameworkName, debugEventListener, output))
@@ -197,23 +215,21 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew
197215

198216
export function updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node, isDebugEnable: boolean) {
199217
// backward compatible check: Features property doesn't present on older version OmniSharp
200-
if (node.Features == undefined) {
218+
if (node.Features === undefined) {
201219
return;
202220
}
203221

204222
let testFeature = node.Features.find(value => (value.Name == 'XunitTestMethod' || value.Name == 'NUnitTestMethod' || value.Name == 'MSTestMethod'));
205223
if (testFeature) {
206224
// this test method has a test feature
207225
let testFrameworkName = 'xunit';
208-
if(testFeature.Name == 'NunitTestMethod')
209-
{
226+
if (testFeature.Name == 'NunitTestMethod') {
210227
testFrameworkName = 'nunit';
211228
}
212-
else if(testFeature.Name == 'MSTestMethod')
213-
{
229+
else if (testFeature.Name == 'MSTestMethod') {
214230
testFrameworkName = 'mstest';
215231
}
216-
232+
217233
bucket.push(new vscode.CodeLens(
218234
toRange(node.Location),
219235
{ title: "run test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName, testFrameworkName] }));

0 commit comments

Comments
 (0)