diff --git a/CHANGELOG.md b/CHANGELOG.md index efc4d720..549c8a45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [4.4.0] + +### Added + +- support for vscode "continuous tests" [feature](https://github.com/microsoft/vscode/issues/134941), [release note](https://code.visualstudio.com/updates/v1_77#_finalized-support-for-continuous-test-runs) + ## [4.3.12] - 2023-03-22 ## [4.3.11] - 2023-03-22 diff --git a/documents/examples/test_wrapper/cppmain_test_wrapper_example/catch2main_wrapper.cpp b/documents/examples/test_wrapper/cppmain_test_wrapper_example/catch2main_wrapper.cpp index 43ed786d..7bd20eaa 100644 --- a/documents/examples/test_wrapper/cppmain_test_wrapper_example/catch2main_wrapper.cpp +++ b/documents/examples/test_wrapper/cppmain_test_wrapper_example/catch2main_wrapper.cpp @@ -4,7 +4,7 @@ * https://github.com/catchorg/Catch2/blob/master/docs/own-main.md */ #define CATCH_CONFIG_RUNNER -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" #include "env_setter.hpp" diff --git a/package-lock.json b/package-lock.json index 5dc8d7db..36426950 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-catch2-test-adapter", - "version": "4.3.11", + "version": "4.3.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-catch2-test-adapter", - "version": "4.3.11", + "version": "4.3.12", "license": "MIT", "dependencies": { "@types/htmlparser2": "^3.10.3", @@ -27,7 +27,7 @@ "@types/request-promise": "4.1.48", "@types/sinon": "^10.0.13", "@types/source-map-support": "^0.5.6", - "@types/vscode": "1.65.0", + "@types/vscode": "1.77.0", "@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/parser": "^5.56.0", "@vscode/test-electron": "^2.3.0", @@ -52,7 +52,7 @@ "webpack-cli": "^5.0.1" }, "engines": { - "vscode": "^1.65.0" + "vscode": "^1.77.0" } }, "node_modules/@babel/code-frame": { @@ -534,9 +534,9 @@ "dev": true }, "node_modules/@types/vscode": { - "version": "1.65.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", - "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", + "version": "1.77.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.77.0.tgz", + "integrity": "sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -7402,9 +7402,9 @@ "dev": true }, "@types/vscode": { - "version": "1.65.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", - "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", + "version": "1.77.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.77.0.tgz", + "integrity": "sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==", "dev": true }, "@typescript-eslint/eslint-plugin": { diff --git a/package.json b/package.json index 9231f386..256cf6f3 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@types/sinon": "^10.0.13", "@types/source-map-support": "^0.5.6", "@vscode/vsce": "^2.18.0", - "@types/vscode": "1.65.0", + "@types/vscode": "1.77.0", "@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/parser": "^5.56.0", "@vscode/test-electron": "^2.3.0", @@ -94,8 +94,9 @@ "webpack-bundle-analyzer": "^4.8.0", "webpack-cli": "^5.0.1" }, + "enabledApiProposals": [], "engines": { - "vscode": "^1.65.0" + "vscode": "^1.77.0" }, "activationEvents": [ "onStartupFinished" diff --git a/src/ConfigOfExecGroup.ts b/src/ConfigOfExecGroup.ts index 65cfc94a..fe1e444b 100644 --- a/src/ConfigOfExecGroup.ts +++ b/src/ConfigOfExecGroup.ts @@ -176,7 +176,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { for (const exec of this._executables.values()) exec.reloadTests(this._shared.taskPool, this._shared.cancellationToken, modiTime); }); - //TODO:future this._shared.sendRetireEvent(this._executables.values()); + this._shared.sendRetireEvent(this._executables.values()); }); } else { absPatterns.push(p.absPath); @@ -191,7 +191,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { w.onAll((fsPath: string): void => { this._shared.log.info('dependsOn watcher event:', fsPath); - //TODO:future this._shared.sendRetireEvent(this._executables.values()); + this._shared.sendRetireEvent(this._executables.values()); }); } } catch (e) { @@ -471,7 +471,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { try { await executable.reloadTests(this._shared.taskPool, this._shared.cancellationToken); this._executables.set(filePath, executable); // it might be set already but we don't care - //TODO:release this._shared.sendRetireEvent([runnable]); + this._shared.sendRetireEvent([executable]); } catch (reason: any /*eslint-disable-line*/) { if (reason?.code === undefined) this._shared.log.debug('problem under reloading', { reason, filePath, runnable: executable }); diff --git a/src/WorkspaceManager.ts b/src/WorkspaceManager.ts index e851957b..a4cb291a 100644 --- a/src/WorkspaceManager.ts +++ b/src/WorkspaceManager.ts @@ -17,12 +17,12 @@ import { AbstractTest } from './framework/AbstractTest'; import { TestItemManager } from './TestItemManager'; import { ProgressReporter } from './util/ProgressReporter'; -//TODO:release if workspace contains ".vscode/testMate.cpp.json" we have to start loading the tests export class WorkspaceManager implements vscode.Disposable { constructor( private readonly workspaceFolder: vscode.WorkspaceFolder, private readonly log: LoggerWrapper, testItemManager: TestItemManager, + executableChanged: (e: Iterable) => void, ) { const workspaceNameRes: ResolveRuleAsync = { resolve: '${workspaceName}', rule: this.workspaceFolder.name }; @@ -137,6 +137,7 @@ export class WorkspaceManager implements vscode.Disposable { log, testItemManager, executeTask, + executableChanged, variableToValue, configuration.getRandomGeneratorSeed(), configuration.getExecWatchTimeout(), diff --git a/src/WorkspaceShared.ts b/src/WorkspaceShared.ts index c3c5f02f..2bdb917e 100644 --- a/src/WorkspaceShared.ts +++ b/src/WorkspaceShared.ts @@ -6,6 +6,7 @@ import { BuildProcessChecker } from './util/BuildProcessChecker'; import { CancellationToken } from './Util'; import { TestItemManager } from './TestItemManager'; import { FrameworkSpecificConfig } from './AdvancedExecutableInterface'; +import { AbstractExecutable } from './framework/AbstractExecutable'; export class WorkspaceShared { constructor( @@ -17,6 +18,7 @@ export class WorkspaceShared { varsToResolve: readonly ResolveRuleAsync[], cancellationToken: CancellationToken, ) => Promise, + readonly sendRetireEvent: (executables: Iterable) => void, readonly varToValue: readonly Readonly[], public rngSeed: 'time' | number | null, public execWatchTimeout: number, diff --git a/src/framework/AbstractExecutable.ts b/src/framework/AbstractExecutable.ts index ecef7e7f..e40690ac 100644 --- a/src/framework/AbstractExecutable.ts +++ b/src/framework/AbstractExecutable.ts @@ -81,6 +81,10 @@ export abstract class AbstractExecutable { + return this._tests.values(); + } + private async _getOrCreateChildGroup( idIn: string | undefined, label: string, @@ -166,6 +170,10 @@ export abstract class AbstractExecutable const controller = vscode.tests.createTestController('testmatecpp', 'TestMate C++'); const workspace2manager = new Map(); const testItemManager = new TestItemManager(controller); + const executableChangedEmitter = new vscode.EventEmitter>(); + const executableChanged = (e: Iterable): void => executableChangedEmitter.fire(e); /// const addWorkspaceManager = (wf: vscode.WorkspaceFolder): void => { if (workspace2manager.get(wf)) log.errorS('Unexpected workspace manager', wf); - else workspace2manager.set(wf, new WorkspaceManager(wf, log, testItemManager)); + else workspace2manager.set(wf, new WorkspaceManager(wf, log, testItemManager, executableChanged)); }; const removeWorkspaceManager = (wf: vscode.WorkspaceFolder): void => { @@ -128,41 +130,67 @@ export async function activate(context: vscode.ExtensionContext): Promise let runCount = 0; let debugCount = 0; - const runProfile = controller.createRunProfile( - 'Run Test', - vscode.TestRunProfileKind.Run, - async (request: vscode.TestRunRequest, cancellation: vscode.CancellationToken): Promise => { - if (debugCount) { - vscode.window.showWarningMessage('Cannot run new tests while debugging.'); - return; - } + const startTestRun = async (request: vscode.TestRunRequest, cancellation: vscode.CancellationToken) => { + if (debugCount) { + vscode.window.showWarningMessage('Cannot run new tests while debugging.'); + return; + } - const testRun = controller.createTestRun(request); - ++runCount; + const testRun = controller.createTestRun(request); + ++runCount; - try { - const managers = collectExecutablesForRun(request); + try { + const managers = collectExecutablesForRun(request); - const runQueue: Thenable[] = []; + const runQueue: Thenable[] = []; - for (const [manager, executables] of managers) { - runQueue.push( - manager.run(executables, cancellation, testRun).catch(e => { - vscode.window.showErrorMessage('Unexpected error from run: ' + e); - }), - ); - } + for (const [manager, executables] of managers) { + runQueue.push( + manager.run(executables, cancellation, testRun).catch(e => { + vscode.window.showErrorMessage('Unexpected error from run: ' + e); + }), + ); + } - await Promise.allSettled(runQueue); - } catch (e) { - log.errorS('runHandler errored. never should be here', e); - } finally { - testRun.end(); - --runCount; + await Promise.allSettled(runQueue); + } catch (e) { + log.errorS('runHandler errored. never should be here', e); + } finally { + testRun.end(); + --runCount; + } + }; + + const runProfile = controller.createRunProfile( + 'Run Test', + vscode.TestRunProfileKind.Run, + async (request: vscode.TestRunRequest, cancellation: vscode.CancellationToken): Promise => { + if (request.continuous) { + const l = executableChangedEmitter.event(executables => { + const include: vscode.TestItem[] = []; + if (request.include === undefined) { + for (const e of executables) { + const eit = e.getExecTestItem(); + if (eit) include.push(eit); + else for (const t of e.getTests()) include.push(t.item); + } + } else { + for (const e of executables) { + for (const t of e.getTests()) { + if (request.include.indexOf(t.item) !== -1) include.push(t.item); + } + } + } + startTestRun(new vscode.TestRunRequest(include, request.exclude, request.profile, true), cancellation); + }); + cancellation.onCancellationRequested(() => l.dispose()); + } else { + return startTestRun(request, cancellation); } }, true, SharedTestTags.runnable, + true, ); // https://github.com/matepek/vscode-catch2-test-adapter/issues/375 diff --git a/test/cpp/catch2/CMakeLists.txt b/test/cpp/catch2/CMakeLists.txt index b7645c57..ea466c4c 100644 --- a/test/cpp/catch2/CMakeLists.txt +++ b/test/cpp/catch2/CMakeLists.txt @@ -1,13 +1,10 @@ -include("Catch2Test.cmake") - -add_catch2test_with_main(suite1 "suite1.cpp") -add_catch2test_with_main(suite2 "suite2.cpp") -add_catch2test_with_main(suite3 "suite3.cpp") -add_catch2test_with_main(suite4 "suite4.cpp") -add_catch2test_with_main(suite5 "suite5.cpp") - -# +# include("Catch2Test.cmake") include("Catch2v3Test.cmake") +add_catch2v3test_with_main(suite1 "suite1.cpp") +add_catch2v3test_with_main(suite2 "suite2.cpp") +add_catch2v3test_with_main(suite3 "suite3.cpp") +add_catch2v3test_with_main(suite4 "suite4.cpp") +add_catch2v3test_with_main(suite5 "suite5.cpp") add_catch2v3test_with_main(catch2v3_test1 "catch2v3_test1.cpp") \ No newline at end of file diff --git a/test/cpp/catch2/suite1.cpp b/test/cpp/catch2/suite1.cpp index c08c4b82..95378010 100644 --- a/test/cpp/catch2/suite1.cpp +++ b/test/cpp/catch2/suite1.cpp @@ -1,6 +1,7 @@ #include +#include -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" // c++ -x c++ -std=c++17 -I ../Catch2/single_include -O0 -g -o suite1 // ../vscode-catch2-test-adapter/src/test/suite1.cpp diff --git a/test/cpp/catch2/suite2.cpp b/test/cpp/catch2/suite2.cpp index 0359778d..48a9ba8e 100644 --- a/test/cpp/catch2/suite2.cpp +++ b/test/cpp/catch2/suite2.cpp @@ -1,4 +1,4 @@ -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" // c++ -x c++ -std=c++17 -I ../Catch2/single_include -O0 -g -o suite2 // ../vscode-catch2-test-adapter/src/test/suite2.cpp diff --git a/test/cpp/catch2/suite3.cpp b/test/cpp/catch2/suite3.cpp index 27105ea5..18aebb60 100644 --- a/test/cpp/catch2/suite3.cpp +++ b/test/cpp/catch2/suite3.cpp @@ -1,7 +1,7 @@ #include #include -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" // clang-format off // c++ -x c++ -std=c++17 -I ../Catch2/single_include -O0 -g -o suite3 ../vscode-catch2-test-adapter/src/test/suite3.cpp diff --git a/test/cpp/catch2/suite4.cpp b/test/cpp/catch2/suite4.cpp index 26172d3f..3663523c 100644 --- a/test/cpp/catch2/suite4.cpp +++ b/test/cpp/catch2/suite4.cpp @@ -1,4 +1,4 @@ -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" #include #include diff --git a/test/cpp/catch2/suite5.cpp b/test/cpp/catch2/suite5.cpp index 87d595a3..939761cb 100644 --- a/test/cpp/catch2/suite5.cpp +++ b/test/cpp/catch2/suite5.cpp @@ -1,4 +1,4 @@ -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" TEST_CASE("suite with label 1", "descr [1][2]") {} TEST_CASE("suite with label 2", "descr [2][3]") {}