in src/goTest/run.ts [138:223]
async debug(request: TestRunRequest, token?: CancellationToken, debugTestFunc: Function = debugTestAtCursor) {
if (!request.include) {
await vscode.window.showErrorMessage('The Go test explorer does not support debugging multiple tests');
return;
}
const collected = new Map<TestItem, CollectedTest[]>();
const files = new Set<TestItem>();
for (const item of request.include) {
await this.collectTests(item, true, request.exclude || [], collected, files);
}
const tests = Array.from(collected.values()).reduce((a, b) => a.concat(b), []);
if (tests.length > 1) {
await vscode.window.showErrorMessage('The Go test explorer does not support debugging multiple tests');
return;
}
const test = tests[0].item;
const { kind, name = '' } = GoTest.parseId(test.id);
if (!test.uri) return;
const doc = await vscode.workspace.openTextDocument(test.uri);
await doc.save();
const goConfig = getGoConfig(test.uri);
const getFunctions = kind === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
const testFunctions = await getFunctions(this.goCtx, doc, token);
// TODO Can we get output from the debug session, in order to check for
// run/pass/fail events?
const id = `debug #${debugSessionID++} ${name}`;
const subs: vscode.Disposable[] = [];
const sessionPromise = new Promise<DebugSession | null>((resolve) => {
subs.push(
vscode.debug.onDidStartDebugSession((s) => {
if (s.configuration.sessionID === id) {
resolve(s);
subs.forEach((s) => s.dispose());
}
})
);
if (token) {
subs.push(
token.onCancellationRequested(() => {
resolve(null);
subs.forEach((s) => s.dispose());
})
);
}
});
const run = this.ctrl.createTestRun(request, `Debug ${name}`);
if (!testFunctions) return;
const started = await debugTestFunc(doc, name, testFunctions, goConfig, id);
if (!started) {
subs.forEach((s) => s.dispose());
run.end();
return;
}
const session = await sessionPromise;
if (!session) {
run.end();
return;
}
token?.onCancellationRequested(() => vscode.debug.stopDebugging(session));
await new Promise<void>((resolve) => {
const sub = vscode.debug.onDidTerminateDebugSession(didTerminateSession);
token?.onCancellationRequested(() => {
resolve();
sub.dispose();
});
function didTerminateSession(s: DebugSession) {
if (s.id !== session?.id) return;
resolve();
sub.dispose();
}
});
run.end();
}