Skip to content

Commit de1317d

Browse files
committed
Add a test about capturing e3-testsuite results into the VS Code API
1 parent 7dbe4af commit de1317d

File tree

2 files changed

+310
-116
lines changed

2 files changed

+310
-116
lines changed

integration/vscode/ada/src/e3Testsuite.ts

Lines changed: 120 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ const showLoadTestListErrorCmdId = 'e3-testsuite.showLoadTestListError';
5959
let lastLoadError: string = '';
6060
export let controller: vscode.TestController;
6161
export let runProfile: vscode.TestRunProfile;
62+
export let runHandler: (
63+
request: vscode.TestRunRequest,
64+
token: vscode.CancellationToken,
65+
) => Promise<void>;
6266

6367
// This method is called when your extension is activated
6468
// Your extension is activated the very first time the command is executed
@@ -156,135 +160,136 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
156160
});
157161
};
158162

159-
runProfile = controller.createRunProfile(
160-
'e3-testsuite',
161-
vscode.TestRunProfileKind.Run,
162-
async function (request, token) {
163-
const ts = getTestsuite();
164-
165-
const enableEventSystem: boolean =
166-
vscode.workspace.getConfiguration('e3-testsuite').get('enableEventSystem') ?? true;
163+
runHandler = async (
164+
request: vscode.TestRunRequest,
165+
token: vscode.CancellationToken,
166+
): Promise<void> => {
167+
const ts = getTestsuite();
167168

168-
const cmd = [ts.python, ts.uri.fsPath, '--failure-exit-code=0'];
169+
const enableEventSystem: boolean =
170+
vscode.workspace.getConfiguration('e3-testsuite').get('enableEventSystem') ?? true;
169171

170-
const remainingSet: Set<vscode.TestItem> = new Set();
171-
function collectAll(i: vscode.TestItem) {
172-
remainingSet.add(i);
173-
i.children.forEach(collectAll);
174-
}
175-
176-
function onlyRootSelected(rq: vscode.TestRunRequest) {
177-
return rq.include?.length === 1 && rq.include[0].id === getRootItemId();
178-
}
172+
const cmd = [ts.python, ts.uri.fsPath, '--failure-exit-code=0'];
179173

180-
if (request.include && !onlyRootSelected(request)) {
181-
const testIds = new Set<string>();
182-
request.include.forEach(collectAll);
183-
remainingSet.forEach((item) => {
184-
const data =
185-
testData.get(item) ??
186-
// If item is a sub-result, it doesn't have data. So use its parent.
187-
(item.parent ? testData.get(item.parent) : undefined);
188-
if (data) {
189-
testIds.add(data.test_matcher ?? data.test_dir);
190-
}
191-
});
174+
const remainingSet: Set<vscode.TestItem> = new Set();
175+
function collectAll(i: vscode.TestItem) {
176+
remainingSet.add(i);
177+
i.children.forEach(collectAll);
178+
}
192179

193-
assert(testIds.size > 0);
194-
cmd.push(...testIds);
195-
} else {
196-
/**
197-
* Do not append tests to the command line. Just run everything.
198-
*/
199-
controller.items.forEach(collectAll);
200-
}
180+
function onlyRootSelected(rq: vscode.TestRunRequest) {
181+
return rq.include?.length === 1 && rq.include[0].id === getRootItemId();
182+
}
201183

202-
const run = controller.createTestRun(request, 'e3-testsuite');
203-
run.appendOutput(`Running: ${cmd.map((c) => '"' + c + '"').join(' ')}\n\r`);
204-
205-
const env = getEnv();
206-
if (enableEventSystem) {
207-
const modulePath = context.asAbsolutePath('media');
208-
const module = 'e3_notify_vscode';
209-
const hook = 'init_callback';
210-
env['PYTHONPATH'] = (env['PYTHONPATH'] ?? '')
211-
.split(path.delimiter)
212-
.filter((v) => !!v)
213-
.concat(modulePath)
214-
.join(path.delimiter);
215-
cmd.push(`--notify-events=python:${module}:${hook}`);
216-
}
184+
if (request.include && !onlyRootSelected(request)) {
185+
const testIds = new Set<string>();
186+
request.include.forEach(collectAll);
187+
remainingSet.forEach((item) => {
188+
const data =
189+
testData.get(item) ??
190+
// If item is a sub-result, it doesn't have data. So use its parent.
191+
(item.parent ? testData.get(item.parent) : undefined);
192+
if (data) {
193+
testIds.add(data.test_matcher ?? data.test_dir);
194+
}
195+
});
217196

197+
assert(testIds.size > 0);
198+
cmd.push(...testIds);
199+
} else {
218200
/**
219-
* Append CLI args defined in settings
201+
* Do not append tests to the command line. Just run everything.
220202
*/
221-
cmd.push(
222-
...(vscode.workspace.getConfiguration('e3-testsuite').get<string[]>('args') ?? []),
223-
);
203+
controller.items.forEach(collectAll);
204+
}
224205

225-
const cwd = vscode.workspace.workspaceFolders![0].uri.fsPath;
226-
await new Promise<void>((resolve, reject) => {
227-
const p = spawn(cmd[0], cmd.splice(1), {
228-
cwd: cwd,
229-
env: env,
230-
});
231-
token.onCancellationRequested(() => {
232-
p.kill();
233-
run.appendOutput('\r\n*** Test run was cancelled');
234-
remainingSet.forEach((item) =>
235-
run.errored(item, new vscode.TestMessage('Test run was cancelled.')),
236-
);
237-
resolve();
238-
});
206+
const run = controller.createTestRun(request, 'e3-testsuite');
207+
run.appendOutput(`Running: ${cmd.map((c) => '"' + c + '"').join(' ')}\n\r`);
208+
209+
const env = getEnv();
210+
if (enableEventSystem) {
211+
const modulePath = context.asAbsolutePath('media');
212+
const module = 'e3_notify_vscode';
213+
const hook = 'init_callback';
214+
env['PYTHONPATH'] = (env['PYTHONPATH'] ?? '')
215+
.split(path.delimiter)
216+
.filter((v) => !!v)
217+
.concat(modulePath)
218+
.join(path.delimiter);
219+
cmd.push(`--notify-events=python:${module}:${hook}`);
220+
}
239221

240-
if (!enableEventSystem) {
241-
remainingSet.forEach((t) => run.started(t));
242-
}
222+
/**
223+
* Append CLI args defined in settings
224+
*/
225+
cmd.push(
226+
...(vscode.workspace.getConfiguration('e3-testsuite').get<string[]>('args') ?? []),
227+
);
243228

244-
function handleLine(line: string | Buffer) {
245-
const decodedLine: string =
246-
typeof line === 'string' ? line : line.toLocaleString();
229+
const cwd = vscode.workspace.workspaceFolders![0].uri.fsPath;
230+
await new Promise<void>((resolve, reject) => {
231+
const p = spawn(cmd[0], cmd.splice(1), {
232+
cwd: cwd,
233+
env: env,
234+
});
235+
token.onCancellationRequested(() => {
236+
p.kill();
237+
run.appendOutput('\r\n*** Test run was cancelled');
238+
remainingSet.forEach((item) =>
239+
run.errored(item, new vscode.TestMessage('Test run was cancelled.')),
240+
);
241+
resolve();
242+
});
247243

248-
if (enableEventSystem) {
249-
handleTestsuiteEvents(run, decodedLine, remainingSet);
250-
} else {
251-
handleTestsuiteOutput(run, decodedLine, remainingSet);
252-
}
244+
if (!enableEventSystem) {
245+
remainingSet.forEach((t) => run.started(t));
246+
}
247+
248+
function handleLine(line: string | Buffer) {
249+
const decodedLine: string = typeof line === 'string' ? line : line.toLocaleString();
250+
251+
if (enableEventSystem) {
252+
handleTestsuiteEvents(run, decodedLine, remainingSet);
253+
} else {
254+
handleTestsuiteOutput(run, decodedLine, remainingSet);
253255
}
254-
p.stdout.pipe(split()).on('data', handleLine);
255-
p.stderr.pipe(split()).on('data', handleLine);
256-
p.on('error', reject);
257-
p.on('close', (code) => {
258-
if (code === 0) {
259-
resolve();
260-
} else {
261-
const md = new vscode.MarkdownString(
262-
`Test run failed, see ` +
263-
`[Output](command:testing.showMostRecentOutput)`,
264-
);
265-
md.isTrusted = true;
266-
const msg = new vscode.TestMessage(md);
267-
remainingSet.forEach((t) => run.errored(t, msg));
268-
run.end();
269-
reject(
270-
Error('Test run failed, see Test Results view for testsuite output.'),
271-
);
272-
}
273-
});
274-
})
275-
.then(() => {
276-
if (!enableEventSystem) {
277-
const e3ResultsPath = path.join(cwd, 'out', 'new');
278-
processTestsuiteResultIndex(e3ResultsPath, run);
279-
}
280-
})
281-
.finally(() => {
282-
/**
283-
* Always end the run, be it a nominal or an error end.
284-
*/
256+
}
257+
p.stdout.pipe(split()).on('data', handleLine);
258+
p.stderr.pipe(split()).on('data', handleLine);
259+
p.on('error', reject);
260+
p.on('close', (code) => {
261+
if (code === 0) {
262+
resolve();
263+
} else {
264+
const md = new vscode.MarkdownString(
265+
`Test run failed, see ` + `[Output](command:testing.showMostRecentOutput)`,
266+
);
267+
md.isTrusted = true;
268+
const msg = new vscode.TestMessage(md);
269+
remainingSet.forEach((t) => run.errored(t, msg));
285270
run.end();
286-
});
287-
},
271+
reject(Error('Test run failed, see Test Results view for testsuite output.'));
272+
}
273+
});
274+
})
275+
.then(() => {
276+
if (!enableEventSystem) {
277+
const e3ResultsPath = path.join(cwd, 'out', 'new');
278+
processTestsuiteResultIndex(e3ResultsPath, run);
279+
}
280+
})
281+
.finally(() => {
282+
/**
283+
* Always end the run, be it a nominal or an error end.
284+
*/
285+
run.end();
286+
});
287+
};
288+
289+
runProfile = controller.createRunProfile(
290+
'e3-testsuite',
291+
vscode.TestRunProfileKind.Run,
292+
runHandler,
288293
);
289294

290295
function processTestsuiteResultIndex(e3ResultsPath: string, run: vscode.TestRun) {

0 commit comments

Comments
 (0)