diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ac8db76a1a6..ce39de1d23e 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2200,7 +2200,7 @@ declare module 'vscode' { /** * List of tests returned by test provider for files in the workspace. */ - readonly tests: ReadonlyArray; + readonly tests: ReadonlyArray; /** * An event that fires when an existing test in the collection changes, or @@ -2230,17 +2230,17 @@ declare module 'vscode' { /** * List of all tests that are newly added. */ - readonly added: ReadonlyArray; + readonly added: ReadonlyArray; /** * List of existing tests that have updated. */ - readonly updated: ReadonlyArray; + readonly updated: ReadonlyArray; /** * List of existing tests that have been removed. */ - readonly removed: ReadonlyArray; + readonly removed: ReadonlyArray; } /** @@ -2377,7 +2377,7 @@ declare module 'vscode' { * A test item is an item shown in the "test explorer" view. It encompasses * both a suite and a test, since they have almost or identical capabilities. */ - export interface TestItem { + export class TestItem { /** * Unique identifier for the TestItem. This is used to correlate * test results and tests in the document with those in the workspace @@ -2396,22 +2396,20 @@ declare module 'vscode' { description?: string; /** - * Whether this test item can be run individually, defaults to `true` - * if not provided. + * Whether this test item can be run individually, defaults to `true`. * * In some cases, like Go's tests, test can have children but these * children cannot be run independently. */ - runnable?: boolean; + runnable: boolean; /** - * Whether this test item can be debugged individually, defaults to `false` - * if not provided. + * Whether this test item can be debugged individually, defaults to `false`. * * In some cases, like Go's tests, test can have children but these * children cannot be run independently. */ - debuggable?: boolean; + debuggable: boolean; /** * Location of the test in the workspace. This is used to show line @@ -2422,54 +2420,20 @@ declare module 'vscode' { /** * Optional list of nested tests for this item. */ - children?: TestItem[]; - } - - /** - * A readonly {@link TestItem}-like interface with its defaults filled in, - * exposed in the {@link TestObserver} interface. - */ - export interface ObservedTestItem { - /** - * See {@link TestItem.id} - */ - readonly id: string; + children: TestItem[]; /** - * See {@link TestItem.label} + * Creates a new TestItem instance. + * @param id Value of the "id" property + * @param label Value of the "label" property. */ - readonly label: string; - - /** - * Optional description that appears next to the label. - */ - readonly description?: string; - - /** - * See {@link TestItem.runnable} - */ - readonly runnable: boolean; - - /** - * See {@link TestItem.debuggable} - */ - readonly debuggable: boolean; - - /** - * See {@link TestItem.location} - */ - readonly location?: Location; - - /** - * See {@link TestItem.children} - */ - readonly children: ReadonlyArray; + constructor(id: string, label: string); } /** * Possible states of tests in a test run. */ - export enum TestRunState { + export enum TestResult { // Initial state Unset = 0, // Test will be run, but is not currently running. @@ -2489,22 +2453,27 @@ declare module 'vscode' { /** * TestState associated with a test in its results. */ - export interface TestState { + export class TestState { /** * Current state of the test. */ - readonly state: TestRunState; + readonly state: TestResult; /** * Optional duration of the test run, in milliseconds. */ - readonly duration?: number; + duration?: number; /** * Associated test run message. Can, for example, contain assertion * failure information if the test fails. */ - readonly messages?: ReadonlyArray>; + messages: TestMessage[]; + + /** + * Creates a new TestState instance. + */ + constructor(state: TestResult); } /** @@ -2521,16 +2490,16 @@ declare module 'vscode' { * Message associated with the test state. Can be linked to a specific * source range -- useful for assertion failures, for example. */ - export interface TestMessage { + export class TestMessage { /** * Human-readable message text to display. */ message: string | MarkdownString; /** - * Message severity. Defaults to "Error", if not provided. + * Message severity. Defaults to "Error". */ - severity?: TestMessageSeverity; + severity: TestMessageSeverity; /** * Expected test output. If given with `actualOutput`, a diff view will be shown. @@ -2546,6 +2515,20 @@ declare module 'vscode' { * Associated file location. */ location?: Location; + + /** + * Creates a new TestMessage that will present as a diff in the editor. + * @param message Message to display to the user. + * @param expected Expected output. + * @param actual Actual output. + */ + static diff(message: string | MarkdownString, expected: string, actual: string): TestMessage; + + /** + * Creates a new TestMessage instance. + * @param message The message to show to the user. + */ + constructor(message: string | MarkdownString); } /** @@ -2584,7 +2567,7 @@ declare module 'vscode' { /** * Optional list of nested tests for this item. */ - children?: Readonly[]; + children: Readonly[]; } //#endregion diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index e48169a7aa1..20f662c6f2e 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1236,7 +1236,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I NotebookCellOutput: extHostTypes.NotebookCellOutput, NotebookCellOutputItem: extHostTypes.NotebookCellOutputItem, LinkedEditingRanges: extHostTypes.LinkedEditingRanges, - TestRunState: extHostTypes.TestRunState, + TestItem: extHostTypes.TestItem, + TestState: extHostTypes.TestState, + TestResult: extHostTypes.TestResult, + TestMessage: extHostTypes.TestMessage, TestMessageSeverity: extHostTypes.TestMessageSeverity, WorkspaceTrustState: extHostTypes.WorkspaceTrustState }; diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index 00272cb76d4..30ba5179ba9 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -17,7 +17,7 @@ import { ExtHostTestingResource, ExtHostTestingShape, MainContext, MainThreadTes import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData'; import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; -import { TestItem, TestResults, TestState } from 'vs/workbench/api/common/extHostTypeConverters'; +import * as Convert from 'vs/workbench/api/common/extHostTypeConverters'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { OwnedTestCollection, SingleUseTestCollection, TestPosition } from 'vs/workbench/contrib/testing/common/ownedTestCollection'; @@ -106,7 +106,7 @@ export class ExtHostTesting implements ExtHostTestingShape { * Implements vscode.test.publishTestResults */ public publishExtensionProvidedResults(results: vscode.TestResults, persist: boolean): void { - this.proxy.$publishExtensionProvidedResults(TestResults.from(generateUuid(), results), persist); + this.proxy.$publishExtensionProvidedResults(Convert.TestResults.from(generateUuid(), results), persist); } /** @@ -116,7 +116,7 @@ export class ExtHostTesting implements ExtHostTestingShape { public $publishTestResults(results: ISerializedTestResults[]): void { this.results = Object.freeze( results - .map(r => deepFreeze(TestResults.to(r))) + .map(r => deepFreeze(Convert.TestResults.to(r))) .concat(this.results) .sort((a, b) => b.completedAt - a.completedAt) .slice(0, 32), @@ -272,7 +272,7 @@ export class ExtHostTesting implements ExtHostTestingShape { } this.flushCollectionDiffs(); - this.proxy.$updateTestStateInRun(req.runId, test.id, TestState.from(state)); + this.proxy.$updateTestStateInRun(req.runId, test.id, Convert.TestState.from(state)); }, tests: includeTests.map(t => TestItemFilteredWrapper.unwrap(t.actual)), exclude: excludeTests.map(([, t]) => TestItemFilteredWrapper.unwrap(t.actual)), @@ -499,9 +499,9 @@ export class TestItemFilteredWrapper implements vscode.TestItem { * @private */ interface MirroredCollectionTestItem extends IncrementalTestCollectionItem { - revived: vscode.TestItem; + revived: Omit; depth: number; - wrapped?: vscode.ObservedTestItem; + wrapped?: TestItemFromMirror; } class MirroredChangeCollector extends IncrementalChangeCollector { @@ -530,7 +530,7 @@ class MirroredChangeCollector extends IncrementalChangeCollector) { - let output: vscode.ObservedTestItem[] = []; + let output: vscode.TestItem[] = []; for (const itemId of itemIds) { const item = this.items.get(itemId); if (item) { @@ -627,7 +627,12 @@ export class MirroredTestCollection extends AbstractIncrementalTestCollection ({ - message: MarkdownString.fromStrict(message.message) || '', - severity: message.severity, - expectedOutput: message.expectedOutput, - actualOutput: message.actualOutput, - location: message.location ? location.from(message.location) as any : undefined, - })) ?? [], + messages: item.messages.map(TestMessage.from), }; } export function to(item: ITestState): vscode.TestState { + const ts = new types.TestState(item.state); + ts.duration = item.duration; + ts.messages = item.messages.map(TestMessage.to); + return ts; + } +} + +export namespace TestMessage { + export function from(message: vscode.TestMessage): ITestMessage { return { - state: item.state, - messages: item.messages.map(message => ({ - message: typeof message.message === 'string' ? message.message : MarkdownString.to(message.message), - severity: message.severity, - expectedOutput: message.expectedOutput, - actualOutput: message.actualOutput, - location: message.location && location.to({ - range: message.location.range, - uri: URI.revive(message.location.uri) - }), - })), - duration: item.duration, + message: MarkdownString.fromStrict(message.message) || '', + severity: message.severity, + expectedOutput: message.expectedOutput, + actualOutput: message.actualOutput, + location: message.location ? location.from(message.location) as any : undefined, }; } + + export function to(item: ITestMessage): vscode.TestMessage { + const message = new types.TestMessage(typeof item.message === 'string' ? item.message : MarkdownString.to(item.message)); + message.severity = item.severity; + message.actualOutput = item.actualOutput; + message.expectedOutput = item.expectedOutput; + return message; + } } export namespace TestItem { + export type Raw = vscode.TestItem; + export function from(item: vscode.TestItem): ITestItem { return { extId: item.id, @@ -1637,7 +1643,7 @@ export namespace TestItem { }; } - export function toShallow(item: ITestItem): Omit { + export function toPlainShallow(item: ITestItem): Omit { return { id: item.extId, label: item.label, @@ -1650,6 +1656,21 @@ export namespace TestItem { runnable: item.runnable, }; } + + export function toShallow(item: ITestItem): Omit { + const testItem = new types.TestItem(item.extId, item.label); + if (item.location) { + testItem.location = location.to({ + range: item.location.range, + uri: URI.revive(item.location.uri) + }); + } + + testItem.debuggable = item.debuggable; + testItem.description = item.description; + testItem.runnable = item.runnable; + return testItem; + } } export namespace TestResults { @@ -1689,7 +1710,7 @@ export namespace TestResults { } const convertTestResultItem = (item: SerializedTestResultItem, byInternalId: Map): vscode.TestItemWithResults => ({ - ...TestItem.toShallow(item.item), + ...TestItem.toPlainShallow(item.item), result: TestState.to(item.state), children: item.children .map(c => byInternalId.get(c)) diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index be5ef20914b..6cf03a15b0e 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -3277,7 +3277,7 @@ export class LinkedEditingRanges { } //#region Testing -export enum TestRunState { +export enum TestResult { Unset = 0, Queued = 1, Running = 2, @@ -3294,13 +3294,44 @@ export enum TestMessageSeverity { Hint = 3 } -export type RequiredTestItem = { - [K in keyof Required]: K extends 'children' - ? RequiredTestItem[] - : (K extends 'description' | 'location' ? TestItem[K] : Required[K]) -}; +export class TestItem implements vscode.TestItem { + public id!: string; + public location?: Location; + public description?: string; + public runnable = true; + public debuggable = false; + public children: vscode.TestItem[] = []; -export type TestItem = vscode.TestItem; + constructor(id: string, public label: string) { + Object.defineProperty(this, 'id', { + value: id, + enumerable: true, + writable: false, + }); + } +} + +export class TestState implements vscode.TestState { + public messages: TestMessage[] = []; + public duration?: number; + + constructor(public state: TestResult) { } +} + +export class TestMessage implements vscode.TestMessage { + public severity = TestMessageSeverity.Error; + public expectedOutput?: string; + public actualOutput?: string; + + public static diff(message: string | vscode.MarkdownString, expected: string, actual: string) { + const msg = new TestMessage(message); + msg.expectedOutput = expected; + msg.actualOutput = actual; + return msg; + } + + constructor(public message: string | vscode.MarkdownString) { } +} //#endregion diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts index 287e561c0fc..0e3fa440dd8 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts @@ -10,7 +10,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { Position } from 'vs/editor/common/core/position'; import { IWorkspaceFolder, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { ITestTreeElement, ITestTreeProjection } from 'vs/workbench/contrib/testing/browser/explorerProjections'; import { HierarchicalElement, HierarchicalFolder } from 'vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes'; import { locationsEqual, TestLocationStore } from 'vs/workbench/contrib/testing/browser/explorerProjections/locationStore'; @@ -68,8 +68,8 @@ export class HierarchicalByLocationProjection extends Disposable implements ITes for (const inTree of [...this.items.values()].sort((a, b) => b.depth - a.depth)) { const lookup = this.results.getStateById(inTree.test.item.extId)?.[1]; - inTree.ownState = lookup?.state.state ?? TestRunState.Unset; - const computed = lookup?.computedState ?? TestRunState.Unset; + inTree.ownState = lookup?.state.state ?? TestResult.Unset; + const computed = lookup?.computedState ?? TestResult.Unset; if (computed !== inTree.state) { inTree.state = computed; this.addUpdated(inTree); diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts index bd02e7a8b72..f1237486a52 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts @@ -6,7 +6,7 @@ import { Iterable } from 'vs/base/common/iterator'; import { generateUuid } from 'vs/base/common/uuid'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { ITestTreeElement } from 'vs/workbench/contrib/testing/browser/explorerProjections'; import { InternalTestItem, TestIdWithProvider } from 'vs/workbench/contrib/testing/common/testCollection'; @@ -41,9 +41,9 @@ export class HierarchicalElement implements ITestTreeElement { : Iterable.empty(); } - public state = TestRunState.Unset; + public state = TestResult.Unset; public retired = false; - public ownState = TestRunState.Unset; + public ownState = TestResult.Unset; constructor(public readonly test: InternalTestItem, public readonly parentItem: HierarchicalFolder | HierarchicalElement) { this.test = { ...test, item: { ...test.item } }; // clone since we Object.assign updatese @@ -61,7 +61,7 @@ export class HierarchicalFolder implements ITestTreeElement { public readonly children = new Set(); public readonly parentItem = null; public readonly depth = 0; - public computedState: TestRunState | undefined; + public computedState: TestResult | undefined; public get treeId() { return generateUuid(); @@ -76,8 +76,8 @@ export class HierarchicalFolder implements ITestTreeElement { } public retired = false; - public state = TestRunState.Unset; - public ownState = TestRunState.Unset; + public state = TestResult.Unset; + public ownState = TestResult.Unset; constructor(private readonly folder: IWorkspaceFolder) { } diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts index 94238523144..a67f77da061 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts @@ -10,7 +10,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { Position } from 'vs/editor/common/core/position'; import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { InternalTestItem, TestIdWithProvider } from 'vs/workbench/contrib/testing/common/testCollection'; /** @@ -90,14 +90,14 @@ export interface ITestTreeElement { /** * Element state to display. */ - state: TestRunState; + state: TestResult; /** * Whether the node's test result is 'retired' -- from an outdated test run. */ readonly retired: boolean; - readonly ownState: TestRunState; + readonly ownState: TestResult; readonly label: string; readonly parentItem: ITestTreeElement | null; } diff --git a/src/vs/workbench/contrib/testing/browser/icons.ts b/src/vs/workbench/contrib/testing/browser/icons.ts index 102479d70f8..0bd4160637e 100644 --- a/src/vs/workbench/contrib/testing/browser/icons.ts +++ b/src/vs/workbench/contrib/testing/browser/icons.ts @@ -7,7 +7,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { localize } from 'vs/nls'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { testingColorRunAction, testStatesToIconColors } from 'vs/workbench/contrib/testing/browser/theme'; export const testingViewIcon = registerIcon('test-view-icon', Codicon.beaker, localize('testViewIcon', 'View icon of the test view.')); @@ -22,14 +22,14 @@ export const testingHiddenIcon = registerIcon('testing-hidden', Codicon.eyeClose export const testingShowAsList = registerIcon('testing-show-as-list-icon', Codicon.listTree, localize('testingShowAsList', 'Icon shown when the test explorer is disabled as a tree.')); export const testingShowAsTree = registerIcon('testing-show-as-list-icon', Codicon.listFlat, localize('testingShowAsTree', 'Icon shown when the test explorer is disabled as a list.')); -export const testingStatesToIcons = new Map([ - [TestRunState.Errored, registerIcon('testing-error-icon', Codicon.issues, localize('testingErrorIcon', 'Icon shown for tests that have an error.'))], - [TestRunState.Failed, registerIcon('testing-failed-icon', Codicon.error, localize('testingFailedIcon', 'Icon shown for tests that failed.'))], - [TestRunState.Passed, registerIcon('testing-passed-icon', Codicon.pass, localize('testingPassedIcon', 'Icon shown for tests that passed.'))], - [TestRunState.Queued, registerIcon('testing-queued-icon', Codicon.history, localize('testingQueuedIcon', 'Icon shown for tests that are queued.'))], - [TestRunState.Running, ThemeIcon.modify(Codicon.loading, 'spin')], - [TestRunState.Skipped, registerIcon('testing-skipped-icon', Codicon.debugStepOver, localize('testingSkippedIcon', 'Icon shown for tests that are skipped.'))], - [TestRunState.Unset, registerIcon('testing-unset-icon', Codicon.circleOutline, localize('testingUnsetIcon', 'Icon shown for tests that are in an unset state.'))], +export const testingStatesToIcons = new Map([ + [TestResult.Errored, registerIcon('testing-error-icon', Codicon.issues, localize('testingErrorIcon', 'Icon shown for tests that have an error.'))], + [TestResult.Failed, registerIcon('testing-failed-icon', Codicon.error, localize('testingFailedIcon', 'Icon shown for tests that failed.'))], + [TestResult.Passed, registerIcon('testing-passed-icon', Codicon.pass, localize('testingPassedIcon', 'Icon shown for tests that passed.'))], + [TestResult.Queued, registerIcon('testing-queued-icon', Codicon.history, localize('testingQueuedIcon', 'Icon shown for tests that are queued.'))], + [TestResult.Running, ThemeIcon.modify(Codicon.loading, 'spin')], + [TestResult.Skipped, registerIcon('testing-skipped-icon', Codicon.debugStepOver, localize('testingSkippedIcon', 'Icon shown for tests that are skipped.'))], + [TestResult.Unset, registerIcon('testing-unset-icon', Codicon.circleOutline, localize('testingUnsetIcon', 'Icon shown for tests that are in an unset state.'))], ]); registerThemingParticipant((theme, collector) => { diff --git a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts index b962e699ca9..3745541bb66 100644 --- a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts +++ b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts @@ -22,7 +22,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IThemeService, themeColorFromId, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ExtHostTestingResource } from 'vs/workbench/api/common/extHost.protocol'; -import { TestMessageSeverity, TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestMessageSeverity, TestResult } from 'vs/workbench/api/common/extHostTypes'; import { BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution } from 'vs/workbench/contrib/debug/common/debug'; import { testingRunAllIcon, testingRunIcon, testingStatesToIcons } from 'vs/workbench/contrib/testing/browser/icons'; import { TestingOutputPeekController } from 'vs/workbench/contrib/testing/browser/testingOutputPeek'; @@ -237,7 +237,7 @@ class RunTestDecoration extends Disposable implements ITestDecoration { super(); this.line = location.range.startLineNumber; - const icon = stateItem?.computedState !== undefined && stateItem.computedState !== TestRunState.Unset + const icon = stateItem?.computedState !== undefined && stateItem.computedState !== TestResult.Unset ? testingStatesToIcons.get(stateItem.computedState)! : test.children.size > 0 ? testingRunAllIcon : testingRunIcon; diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index a6a8909acf1..d0ae04b2ce9 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -45,7 +45,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { foreground } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { IResourceLabel, IResourceLabelOptions, IResourceLabelProps, ResourceLabels } from 'vs/workbench/browser/labels'; import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; @@ -706,7 +706,7 @@ class TestsFilter implements ITreeFilter { case TestExplorerStateFilter.All: return FilterResult.Include; case TestExplorerStateFilter.OnlyExecuted: - return element.ownState !== TestRunState.Unset ? FilterResult.Include : FilterResult.Inherit; + return element.ownState !== TestResult.Unset ? FilterResult.Include : FilterResult.Inherit; case TestExplorerStateFilter.OnlyFailed: return isFailedState(element.ownState) ? FilterResult.Include : FilterResult.Inherit; } @@ -946,7 +946,7 @@ const getTestItemActions = ( try { const primary: IAction[] = []; - const running = element.state === TestRunState.Running; + const running = element.state === TestResult.Running; if (!Iterable.isEmpty(element.runnable)) { primary.push(instantionService.createInstance(RunAction, element.runnable, running)); } @@ -975,15 +975,15 @@ const getTestItemActions = ( type CountSummary = ReturnType; const collectCounts = (count: TestStateCount) => { - const failed = count[TestRunState.Errored] + count[TestRunState.Failed]; - const passed = count[TestRunState.Passed]; - const skipped = count[TestRunState.Skipped]; + const failed = count[TestResult.Errored] + count[TestResult.Failed]; + const passed = count[TestResult.Passed]; + const skipped = count[TestResult.Skipped]; return { passed, failed, runSoFar: passed + failed, - totalWillBeRun: passed + failed + count[TestRunState.Queued] + count[TestRunState.Running], + totalWillBeRun: passed + failed + count[TestResult.Queued] + count[TestResult.Running], skipped, }; }; @@ -1098,7 +1098,7 @@ class TestRunProgress { return; } - const failures = result.counts[TestRunState.Failed] + result.counts[TestRunState.Errored]; + const failures = result.counts[TestResult.Failed] + result.counts[TestResult.Errored]; if (failures === 0) { return; } diff --git a/src/vs/workbench/contrib/testing/browser/theme.ts b/src/vs/workbench/contrib/testing/browser/theme.ts index 635baca1d34..0f6d20e2e00 100644 --- a/src/vs/workbench/contrib/testing/browser/theme.ts +++ b/src/vs/workbench/contrib/testing/browser/theme.ts @@ -7,7 +7,7 @@ import { Color, RGBA } from 'vs/base/common/color'; import { localize } from 'vs/nls'; import { editorErrorForeground, editorForeground, editorHintForeground, editorInfoForeground, editorWarningForeground, inputActiveOptionBackground, inputActiveOptionBorder, inputActiveOptionForeground, registerColor } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; -import { TestMessageSeverity, TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestMessageSeverity, TestResult } from 'vs/workbench/api/common/extHostTypes'; import { ACTIVITY_BAR_BADGE_BACKGROUND } from 'vs/workbench/common/theme'; export const testingColorIconFailed = registerColor('testing.iconFailed', { @@ -114,13 +114,13 @@ export const testMessageSeverityColors: { }, }; -export const testStatesToIconColors: { [K in TestRunState]?: string } = { - [TestRunState.Errored]: testingColorIconErrored, - [TestRunState.Failed]: testingColorIconFailed, - [TestRunState.Passed]: testingColorIconPassed, - [TestRunState.Queued]: testingColorIconQueued, - [TestRunState.Unset]: testingColorIconUnset, - [TestRunState.Skipped]: testingColorIconUnset, +export const testStatesToIconColors: { [K in TestResult]?: string } = { + [TestResult.Errored]: testingColorIconErrored, + [TestResult.Failed]: testingColorIconFailed, + [TestResult.Passed]: testingColorIconPassed, + [TestResult.Queued]: testingColorIconQueued, + [TestResult.Unset]: testingColorIconUnset, + [TestResult.Skipped]: testingColorIconUnset, }; diff --git a/src/vs/workbench/contrib/testing/common/constants.ts b/src/vs/workbench/contrib/testing/common/constants.ts index 0e6ebdae3ba..6c511086250 100644 --- a/src/vs/workbench/contrib/testing/common/constants.ts +++ b/src/vs/workbench/contrib/testing/common/constants.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; export const enum Testing { // marked as "extension" so that any existing test extensions are assigned to it. @@ -31,12 +31,12 @@ export const enum TestExplorerStateFilter { All = 'all', } -export const testStateNames: { [K in TestRunState]: string } = { - [TestRunState.Errored]: localize('testState.errored', 'Errored'), - [TestRunState.Failed]: localize('testState.failed', 'Failed'), - [TestRunState.Passed]: localize('testState.passed', 'Passed'), - [TestRunState.Queued]: localize('testState.queued', 'Queued'), - [TestRunState.Running]: localize('testState.running', 'Running'), - [TestRunState.Skipped]: localize('testState.skipped', 'Skipped'), - [TestRunState.Unset]: localize('testState.unset', 'Unset'), +export const testStateNames: { [K in TestResult]: string } = { + [TestResult.Errored]: localize('testState.errored', 'Errored'), + [TestResult.Failed]: localize('testState.failed', 'Failed'), + [TestResult.Passed]: localize('testState.passed', 'Passed'), + [TestResult.Queued]: localize('testState.queued', 'Queued'), + [TestResult.Running]: localize('testState.running', 'Running'), + [TestResult.Skipped]: localize('testState.skipped', 'Skipped'), + [TestResult.Unset]: localize('testState.unset', 'Unset'), }; diff --git a/src/vs/workbench/contrib/testing/common/getComputedState.ts b/src/vs/workbench/contrib/testing/common/getComputedState.ts index e8bb0d16a2c..14e7b371a5c 100644 --- a/src/vs/workbench/contrib/testing/common/getComputedState.ts +++ b/src/vs/workbench/contrib/testing/common/getComputedState.ts @@ -3,16 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { maxPriority, statePriority } from 'vs/workbench/contrib/testing/common/testingStates'; /** * Accessor for nodes in get and refresh computed state. */ export interface IComputedStateAccessor { - getOwnState(item: T): TestRunState | undefined; - getCurrentComputedState(item: T): TestRunState; - setComputedState(item: T, state: TestRunState): void; + getOwnState(item: T): TestResult | undefined; + getCurrentComputedState(item: T): TestResult; + setComputedState(item: T, state: TestResult): void; getChildren(item: T): IterableIterator; getParents(item: T): IterableIterator; } @@ -26,7 +26,7 @@ export interface IComputedStateAccessor { export const getComputedState = (accessor: IComputedStateAccessor, node: T, force = false) => { let computed = accessor.getCurrentComputedState(node); if (computed === undefined || force) { - computed = accessor.getOwnState(node) ?? TestRunState.Unset; + computed = accessor.getOwnState(node) ?? TestResult.Unset; for (const child of accessor.getChildren(node)) { computed = maxPriority(computed, getComputedState(accessor, child)); } @@ -45,7 +45,7 @@ export const refreshComputedState = ( accessor: IComputedStateAccessor, node: T, addUpdated: (node: T) => void, - explicitNewComputedState?: TestRunState, + explicitNewComputedState?: TestResult, ) => { const oldState = accessor.getCurrentComputedState(node); const oldPriority = statePriority[oldState]; diff --git a/src/vs/workbench/contrib/testing/common/ownedTestCollection.ts b/src/vs/workbench/contrib/testing/common/ownedTestCollection.ts index 64065246000..235c53ce45a 100644 --- a/src/vs/workbench/contrib/testing/common/ownedTestCollection.ts +++ b/src/vs/workbench/contrib/testing/common/ownedTestCollection.ts @@ -8,7 +8,6 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { throttle } from 'vs/base/common/decorators'; import { IDisposable, IReference } from 'vs/base/common/lifecycle'; import { TestItem } from 'vs/workbench/api/common/extHostTypeConverters'; -import { RequiredTestItem, TestItem as ApiTestItem } from 'vs/workbench/api/common/extHostTypes'; import { InternalTestItem, TestDiffOpType, TestsDiff, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testCollection'; /** @@ -46,9 +45,9 @@ export class OwnedTestCollection { * @private */ export interface OwnedCollectionTestItem extends InternalTestItem { - actual: ApiTestItem; + actual: TestItem.Raw; previousChildren: Set; - previousEquals: (v: ApiTestItem) => boolean; + previousEquals: (v: TestItem.Raw) => boolean; } /** @@ -169,7 +168,7 @@ export class TestTree { * @private */ export class SingleUseTestCollection implements IDisposable { - protected readonly testItemToInternal = new Map(); + protected readonly testItemToInternal = new Map(); protected diff: TestsDiff = []; private disposed = false; @@ -188,7 +187,7 @@ export class SingleUseTestCollection implements IDisposable { /** * Adds a new root node to the collection. */ - public addRoot(item: ApiTestItem, providerId: string) { + public addRoot(item: TestItem.Raw, providerId: string) { this.addItem(item, providerId, null); this.debounceSendDiff.schedule(); } @@ -197,14 +196,14 @@ export class SingleUseTestCollection implements IDisposable { * Gets test information by its reference, if it was defined and still exists * in this extension host. */ - public getTestByReference(item: ApiTestItem) { + public getTestByReference(item: TestItem.Raw) { return this.testItemToInternal.get(item); } /** * Should be called when an item change is fired on the test provider. */ - public onItemChange(item: ApiTestItem, providerId: string) { + public onItemChange(item: TestItem.Raw, providerId: string) { const existing = this.testItemToInternal.get(item); if (!existing) { if (!this.disposed) { @@ -240,7 +239,7 @@ export class SingleUseTestCollection implements IDisposable { this.disposed = true; } - private addItem(actual: ApiTestItem, providerId: string, parent: string | null) { + private addItem(actual: TestItem.Raw, providerId: string, parent: string | null) { let internal = this.testItemToInternal.get(actual); if (!internal) { if (this.testIdToInternal.object.has(actual.id)) { @@ -325,7 +324,7 @@ export class SingleUseTestCollection implements IDisposable { } } -const keyMap: { [K in keyof Omit]: null } = { +const keyMap: { [K in keyof Omit]: null } = { id: null, label: null, location: null, @@ -336,13 +335,13 @@ const keyMap: { [K in keyof Omit]: null } = { const simpleProps = Object.keys(keyMap) as ReadonlyArray; -const itemEqualityComparator = (a: ApiTestItem) => { +const itemEqualityComparator = (a: TestItem.Raw) => { const values: unknown[] = []; for (const prop of simpleProps) { values.push(a[prop]); } - return (b: ApiTestItem) => { + return (b: TestItem.Raw) => { for (let i = 0; i < simpleProps.length; i++) { if (values[i] !== b[simpleProps[i]]) { return false; diff --git a/src/vs/workbench/contrib/testing/common/testCollection.ts b/src/vs/workbench/contrib/testing/common/testCollection.ts index 7b6ad2c3bd1..9c871a14e3e 100644 --- a/src/vs/workbench/contrib/testing/common/testCollection.ts +++ b/src/vs/workbench/contrib/testing/common/testCollection.ts @@ -7,7 +7,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent'; import { URI } from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; import { ExtHostTestingResource } from 'vs/workbench/api/common/extHost.protocol'; -import { TestMessageSeverity, TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestMessageSeverity, TestResult } from 'vs/workbench/api/common/extHostTypes'; export interface TestIdWithProvider { testId: string; @@ -45,14 +45,14 @@ export interface IRichLocation { export interface ITestMessage { message: string | IMarkdownString; - severity: TestMessageSeverity | undefined; + severity: TestMessageSeverity; expectedOutput: string | undefined; actualOutput: string | undefined; location: IRichLocation | undefined; } export interface ITestState { - state: TestRunState; + state: TestResult; duration: number | undefined; messages: ITestMessage[]; } @@ -87,7 +87,7 @@ export interface TestResultItem extends IncrementalTestCollectionItem { /** Current state of this test */ state: ITestState; /** Computed state based on children */ - computedState: TestRunState; + computedState: TestResult; /** True if the test is outdated */ retired: boolean; /** True if the test was directly requested by the run (is not a child or parent) */ diff --git a/src/vs/workbench/contrib/testing/common/testResultService.ts b/src/vs/workbench/contrib/testing/common/testResultService.ts index 6ed1ebd4192..507443efb42 100644 --- a/src/vs/workbench/contrib/testing/common/testResultService.ts +++ b/src/vs/workbench/contrib/testing/common/testResultService.ts @@ -15,7 +15,7 @@ import { Range } from 'vs/editor/common/core/range'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { IComputedStateAccessor, refreshComputedState } from 'vs/workbench/contrib/testing/common/getComputedState'; import { StoredValue } from 'vs/workbench/contrib/testing/common/storedValue'; import { IncrementalTestCollectionItem, ISerializedTestResults, ITestState, RunTestsRequest, TestResultItem } from 'vs/workbench/contrib/testing/common/testCollection'; @@ -26,7 +26,7 @@ import { IMainThreadTestCollection } from 'vs/workbench/contrib/testing/common/t /** * Count of the number of tests in each run state. */ -export type TestStateCount = { [K in TestRunState]: number }; +export type TestStateCount = { [K in TestResult]: number }; export const enum TestResultItemChangeReason { Retired, @@ -102,13 +102,13 @@ export const sumCounts = (counts: Iterable) => { const queuedState: ITestState = { duration: undefined, messages: [], - state: TestRunState.Queued + state: TestResult.Queued }; const unsetState: ITestState = { duration: undefined, messages: [], - state: TestRunState.Unset + state: TestResult.Unset }; const itemToNode = ( @@ -120,7 +120,7 @@ const itemToNode = ( // shallow-clone the test to take a 'snapshot' of it at the point in time where tests run item: { ...item.item }, state: unsetState, - computedState: TestRunState.Unset, + computedState: TestResult.Unset, retired: false, }; @@ -229,7 +229,7 @@ export class LiveTestResult implements ITestResult { /** * @inheritdoc */ - public readonly counts: { [K in TestRunState]: number } = makeEmptyCounts(); + public readonly counts: { [K in TestResult]: number } = makeEmptyCounts(); /** * @inheritdoc @@ -275,7 +275,7 @@ export class LiveTestResult implements ITestResult { private readonly excluded: ReadonlySet, public readonly isAutoRun: boolean, ) { - this.counts[TestRunState.Unset] = testById.size; + this.counts[TestResult.Unset] = testById.size; } /** @@ -366,7 +366,7 @@ export class LiveTestResult implements ITestResult { const originalSize = this.testById.size; makeParents(collection, test, this.testById); const node = makeNodeAndChildren(collection, test, this.excluded, this.testById); - this.counts[TestRunState.Unset] += this.testById.size - originalSize; + this.counts[TestResult.Unset] += this.testById.size - originalSize; return node; } } @@ -383,7 +383,7 @@ export class LiveTestResult implements ITestResult { } // un-queue any tests that weren't explicitly updated - this.setAllToState(unsetState, t => t.state.state === TestRunState.Queued); + this.setAllToState(unsetState, t => t.state.state === TestResult.Queued); this._completedAt = Date.now(); this.completeEmitter.fire(); } @@ -577,7 +577,7 @@ export class TestResultService implements ITestResultService { public getStateById(extId: string): [results: ITestResult, item: TestResultItem] | undefined { for (const result of this.results) { const lookup = result.getStateById(extId); - if (lookup && lookup.computedState !== TestRunState.Unset) { + if (lookup && lookup.computedState !== TestResult.Unset) { return [result, lookup]; } } diff --git a/src/vs/workbench/contrib/testing/common/testStubs.ts b/src/vs/workbench/contrib/testing/common/testStubs.ts index c3a67e574b0..e88a67404ef 100644 --- a/src/vs/workbench/contrib/testing/common/testStubs.ts +++ b/src/vs/workbench/contrib/testing/common/testStubs.ts @@ -3,26 +3,20 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TestItem, TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestItem, TestResult } from 'vs/workbench/api/common/extHostTypes'; -export const stubTest = (label: string, idPrefix = 'id-'): TestItem => ({ - id: idPrefix + label, - label, - location: undefined, - debuggable: true, - runnable: true, - description: '' -}); +export const stubTest = (label: string, idPrefix = 'id-', children: TestItem[] = []): TestItem => { + const t = new TestItem(idPrefix + label, label); + t.children = children; + return t; +}; export const testStubs = { test: stubTest, - nested: (idPrefix = 'id-') => ({ - ...stubTest('root', idPrefix), - children: [ - { ...stubTest('a', idPrefix), children: [stubTest('aa', idPrefix), stubTest('ab', idPrefix)] }, - stubTest('b', idPrefix), - ], - }), + nested: (idPrefix = 'id-') => stubTest('root', idPrefix, [ + stubTest('a', idPrefix, [stubTest('aa', idPrefix), stubTest('ab', idPrefix)]), + stubTest('b', idPrefix), + ]), }; -export const ReExportedTestRunState = TestRunState; +export const ReExportedTestRunState = TestResult; diff --git a/src/vs/workbench/contrib/testing/common/testingStates.ts b/src/vs/workbench/contrib/testing/common/testingStates.ts index f7eef7b5e45..b22e07573df 100644 --- a/src/vs/workbench/contrib/testing/common/testingStates.ts +++ b/src/vs/workbench/contrib/testing/common/testingStates.ts @@ -3,39 +3,39 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TestRunState } from 'vs/workbench/api/common/extHostTypes'; +import { TestResult } from 'vs/workbench/api/common/extHostTypes'; -export type TreeStateNode = { statusNode: true; state: TestRunState; priority: number }; +export type TreeStateNode = { statusNode: true; state: TestResult; priority: number }; /** * List of display priorities for different run states. When tests update, * the highest-priority state from any of their children will be the state * reflected in the parent node. */ -export const statePriority: { [K in TestRunState]: number } = { - [TestRunState.Running]: 6, - [TestRunState.Errored]: 5, - [TestRunState.Failed]: 4, - [TestRunState.Passed]: 3, - [TestRunState.Queued]: 2, - [TestRunState.Unset]: 1, - [TestRunState.Skipped]: 0, +export const statePriority: { [K in TestResult]: number } = { + [TestResult.Running]: 6, + [TestResult.Errored]: 5, + [TestResult.Failed]: 4, + [TestResult.Passed]: 3, + [TestResult.Queued]: 2, + [TestResult.Unset]: 1, + [TestResult.Skipped]: 0, }; -export const isFailedState = (s: TestRunState) => s === TestRunState.Errored || s === TestRunState.Failed; +export const isFailedState = (s: TestResult) => s === TestResult.Errored || s === TestResult.Failed; export const stateNodes = Object.entries(statePriority).reduce( (acc, [stateStr, priority]) => { - const state = Number(stateStr) as TestRunState; + const state = Number(stateStr) as TestResult; acc[state] = { statusNode: true, state, priority }; return acc; - }, {} as { [K in TestRunState]: TreeStateNode } + }, {} as { [K in TestResult]: TreeStateNode } ); -export const cmpPriority = (a: TestRunState, b: TestRunState) => statePriority[b] - statePriority[a]; +export const cmpPriority = (a: TestResult, b: TestResult) => statePriority[b] - statePriority[a]; -export const maxPriority = (a: TestRunState, b: TestRunState) => statePriority[a] > statePriority[b] ? a : b; +export const maxPriority = (a: TestResult, b: TestResult) => statePriority[a] > statePriority[b] ? a : b; -export const statesInOrder = Object.keys(statePriority).map(s => Number(s) as TestRunState).sort(cmpPriority); +export const statesInOrder = Object.keys(statePriority).map(s => Number(s) as TestResult).sort(cmpPriority); -export const isRunningState = (s: TestRunState) => s === TestRunState.Queued || s === TestRunState.Running; +export const isRunningState = (s: TestResult) => s === TestResult.Queued || s === TestResult.Running; diff --git a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts index 76a2065f059..cd80ecd830e 100644 --- a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts +++ b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts @@ -56,10 +56,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => { test('updates render if second test provider appears', () => { harness.c.addRoot(testStubs.nested(), 'a'); harness.flush(folder1); - harness.c.addRoot({ - ...testStubs.test('root2'), - children: [testStubs.test('c')] - }, 'b'); + harness.c.addRoot(testStubs.test('root2', undefined, [testStubs.test('c')]), 'b'); assert.deepStrictEqual(harness.flush(folder1), [ { e: 'root', children: [{ e: 'a', children: [{ e: 'aa' }, { e: 'ab' }] }, { e: 'b' }] }, { e: 'root2', children: [{ e: 'c' }] }, diff --git a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts index 8095598d999..f7812e7ce4f 100644 --- a/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts +++ b/src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts @@ -56,10 +56,7 @@ suite('Workbench - Testing Explorer Hierarchal by Name Projection', () => { test('updates render if second test provider appears', () => { harness.c.addRoot(testStubs.nested(), 'a'); harness.flush(folder1); - harness.c.addRoot({ - ...testStubs.test('root2'), - children: [testStubs.test('c')] - }, 'b'); + harness.c.addRoot(testStubs.test('root2', undefined, [testStubs.test('c')]), 'b'); assert.deepStrictEqual(harness.flush(folder1), [ { e: 'root', children: [{ e: 'aa' }, { e: 'ab' }, { e: 'b' }] }, { e: 'root2', children: [{ e: 'c' }] }, diff --git a/src/vs/workbench/test/browser/api/extHostTesting.test.ts b/src/vs/workbench/test/browser/api/extHostTesting.test.ts index 981c7a240ab..89fcfb56a13 100644 --- a/src/vs/workbench/test/browser/api/extHostTesting.test.ts +++ b/src/vs/workbench/test/browser/api/extHostTesting.test.ts @@ -6,25 +6,24 @@ import * as assert from 'assert'; import { MirroredTestCollection, TestItemFilteredWrapper } from 'vs/workbench/api/common/extHostTesting'; import * as convert from 'vs/workbench/api/common/extHostTypeConverters'; +import { TestItem as TestItemImpl } from 'vs/workbench/api/common/extHostTypes'; import { TestDiffOpType } from 'vs/workbench/contrib/testing/common/testCollection'; import { stubTest, testStubs } from 'vs/workbench/contrib/testing/common/testStubs'; import { TestOwnedTestCollection, TestSingleUseCollection } from 'vs/workbench/contrib/testing/test/common/ownedTestCollection'; -import { ObservedTestItem, TestChangeEvent, TestItem, TextDocument } from 'vscode'; +import { TestChangeEvent, TestItem, TextDocument } from 'vscode'; import { URI } from 'vs/base/common/uri'; import { Location } from 'vs/editor/common/modes'; import { Range } from 'vs/editor/common/core/range'; -const simplify = (item: TestItem | ObservedTestItem) => { - if ('toJSON' in item) { - item = (item as any).toJSON(); - delete (item as any).providerId; - delete (item as any).testId; - } +const simplify = (item: TestItem) => ({ + id: item.id, + label: item.label, + location: item.location, + runnable: item.runnable, + debuggable: item.debuggable, +}); - return { ...item, children: undefined }; -}; - -const assertTreesEqual = (a: TestItem | ObservedTestItem, b: TestItem | ObservedTestItem) => { +const assertTreesEqual = (a: TestItem, b: TestItem) => { assert.deepStrictEqual(simplify(a), simplify(b)); const aChildren = (a.children ?? []).slice().sort(); @@ -33,7 +32,7 @@ const assertTreesEqual = (a: TestItem | ObservedTestItem, b: TestItem | Observed aChildren.forEach((_, i) => assertTreesEqual(aChildren[i], bChildren[i])); }; -const assertTreeListEqual = (a: ReadonlyArray, b: ReadonlyArray) => { +const assertTreeListEqual = (a: ReadonlyArray, b: ReadonlyArray) => { assert.strictEqual(a.length, b.length, `expected a.length == n.length`); a.forEach((_, i) => assertTreesEqual(a[i], b[i])); }; @@ -90,8 +89,11 @@ suite('ExtHost Testing', () => { single.collectDiff(); tests.children![0].description = 'Hello world'; /* item a */ single.onItemChange(tests, 'pid'); + + const expected = stubTest('a'); + expected.description = 'Hello world'; assert.deepStrictEqual(single.collectDiff(), [ - [TestDiffOpType.Update, { parent: 'id-root', providerId: 'pid', item: convert.TestItem.from({ ...stubTest('a'), description: 'Hello world' }) }], + [TestDiffOpType.Update, { parent: 'id-root', providerId: 'pid', item: convert.TestItem.from(expected) }], ]); single.onItemChange(tests, 'pid'); @@ -263,8 +265,8 @@ suite('ExtHost Testing', () => { }); suite('TestItemFilteredWrapper', () => { - const stubTestWithLocation = (label: string, location: Location): TestItem => { - const t = stubTest(label); + const stubTestWithLocation = (label: string, location: Location, children: TestItemImpl[] = []) => { + const t = stubTest(label, undefined, children); t.location = location as any; return t; }; @@ -290,22 +292,12 @@ suite('ExtHost Testing', () => { let testsWithLocation: TestItem; setup(() => { - testsWithLocation = { - ...stubTest('root'), - children: [ - { - ...stubTestWithLocation('a', location1), - children: [stubTestWithLocation('aa', location1), stubTestWithLocation('ab', location1)] - }, - { - ...stubTestWithLocation('b', location2), - children: [stubTestWithLocation('ba', location2), stubTestWithLocation('bb', location2)] - }, - { - ...stubTestWithLocation('b', location3), - } - ], - }; + testsWithLocation = + stubTest('root', undefined, [ + stubTestWithLocation('a', location1, [stubTestWithLocation('aa', location1), stubTestWithLocation('ab', location1)]), + stubTestWithLocation('b', location2, [stubTestWithLocation('ba', location2), stubTestWithLocation('bb', location2)]), + stubTestWithLocation('b', location3), + ]); }); teardown(() => {