mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user