From 2d75fb074993c2706580632ee3acd898eeaf1076 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 19 Mar 2024 11:10:05 -0700 Subject: [PATCH] testing: finalize test coverage Closes #123713 --- extensions/vscode-api-tests/package.json | 1 - package.json | 2 +- src/vs/workbench/api/common/extHostTesting.ts | 26 +-- .../api/test/browser/extHostTesting.test.ts | 33 ++- .../common/extensionsApiProposals.ts | 1 - src/vscode-dts/vscode.d.ts | 190 +++++++++++++++++ .../vscode.proposed.testCoverage.d.ts | 201 ------------------ 7 files changed, 216 insertions(+), 238 deletions(-) delete mode 100644 src/vscode-dts/vscode.proposed.testCoverage.d.ts diff --git a/extensions/vscode-api-tests/package.json b/extensions/vscode-api-tests/package.json index b0b56a3fdd9b8..5ea2340b27094 100644 --- a/extensions/vscode-api-tests/package.json +++ b/extensions/vscode-api-tests/package.json @@ -45,7 +45,6 @@ "terminalDataWriteEvent", "terminalDimensions", "tunnels", - "testCoverage", "testObserver", "textSearchProvider", "timeline", diff --git a/package.json b/package.json index 19021da8ec39d..25ab5b12dc648 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.88.0", - "distro": "7ca938298e57ad434ea8807e132707055458a749", + "distro": "ff3bff60edcc6e1f7269509e1673036c00fa62bd", "author": { "name": "Microsoft Corporation" }, diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index c15138fe33b16..3cd53e11d89ad 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -28,7 +28,6 @@ import { TestCommandId } from 'vs/workbench/contrib/testing/common/constants'; import { TestId, TestIdPathParts, TestPosition } from 'vs/workbench/contrib/testing/common/testId'; import { InvalidTestItemError } from 'vs/workbench/contrib/testing/common/testItemCollection'; import { AbstractIncrementalTestCollection, CoverageDetails, ICallProfileRunHandler, ISerializedTestResults, IStartControllerTests, IStartControllerTestsResult, ITestErrorMessage, ITestItem, ITestItemContext, ITestMessageMenuArgs, ITestRunProfile, IncrementalChangeCollector, IncrementalTestCollectionItem, InternalTestItem, TestResultState, TestRunProfileBitset, TestsDiff, TestsDiffOp, isStartControllerTests } from 'vs/workbench/contrib/testing/common/testTypes'; -import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import type * as vscode from 'vscode'; interface ControllerInfo { @@ -155,7 +154,7 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape { return new TestItemImpl(controllerId, id, label, uri); }, createTestRun: (request, name, persist = true) => { - return this.runTracker.createTestRun(extension, controllerId, collection, request, name, persist); + return this.runTracker.createTestRun(controllerId, collection, request, name, persist); }, invalidateTestResults: items => { if (items === undefined) { @@ -354,7 +353,7 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape { return {}; } - const { collection, profiles, extension } = lookup; + const { collection, profiles } = lookup; const profile = profiles.get(req.profileId); if (!profile) { return {}; @@ -385,7 +384,6 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape { const tracker = isStartControllerTests(req) && this.runTracker.prepareForMainThreadTestRun( publicReq, TestRunDto.fromInternal(req, lookup.collection), - extension, profile, token, ); @@ -463,7 +461,6 @@ class TestRunTracker extends Disposable { constructor( private readonly dto: TestRunDto, private readonly proxy: MainThreadTestingShape, - private readonly extension: IRelaxedExtensionDescription, private readonly logService: ILogService, private readonly profile: vscode.TestRunProfile | undefined, parentToken?: CancellationToken, @@ -517,7 +514,6 @@ class TestRunTracker extends Disposable { const runId = this.dto.id; const ctrlId = this.dto.controllerId; const taskId = generateUuid(); - const extension = this.extension; const guardTestMutation = (fn: (test: vscode.TestItem, ...args: Args) => void) => (test: vscode.TestItem, ...args: Args) => { @@ -574,7 +570,6 @@ class TestRunTracker extends Disposable { }, // todo@connor4312: back compat set coverageProvider(provider: ICoverageProvider | undefined) { - checkProposedApiEnabled(extension, 'testCoverage'); coverageProvider = provider; if (provider) { Promise.resolve(provider.provideFileCoverage(CancellationToken.None)).then(coverage => { @@ -585,10 +580,7 @@ class TestRunTracker extends Disposable { }); } }, - addCoverage: coverage => { - checkProposedApiEnabled(extension, 'testCoverage'); - addCoverage(coverage); - }, + addCoverage, //#region state mutation enqueued: guardTestMutation(test => { this.proxy.$updateTestStateInRun(runId, taskId, TestId.fromExtHostTestItem(test, ctrlId).toString(), TestResultState.Queued); @@ -745,8 +737,8 @@ export class TestRunCoordinator { * `$startedExtensionTestRun` is not invoked. The run must eventually * be cancelled manually. */ - public prepareForMainThreadTestRun(req: vscode.TestRunRequest, dto: TestRunDto, extension: Readonly, profile: vscode.TestRunProfile, token: CancellationToken) { - return this.getTracker(req, dto, extension, profile, token); + public prepareForMainThreadTestRun(req: vscode.TestRunRequest, dto: TestRunDto, profile: vscode.TestRunProfile, token: CancellationToken) { + return this.getTracker(req, dto, profile, token); } /** @@ -768,7 +760,7 @@ export class TestRunCoordinator { /** * Implements the public `createTestRun` API. */ - public createTestRun(extension: IRelaxedExtensionDescription, controllerId: string, collection: ExtHostTestItemCollection, request: vscode.TestRunRequest, name: string | undefined, persist: boolean): vscode.TestRun { + public createTestRun(controllerId: string, collection: ExtHostTestItemCollection, request: vscode.TestRunRequest, name: string | undefined, persist: boolean): vscode.TestRun { const existing = this.tracked.get(request); if (existing) { return existing.createRun(name); @@ -788,7 +780,7 @@ export class TestRunCoordinator { persist }); - const tracker = this.getTracker(request, dto, extension, request.profile); + const tracker = this.getTracker(request, dto, request.profile); Event.once(tracker.onEnd)(() => { this.proxy.$finishedExtensionTestRun(dto.id); }); @@ -796,8 +788,8 @@ export class TestRunCoordinator { return tracker.createRun(name); } - private getTracker(req: vscode.TestRunRequest, dto: TestRunDto, extension: IRelaxedExtensionDescription, profile: vscode.TestRunProfile | undefined, token?: CancellationToken) { - const tracker = new TestRunTracker(dto, this.proxy, extension, this.logService, profile, token); + private getTracker(req: vscode.TestRunRequest, dto: TestRunDto, profile: vscode.TestRunProfile | undefined, token?: CancellationToken) { + const tracker = new TestRunTracker(dto, this.proxy, this.logService, profile, token); this.tracked.set(req, tracker); this.trackedById.set(tracker.id, tracker); return tracker; diff --git a/src/vs/workbench/api/test/browser/extHostTesting.test.ts b/src/vs/workbench/api/test/browser/extHostTesting.test.ts index e931132b918d3..b79db583bb0b9 100644 --- a/src/vs/workbench/api/test/browser/extHostTesting.test.ts +++ b/src/vs/workbench/api/test/browser/extHostTesting.test.ts @@ -13,7 +13,7 @@ import { URI } from 'vs/base/common/uri'; import { mock, mockObject, MockObject } from 'vs/base/test/common/mock'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import * as editorRange from 'vs/editor/common/core/range'; -import { ExtensionIdentifier, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { NullLogService } from 'vs/platform/log/common/log'; import { MainThreadTestingShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; @@ -603,7 +603,6 @@ suite('ExtHost Testing', () => { let req: TestRunRequest; let dto: TestRunDto; - const ext: IRelaxedExtensionDescription = {} as any; teardown(() => { for (const { id } of c.trackers) { @@ -637,11 +636,11 @@ suite('ExtHost Testing', () => { }); test('tracks a run started from a main thread request', () => { - const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, ext, configuration, cts.token)); + const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, configuration, cts.token)); assert.strictEqual(tracker.hasRunningTasks, false); - const task1 = c.createTestRun(ext, 'ctrl', single, req, 'run1', true); - const task2 = c.createTestRun(ext, 'ctrl', single, req, 'run2', true); + const task1 = c.createTestRun('ctrl', single, req, 'run1', true); + const task2 = c.createTestRun('ctrl', single, req, 'run2', true); assert.strictEqual(proxy.$startedExtensionTestRun.called, false); assert.strictEqual(tracker.hasRunningTasks, true); @@ -662,8 +661,8 @@ suite('ExtHost Testing', () => { test('run cancel force ends after a timeout', () => { const clock = sinon.useFakeTimers(); try { - const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, ext, configuration, cts.token)); - const task = c.createTestRun(ext, 'ctrl', single, req, 'run1', true); + const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, configuration, cts.token)); + const task = c.createTestRun('ctrl', single, req, 'run1', true); const onEnded = sinon.stub(); ds.add(tracker.onEnd(onEnded)); @@ -687,8 +686,8 @@ suite('ExtHost Testing', () => { }); test('run cancel force ends on second cancellation request', () => { - const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, ext, configuration, cts.token)); - const task = c.createTestRun(ext, 'ctrl', single, req, 'run1', true); + const tracker = ds.add(c.prepareForMainThreadTestRun(req, dto, configuration, cts.token)); + const task = c.createTestRun('ctrl', single, req, 'run1', true); const onEnded = sinon.stub(); ds.add(tracker.onEnd(onEnded)); @@ -706,7 +705,7 @@ suite('ExtHost Testing', () => { }); test('tracks a run started from an extension request', () => { - const task1 = c.createTestRun(ext, 'ctrl', single, req, 'hello world', false); + const task1 = c.createTestRun('ctrl', single, req, 'hello world', false); const tracker = Iterable.first(c.trackers)!; assert.strictEqual(tracker.hasRunningTasks, true); @@ -722,8 +721,8 @@ suite('ExtHost Testing', () => { }] ]); - const task2 = c.createTestRun(ext, 'ctrl', single, req, 'run2', true); - const task3Detached = c.createTestRun(ext, 'ctrl', single, { ...req }, 'task3Detached', true); + const task2 = c.createTestRun('ctrl', single, req, 'run2', true); + const task3Detached = c.createTestRun('ctrl', single, { ...req }, 'task3Detached', true); task1.end(); assert.strictEqual(proxy.$finishedExtensionTestRun.called, false); @@ -737,7 +736,7 @@ suite('ExtHost Testing', () => { }); test('adds tests to run smartly', () => { - const task1 = c.createTestRun(ext, 'ctrlId', single, req, 'hello world', false); + const task1 = c.createTestRun('ctrlId', single, req, 'hello world', false); const tracker = Iterable.first(c.trackers)!; const expectedArgs: unknown[][] = []; assert.deepStrictEqual(proxy.$addTestsToRun.args, expectedArgs); @@ -776,7 +775,7 @@ suite('ExtHost Testing', () => { const test2 = new TestItemImpl('ctrlId', 'id-d', 'test d', URI.file('/testd.txt')); test1.range = test2.range = new Range(new Position(0, 0), new Position(1, 0)); single.root.children.replace([test1, test2]); - const task = c.createTestRun(ext, 'ctrlId', single, req, 'hello world', false); + const task = c.createTestRun('ctrlId', single, req, 'hello world', false); const message1 = new TestMessage('some message'); message1.location = new Location(URI.file('/a.txt'), new Position(0, 0)); @@ -817,7 +816,7 @@ suite('ExtHost Testing', () => { }); test('guards calls after runs are ended', () => { - const task = c.createTestRun(ext, 'ctrl', single, req, 'hello world', false); + const task = c.createTestRun('ctrl', single, req, 'hello world', false); task.end(); task.failed(single.root, new TestMessage('some message')); @@ -829,7 +828,7 @@ suite('ExtHost Testing', () => { }); test('excludes tests outside tree or explicitly excluded', () => { - const task = c.createTestRun(ext, 'ctrlId', single, { + const task = c.createTestRun('ctrlId', single, { profile: configuration, include: [single.root.children.get('id-a')!], exclude: [single.root.children.get('id-a')!.children.get('id-aa')!], @@ -858,7 +857,7 @@ suite('ExtHost Testing', () => { const childB = new TestItemImpl('ctrlId', 'id-child', 'child', undefined); testB!.children.replace([childB]); - const task1 = c.createTestRun(ext, 'ctrl', single, new TestRunRequestImpl(), 'hello world', false); + const task1 = c.createTestRun('ctrl', single, new TestRunRequestImpl(), 'hello world', false); const tracker = Iterable.first(c.trackers)!; task1.passed(childA); diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 0968a659412d8..62e37286be5f7 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -113,7 +113,6 @@ export const allApiProposals = Object.freeze({ terminalExecuteCommandEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalExecuteCommandEvent.d.ts', terminalQuickFixProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts', terminalSelection: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalSelection.d.ts', - testCoverage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testCoverage.d.ts', testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts', textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts', timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts', diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index af3e492574b76..1dbf3c22c45c5 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -17194,6 +17194,14 @@ declare module 'vscode' { */ runHandler: (request: TestRunRequest, token: CancellationToken) => Thenable | void; + /** + * A function that provides detailed statement and function-level coverage for a file. + * + * The {@link FileCoverage} object passed to this function is the same instance + * emitted on {@link TestRun.addCoverage} calls associated with this profile. + */ + loadDetailedCoverage?: (testRun: TestRun, fileCoverage: FileCoverage, token: CancellationToken) => Thenable; + /** * Deletes the run profile. */ @@ -17473,11 +17481,22 @@ declare module 'vscode' { */ appendOutput(output: string, location?: Location, test?: TestItem): void; + /** + * Adds coverage for a file in the run. + */ + addCoverage(fileCoverage: FileCoverage): void; + /** * Signals the end of the test run. Any tests included in the run whose * states have not been updated will have their state reset. */ end(): void; + + /** + * An event fired when the editor is no longer interested in data + * associated with the test run. + */ + onDidDispose: Event; } /** @@ -17687,6 +17706,177 @@ declare module 'vscode' { constructor(message: string | MarkdownString); } + /** + * A class that contains information about a covered resource. A count can + * be give for lines, branches, and declarations in a file. + */ + export class TestCoverageCount { + /** + * Number of items covered in the file. + */ + covered: number; + /** + * Total number of covered items in the file. + */ + total: number; + + /** + * @param covered Value for {@link TestCoverageCount.covered} + * @param total Value for {@link TestCoverageCount.total} + */ + constructor(covered: number, total: number); + } + + /** + * Contains coverage metadata for a file. + */ + export class FileCoverage { + /** + * File URI. + */ + readonly uri: Uri; + + /** + * Statement coverage information. If the reporter does not provide statement + * coverage information, this can instead be used to represent line coverage. + */ + statementCoverage: TestCoverageCount; + + /** + * Branch coverage information. + */ + branchCoverage?: TestCoverageCount; + + /** + * Declaration coverage information. Depending on the reporter and + * language, this may be types such as functions, methods, or namespaces. + */ + declarationCoverage?: TestCoverageCount; + + /** + * Creates a {@link FileCoverage} instance with counts filled in from + * the coverage details. + * @param uri Covered file URI + * @param detailed Detailed coverage information + */ + static fromDetails(uri: Uri, details: readonly FileCoverageDetail[]): FileCoverage; + + /** + * @param uri Covered file URI + * @param statementCoverage Statement coverage information. If the reporter + * does not provide statement coverage information, this can instead be + * used to represent line coverage. + * @param branchCoverage Branch coverage information + * @param declarationCoverage Declaration coverage information + */ + constructor( + uri: Uri, + statementCoverage: TestCoverageCount, + branchCoverage?: TestCoverageCount, + declarationCoverage?: TestCoverageCount, + ); + } + + /** + * Contains coverage information for a single statement or line. + */ + export class StatementCoverage { + /** + * The number of times this statement was executed, or a boolean indicating + * whether it was executed if the exact count is unknown. If zero or false, + * the statement will be marked as un-covered. + */ + executed: number | boolean; + + /** + * Statement location. + */ + location: Position | Range; + + /** + * Coverage from branches of this line or statement. If it's not a + * conditional, this will be empty. + */ + branches: BranchCoverage[]; + + /** + * @param location The statement position. + * @param executed The number of times this statement was executed, or a + * boolean indicating whether it was executed if the exact count is + * unknown. If zero or false, the statement will be marked as un-covered. + * @param branches Coverage from branches of this line. If it's not a + * conditional, this should be omitted. + */ + constructor(executed: number | boolean, location: Position | Range, branches?: BranchCoverage[]); + } + + /** + * Contains coverage information for a branch of a {@link StatementCoverage}. + */ + export class BranchCoverage { + /** + * The number of times this branch was executed, or a boolean indicating + * whether it was executed if the exact count is unknown. If zero or false, + * the branch will be marked as un-covered. + */ + executed: number | boolean; + + /** + * Branch location. + */ + location?: Position | Range; + + /** + * Label for the branch, used in the context of "the ${label} branch was + * not taken," for example. + */ + label?: string; + + /** + * @param executed The number of times this branch was executed, or a + * boolean indicating whether it was executed if the exact count is + * unknown. If zero or false, the branch will be marked as un-covered. + * @param location The branch position. + */ + constructor(executed: number | boolean, location?: Position | Range, label?: string); + } + + /** + * Contains coverage information for a declaration. Depending on the reporter + * and language, this may be types such as functions, methods, or namespaces. + */ + export class DeclarationCoverage { + /** + * Name of the declaration. + */ + name: string; + + /** + * The number of times this declaration was executed, or a boolean + * indicating whether it was executed if the exact count is unknown. If + * zero or false, the declaration will be marked as un-covered. + */ + executed: number | boolean; + + /** + * Declaration location. + */ + location: Position | Range; + + /** + * @param executed The number of times this declaration was executed, or a + * boolean indicating whether it was executed if the exact count is + * unknown. If zero or false, the declaration will be marked as un-covered. + * @param location The declaration position. + */ + constructor(name: string, executed: number | boolean, location: Position | Range); + } + + /** + * Coverage details returned from {@link TestRunProfile.loadDetailedCoverage}. + */ + export type FileCoverageDetail = StatementCoverage | DeclarationCoverage; + /** * The tab represents a single text based resource. */ diff --git a/src/vscode-dts/vscode.proposed.testCoverage.d.ts b/src/vscode-dts/vscode.proposed.testCoverage.d.ts deleted file mode 100644 index 2f40ffbdefc69..0000000000000 --- a/src/vscode-dts/vscode.proposed.testCoverage.d.ts +++ /dev/null @@ -1,201 +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' { - - // https://github.com/microsoft/vscode/issues/123713 - - export interface TestRun { - /** - * Adds coverage for a file in the run. - */ - addCoverage(fileCoverage: FileCoverage): void; - - /** - * An event fired when the editor is no longer interested in data - * associated with the test run. - */ - onDidDispose: Event; - } - - export interface TestRunProfile { - /** - * A function that provides detailed statement and function-level coverage for a file. - * - * The {@link FileCoverage} object passed to this function is the same instance - * emitted on {@link TestRun.addCoverage} calls associated with this profile. - */ - loadDetailedCoverage?: (testRun: TestRun, fileCoverage: FileCoverage, token: CancellationToken) => Thenable; - } - - /** - * A class that contains information about a covered resource. A count can - * be give for lines, branches, and declarations in a file. - */ - export class TestCoverageCount { - /** - * Number of items covered in the file. - */ - covered: number; - /** - * Total number of covered items in the file. - */ - total: number; - - /** - * @param covered Value for {@link TestCoverageCount.covered} - * @param total Value for {@link TestCoverageCount.total} - */ - constructor(covered: number, total: number); - } - - /** - * Contains coverage metadata for a file. - */ - export class FileCoverage { - /** - * File URI. - */ - readonly uri: Uri; - - /** - * Statement coverage information. If the reporter does not provide statement - * coverage information, this can instead be used to represent line coverage. - */ - statementCoverage: TestCoverageCount; - - /** - * Branch coverage information. - */ - branchCoverage?: TestCoverageCount; - - /** - * Declaration coverage information. Depending on the reporter and - * language, this may be types such as functions, methods, or namespaces. - */ - declarationCoverage?: TestCoverageCount; - - /** - * Creates a {@link FileCoverage} instance with counts filled in from - * the coverage details. - * @param uri Covered file URI - * @param detailed Detailed coverage information - */ - static fromDetails(uri: Uri, details: readonly FileCoverageDetail[]): FileCoverage; - - /** - * @param uri Covered file URI - * @param statementCoverage Statement coverage information. If the reporter - * does not provide statement coverage information, this can instead be - * used to represent line coverage. - * @param branchCoverage Branch coverage information - * @param declarationCoverage Declaration coverage information - */ - constructor( - uri: Uri, - statementCoverage: TestCoverageCount, - branchCoverage?: TestCoverageCount, - declarationCoverage?: TestCoverageCount, - ); - } - - /** - * Contains coverage information for a single statement or line. - */ - export class StatementCoverage { - /** - * The number of times this statement was executed, or a boolean indicating - * whether it was executed if the exact count is unknown. If zero or false, - * the statement will be marked as un-covered. - */ - executed: number | boolean; - - /** - * Statement location. - */ - location: Position | Range; - - /** - * Coverage from branches of this line or statement. If it's not a - * conditional, this will be empty. - */ - branches: BranchCoverage[]; - - /** - * @param location The statement position. - * @param executed The number of times this statement was executed, or a - * boolean indicating whether it was executed if the exact count is - * unknown. If zero or false, the statement will be marked as un-covered. - * @param branches Coverage from branches of this line. If it's not a - * conditional, this should be omitted. - */ - constructor(executed: number | boolean, location: Position | Range, branches?: BranchCoverage[]); - } - - /** - * Contains coverage information for a branch of a {@link StatementCoverage}. - */ - export class BranchCoverage { - /** - * The number of times this branch was executed, or a boolean indicating - * whether it was executed if the exact count is unknown. If zero or false, - * the branch will be marked as un-covered. - */ - executed: number | boolean; - - /** - * Branch location. - */ - location?: Position | Range; - - /** - * Label for the branch, used in the context of "the ${label} branch was - * not taken," for example. - */ - label?: string; - - /** - * @param executed The number of times this branch was executed, or a - * boolean indicating whether it was executed if the exact count is - * unknown. If zero or false, the branch will be marked as un-covered. - * @param location The branch position. - */ - constructor(executed: number | boolean, location?: Position | Range, label?: string); - } - - /** - * Contains coverage information for a declaration. Depending on the reporter - * and language, this may be types such as functions, methods, or namespaces. - */ - export class DeclarationCoverage { - /** - * Name of the declaration. - */ - name: string; - - /** - * The number of times this declaration was executed, or a boolean - * indicating whether it was executed if the exact count is unknown. If - * zero or false, the declaration will be marked as un-covered. - */ - executed: number | boolean; - - /** - * Declaration location. - */ - location: Position | Range; - - /** - * @param executed The number of times this declaration was executed, or a - * boolean indicating whether it was executed if the exact count is - * unknown. If zero or false, the declaration will be marked as un-covered. - * @param location The declaration position. - */ - constructor(name: string, executed: number | boolean, location: Position | Range); - } - - export type FileCoverageDetail = StatementCoverage | DeclarationCoverage; - -}