diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ff3df3d..28d85c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.3.24] + +### Fixed + +- a bug related to debugging (https://github.com/Microsoft/vscode/issues/70125). + +### Changed + +- test suite loading order from now is not deterministic. One can set `testExplorer.sort` for ordering. + ## [2.3.23] - 2019-03-14 ### Changed diff --git a/package.json b/package.json index fbfad9d3..9cad386b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "icon": "resources/icon.png", "author": "Mate Pek", "publisher": "matepek", - "version": "2.3.23", + "version": "2.3.24-dev", "license": "Unlicense", "homepage": "https://github.com/matepek/vscode-catch2-test-adapter", "repository": { diff --git a/src/RootTestSuiteInfo.ts b/src/RootTestSuiteInfo.ts index 7c195688..1c492696 100644 --- a/src/RootTestSuiteInfo.ts +++ b/src/RootTestSuiteInfo.ts @@ -13,7 +13,7 @@ import { SharedVariables } from './SharedVariables'; export class RootTestSuiteInfo extends AbstractTestSuiteInfoBase implements vscode.Disposable { public readonly children: AbstractTestSuiteInfo[] = []; - private readonly _executables: TestExecutableInfo[] = []; + private _executables: TestExecutableInfo[] = []; private readonly _taskPool: TaskPool; public constructor(shared: SharedVariables, workerMaxNumber: number) { @@ -33,16 +33,12 @@ export class RootTestSuiteInfo extends AbstractTestSuiteInfoBase implements vsco this.children.forEach(c => c.cancel()); } - public async load(executables: TestExecutableInfo[]): Promise { - for (let i = 0; i < executables.length; i++) { - const executable = executables[i]; - try { - await executable.load(); - this._executables.push(executable); - } catch (e) { - this._shared.log.error(e, i, executables); - } - } + public load(executables: TestExecutableInfo[]): Promise { + this._executables.forEach(e => e.dispose()); + + this._executables = executables; + + return Promise.all(executables.map(v => v.load().catch(e => this._shared.log.error(e, v)))).then(() => {}); } public run(tests: string[]): Promise { diff --git a/src/TestAdapter.ts b/src/TestAdapter.ts index df9a0a53..77c6ab0f 100644 --- a/src/TestAdapter.ts +++ b/src/TestAdapter.ts @@ -18,7 +18,7 @@ import * as api from 'vscode-test-adapter-api'; import * as util from 'vscode-test-adapter-util'; import { RootTestSuiteInfo } from './RootTestSuiteInfo'; -import { resolveVariables } from './Util'; +import { resolveVariables, generateUniqueId } from './Util'; import { TaskQueue } from './TaskQueue'; import { TestExecutableInfo } from './TestExecutableInfo'; import { SharedVariables } from './SharedVariables'; @@ -387,32 +387,41 @@ export class TestAdapter implements api.TestAdapter, vscode.Disposable { ['${envObj}', Object.assign(Object.assign({}, process.env), testSuite.execOptions.env!)], ]); + // we dont know better :( + // https://github.com/Microsoft/vscode/issues/70125 + const magicValueKey = 'magic variable 🤦🏼‍♂️'; + const magicValue = generateUniqueId(); + debugConfig[magicValueKey] = magicValue; + this._log.info('Debug: resolved catch2TestExplorer.debugConfigTemplate:', debugConfig); + const terminated = new Promise(resolve => { + const conn = vscode.debug.onDidTerminateDebugSession((session: vscode.DebugSession) => { + const session2 = (session as unknown) as { configuration: { [prop: string]: string } }; + if (session2.configuration && session2.configuration[magicValueKey] === magicValue) { + resolve(session); + conn.dispose(); + } + }); + }); + return this._mainTaskQueue.then(() => { return vscode.debug .startDebugging(this.workspaceFolder, debugConfig) .then((debugSessionStarted: boolean) => { - const currentSession = vscode.debug.activeDebugSession; - - if (!debugSessionStarted || !currentSession) { + if (!debugSessionStarted) { return Promise.reject( - 'Failed starting the debug session - aborting. Maybe something wrong with "catch2TestExplorer.debugConfigTemplate"; ' + - +debugSessionStarted + - '; ' + - currentSession, + new Error( + 'Failed starting the debug session. ' + + 'Maybe something wrong with "catch2TestExplorer.debugConfigTemplate".', + ), ); } this._log.info('debugSessionStarted'); - return new Promise(resolve => { - const subscription = vscode.debug.onDidTerminateDebugSession(session => { - if (currentSession != session) return; - this._log.info('Debug session ended.'); - resolve(); - subscription.dispose(); - }); + return terminated.finally(() => { + this._log.info('debugSessionTerminated'); }); }) .then(undefined, (reason: Error) => { diff --git a/src/TestExecutableInfo.ts b/src/TestExecutableInfo.ts index d5f410f8..4c9395b9 100644 --- a/src/TestExecutableInfo.ts +++ b/src/TestExecutableInfo.ts @@ -94,36 +94,42 @@ export class TestExecutableInfo implements vscode.Disposable { fileUris.push(absPatternAsUri); } + const suiteCreationAndLoadingTasks: Promise[] = []; + for (let i = 0; i < fileUris.length; i++) { const file = fileUris[i]; this._shared.log.info('Checking file for tests:', file.fsPath); - await c2fs.isNativeExecutableAsync(file.fsPath).then( - () => { - return this._createSuiteByUri(file).then( - (suite: AbstractTestSuiteInfo) => { - return suite.reloadChildren().then( - () => { - if (this._rootSuite.insertChild(suite, false /* called later */)) { - this._executables.set(file.fsPath, suite); - } - }, - (reason: Error) => { - this._shared.log.warn("Couldn't load executable:", reason, suite); - }, - ); - }, - (reason: Error) => { - this._shared.log.warn('Not a test executable:', file.fsPath, 'reason:', reason); - }, - ); - }, - (reason: Error) => { - this._shared.log.info('Not an executable:', file.fsPath, reason); - }, + suiteCreationAndLoadingTasks.push( + c2fs.isNativeExecutableAsync(file.fsPath).then( + () => { + return this._createSuiteByUri(file).then( + (suite: AbstractTestSuiteInfo) => { + return suite.reloadChildren().then( + () => { + if (this._rootSuite.insertChild(suite, false /* called later */)) { + this._executables.set(file.fsPath, suite); + } + }, + (reason: Error) => { + this._shared.log.warn("Couldn't load executable:", reason, suite); + }, + ); + }, + (reason: Error) => { + this._shared.log.warn('Not a test executable:', file.fsPath, 'reason:', reason); + }, + ); + }, + (reason: Error) => { + this._shared.log.info('Not an executable:', file.fsPath, reason); + }, + ), ); } + await Promise.all(suiteCreationAndLoadingTasks); + this._rootSuite.uniquifySuiteLabels(); } diff --git a/src/test/TestCatch2FrameworkLoad.test.ts b/src/test/TestCatch2FrameworkLoad.test.ts index 0af5ce4b..79372219 100644 --- a/src/test/TestCatch2FrameworkLoad.test.ts +++ b/src/test/TestCatch2FrameworkLoad.test.ts @@ -1432,7 +1432,7 @@ describe(path.basename(__filename), function() { await adapter.load(); - startDebuggingStub.onFirstCall().resolves(true); + startDebuggingStub.onFirstCall().resolves(false); try { await adapter.debug([adapter.suite1.children[0].id]); diff --git a/src/test/TestExecutablesVariable.test.ts b/src/test/TestExecutablesVariable.test.ts index 2f64d12a..7f22f7a3 100644 --- a/src/test/TestExecutablesVariable.test.ts +++ b/src/test/TestExecutablesVariable.test.ts @@ -15,8 +15,10 @@ describe(path.basename(__filename), function() { let adapter: TestAdapter; before(async function() { - await settings.resetConfig(); + this.timeout(4000); + imitation = new Imitation(); + await settings.resetConfig(); }); beforeEach(function() { diff --git a/src/test/TestLogOutputContent.test.ts b/src/test/TestLogOutputContent.test.ts index 16cce291..ef8e0543 100644 --- a/src/test/TestLogOutputContent.test.ts +++ b/src/test/TestLogOutputContent.test.ts @@ -28,7 +28,7 @@ const expectedErrorLines = new Map>([ [ 'TestCatch2FrameworkLoad.test.js -> vscode.debug -> should be debugged', new Set([ - '[ERROR] Failed starting the debug session - aborting. Maybe something wrong with "catch2TestExplorer.debugConfigTemplate"; 1; undefined', + '[ERROR] Error: Failed starting the debug session. Maybe something wrong with "catch2TestExplorer.debugConfigTemplate".', ]), ], ]);