testProvider: fix continuous run handling (#917)

Fixes #900
This commit is contained in:
Connor Peet
2023-10-03 10:27:59 -07:00
committed by GitHub
parent ff51306982
commit a8a74c4d77
2 changed files with 35 additions and 80 deletions

View File

@ -1,25 +1,45 @@
import * as vscode from 'vscode';
import { getContentFromFilesystem, MarkdownTestData, TestCase, testData, TestFile } from './testTree';
import { getContentFromFilesystem, TestCase, testData, TestFile } from './testTree';
export async function activate(context: vscode.ExtensionContext) {
const ctrl = vscode.tests.createTestController('mathTestController', 'Markdown Math');
context.subscriptions.push(ctrl);
const fileChangedEmitter = new vscode.EventEmitter<vscode.Uri>();
const runHandler = (request: vscode.TestRunRequest2, cancellation: vscode.CancellationToken) => {
const watchingTests = new Map<vscode.TestItem | 'ALL', vscode.TestRunProfile | undefined>();
fileChangedEmitter.event(uri => {
if (watchingTests.has('ALL')) {
startTestRun(new vscode.TestRunRequest(undefined, undefined, watchingTests.get('ALL'), true));
return;
}
const include: vscode.TestItem[] = [];
let profile: vscode.TestRunProfile | undefined;
for (const [item, thisProfile] of watchingTests) {
const cast = item as vscode.TestItem;
if (cast.uri?.toString() == uri.toString()) {
include.push(cast);
profile = thisProfile;
}
}
if (include.length) {
startTestRun(new vscode.TestRunRequest(include, undefined, profile, true));
}
});
const runHandler = (request: vscode.TestRunRequest, cancellation: vscode.CancellationToken) => {
if (!request.continuous) {
return startTestRun(request);
}
const l = fileChangedEmitter.event(uri => startTestRun(
new vscode.TestRunRequest2(
[getOrCreateFile(ctrl, uri).file],
undefined,
request.profile,
true
),
));
cancellation.onCancellationRequested(() => l.dispose());
if (request.include === undefined) {
watchingTests.set('ALL', request.profile);
cancellation.onCancellationRequested(() => watchingTests.delete('ALL'));
} else {
request.include.forEach(item => watchingTests.set(item, request.profile));
cancellation.onCancellationRequested(() => request.include!.forEach(item => watchingTests.delete(item)));
}
};
const startTestRun = (request: vscode.TestRunRequest) => {
@ -74,8 +94,9 @@ export async function activate(context: vscode.ExtensionContext) {
const lineNo = test.range!.start.line;
const fileCoverage = coveredLines.get(test.uri!.toString());
if (fileCoverage) {
fileCoverage[lineNo]!.executionCount++;
const lineInfo = fileCoverage?.[lineNo];
if (lineInfo) {
lineInfo.executionCount++;
}
run.appendOutput(`Completed ${test.id}\r\n`);
@ -183,7 +204,7 @@ async function findInitialFiles(controller: vscode.TestController, pattern: vsco
}
}
function startWatchingWorkspace(controller: vscode.TestController, fileChangedEmitter: vscode.EventEmitter<vscode.Uri> ) {
function startWatchingWorkspace(controller: vscode.TestController, fileChangedEmitter: vscode.EventEmitter<vscode.Uri>) {
return getWorkspaceTestPatterns().map(({ workspaceFolder, pattern }) => {
const watcher = vscode.workspace.createFileSystemWatcher(pattern);

View File

@ -1,66 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
export interface TestRunProfile {
/**
* Whether this profile supports continuous running of requests. If so,
* then {@link TestRunRequest.continuous} may be set to `true`. Defaults
* to false.
*/
supportsContinuousRun: boolean;
/**
* Handler called to start a test run. When invoked, the function should call
* {@link TestController.createTestRun} at least once, and all test runs
* associated with the request should be created before the function returns
* or the returned promise is resolved.
*
* If {@link supportsContinuousRun} is set, then {@link TestRunRequest2.continuous}
* may be `true`. In this case, the profile should observe changes to
* source code and create new test runs by calling {@link TestController.createTestRun},
* until the cancellation is requested on the `token`.
*
* @param request Request information for the test run.
* @param cancellationToken Token that signals the used asked to abort the
* test run. If cancellation is requested on this token, all {@link TestRun}
* instances associated with the request will be
* automatically cancelled as well.
*/
runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable<void> | void;
}
export interface TestController {
/**
* Creates a profile used for running tests. Extensions must create
* at least one profile in order for tests to be run.
* @param label A human-readable label for this profile.
* @param kind Configures what kind of execution this profile manages.
* @param runHandler Function called to start a test run.
* @param isDefault Whether this is the default action for its kind.
* @param tag Profile test tag.
* @param supportsContinuousRun Whether the profile supports continuous running.
* @returns An instance of a {@link TestRunProfile}, which is automatically
* associated with this controller.
*/
createRunProfile(label: string, kind: TestRunProfileKind, runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable<void> | void, isDefault?: boolean, tag?: TestTag, supportsContinuousRun?: boolean): TestRunProfile;
}
export class TestRunRequest2 extends TestRunRequest {
/**
* Whether the profile should run continuously as source code changes. Only
* relevant for profiles that set {@link TestRunProfile.supportsContinuousRun}.
*/
readonly continuous?: boolean;
/**
* @param tests Array of specific tests to run, or undefined to run all tests
* @param exclude An array of tests to exclude from the run.
* @param profile The run profile used for this request.
* @param continuous Whether to run tests continuously as source changes.
*/
constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean);
}
}