diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 129d1b324b4..3fd5e086bd6 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -2325,6 +2325,11 @@ declare module 'vscode' { */ readonly id: string; + /** + * URI this TestItem is associated with. May be a file or file. + */ + readonly uri: Uri; + /** * A set of children this item has. You can add new children to it, which * will propagate to the editor UI. @@ -2342,10 +2347,10 @@ declare module 'vscode' { description?: string; /** - * Location of the test in the workspace. This is used to show line - * decorations and code lenses for the test. + * Location of the test item in its `uri`. This is only meaningful if the + * `uri` points to a file. */ - location?: Location; + range?: Range; /** * Whether this test item can be run individually, defaults to `true`. @@ -2374,10 +2379,11 @@ declare module 'vscode' { * Creates a new TestItem instance. * @param id Value of the "id" property * @param label Value of the "label" property. + * @param uri Value of the "uri" property. * @param parent Parent of this item. This should only be defined for the * test root. */ - constructor(id: string, label: string, expandable: boolean); + constructor(id: string, label: string, uri: Uri, expandable: boolean); /** * Marks the test as outdated. This can happen as a result of file changes, @@ -2549,6 +2555,11 @@ declare module 'vscode' { */ readonly id: string; + /** + * URI this TestItem is associated with. May be a file or file. + */ + readonly uri: Uri; + /** * Display name describing the test case. */ @@ -2560,10 +2571,10 @@ declare module 'vscode' { readonly description?: string; /** - * Location of the test in the workspace. This is used to show line - * decorations and code lenses for the test. + * Location of the test item in its `uri`. This is only meaningful if the + * `uri` points to a file. */ - readonly location?: Location; + readonly range?: Range; /** * Current result of the test. diff --git a/src/vs/workbench/api/browser/mainThreadTesting.ts b/src/vs/workbench/api/browser/mainThreadTesting.ts index 23b3dc5b6e7..ec01db91302 100644 --- a/src/vs/workbench/api/browser/mainThreadTesting.ts +++ b/src/vs/workbench/api/browser/mainThreadTesting.ts @@ -18,9 +18,11 @@ const reviveDiff = (diff: TestsDiff) => { for (const entry of diff) { if (entry[0] === TestDiffOpType.Add || entry[0] === TestDiffOpType.Update) { const item = entry[1]; - if (item.item?.location) { - item.item.location.uri = URI.revive(item.item.location.uri); - item.item.location.range = Range.lift(item.item.location.range); + if (item.item?.uri) { + item.item.uri = URI.revive(item.item.uri); + } + if (item.item?.range) { + item.item.range = Range.lift(item.item.range); } } } diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index 5ac5508a131..5d39e2e6061 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -402,18 +402,13 @@ export class TestItemFilteredWrapper, ) { - super(actual.id, actual.label, actual.expandable); + super(actual.id, actual.label, actual.uri, actual.expandable); if (!(actual instanceof TestItemImpl)) { throw new Error(`TestItems provided to the VS Code API must extend \`vscode.TestItem\`, but ${actual.id} did not`); } (actual as TestItemImpl)[TestItemHookProperty] = { - setProp: (key, value) => { - (this as Record)[key] = value; - if (key === 'location') { - this.refreshMatch(); - } - }, + setProp: (key, value) => (this as Record)[key] = value, created: child => TestItemFilteredWrapper.getWrapperForTestItem(child, this.filterDocument, this).refreshMatch(), invalidate: () => this.invalidate(), delete: child => this.children.delete(child), @@ -439,7 +434,7 @@ export class TestItemFilteredWrapper 0 || this.actual.location?.uri.toString() === this.filterDocument.uri.toString(); + const nowMatches = this.children.size > 0 || this.actual.uri.toString() === this.filterDocument.uri.toString(); this._cachedMatchesFilter = nowMatches; if (nowMatches !== didMatch) { diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 8b33c1fcf05..113adbf8e4c 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -3,36 +3,35 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as modes from 'vs/editor/common/modes'; -import * as types from './extHostTypes'; -import * as search from 'vs/workbench/contrib/search/common/search'; -import { ITextEditorOptions, EditorOverride } from 'vs/platform/editor/common/editor'; -import { IDecorationOptions, IThemeDecorationRenderOptions, IDecorationRenderOptions, IContentDecorationRenderOptions } from 'vs/editor/common/editorCommon'; -import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/model'; -import type * as vscode from 'vscode'; -import { URI, UriComponents } from 'vs/base/common/uri'; -import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress'; -import { EditorGroupColumn, SaveReason } from 'vs/workbench/common/editor'; -import { IPosition } from 'vs/editor/common/core/position'; -import * as editorRange from 'vs/editor/common/core/range'; -import { ISelection } from 'vs/editor/common/core/selection'; +import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays'; import * as htmlContent from 'vs/base/common/htmlContent'; -import * as languageSelector from 'vs/editor/common/modes/languageSelector'; -import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol'; -import { MarkerSeverity, IRelatedInformation, IMarkerData, MarkerTag } from 'vs/platform/markers/common/markers'; -import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { isString, isNumber, isDefined } from 'vs/base/common/types'; import * as marked from 'vs/base/common/marked/marked'; import { parse } from 'vs/base/common/marshalling'; import { cloneAndChange } from 'vs/base/common/objects'; -import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log'; -import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays'; +import { isDefined, isNumber, isString } from 'vs/base/common/types'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; +import { IPosition } from 'vs/editor/common/core/position'; +import * as editorRange from 'vs/editor/common/core/range'; +import { ISelection } from 'vs/editor/common/core/selection'; +import { IContentDecorationRenderOptions, IDecorationOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions } from 'vs/editor/common/editorCommon'; +import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/model'; +import * as modes from 'vs/editor/common/modes'; +import * as languageSelector from 'vs/editor/common/modes/languageSelector'; +import { EditorOverride, ITextEditorOptions } from 'vs/platform/editor/common/editor'; +import { IMarkerData, IRelatedInformation, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers'; +import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress'; +import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol'; import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; +import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; +import { EditorGroupColumn, SaveReason } from 'vs/workbench/common/editor'; import * as notebooks from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import * as search from 'vs/workbench/contrib/search/common/search'; import { ISerializedTestResults, ITestItem, ITestMessage, ITestState, SerializedTestResultItem, TestItemExpandState } from 'vs/workbench/contrib/testing/common/testCollection'; +import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import type * as vscode from 'vscode'; +import * as types from './extHostTypes'; export interface PositionLike { line: number; @@ -1657,7 +1656,8 @@ export namespace TestItem { return { extId: item.id, label: item.label, - location: item.location ? location.from(item.location) as any : undefined, + uri: item.uri, + range: Range.from(item.range), debuggable: item.debuggable ?? false, description: item.description, runnable: item.runnable ?? true, @@ -1669,7 +1669,8 @@ export namespace TestItem { return { extId: item.id, label: item.label, - location: item.location ? location.from(item.location) as any : undefined, + uri: item.uri, + range: Range.from(item.range), debuggable: false, description: item.description, runnable: true, @@ -1681,10 +1682,8 @@ export namespace TestItem { return { id: item.extId, label: item.label, - location: item.location && location.to({ - range: item.location.range, - uri: URI.revive(item.location.uri) - }), + uri: URI.revive(item.uri), + range: Range.to(item.range), expandable: item.expandable, debuggable: item.debuggable, description: item.description, @@ -1693,14 +1692,8 @@ export namespace TestItem { } export function to(item: ITestItem): types.TestItem { - const testItem = new types.TestItem(item.extId, item.label, item.expandable); - if (item.location) { - testItem.location = location.to({ - range: item.location.range, - uri: URI.revive(item.location.uri) - }); - } - + const testItem = new types.TestItem(item.extId, item.label, URI.revive(item.uri), item.expandable); + testItem.range = Range.to(item.range); testItem.debuggable = item.debuggable; testItem.description = item.description; testItem.runnable = item.runnable; diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 233bab94cdb..655b37984c4 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -3322,20 +3322,26 @@ export class TestChildrenCollection implements vscode.TestChildrenCollection this[TestItemHookProperty]), enumerable: true, @@ -3346,7 +3352,7 @@ export class TestItem implements vscode.TestItem { writable: true, configurable: false, }, - location: testItemPropAccessor(this, 'location', undefined), + range: testItemPropAccessor(this, 'range', undefined), description: testItemPropAccessor(this, 'description', undefined), runnable: testItemPropAccessor(this, 'runnable', true), debuggable: testItemPropAccessor(this, 'debuggable', true), diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts index e97b5fe41fb..4b6b1ba64aa 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts @@ -160,7 +160,7 @@ export class HierarchicalByLocationProjection extends Disposable implements ITes break; } - const locationChanged = !!patch.item?.location; + const locationChanged = !!patch.item?.range; if (locationChanged) { this.locations.remove(existing); } existing.update(patch); if (locationChanged) { this.locations.add(existing); } diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts index 2b4073443e7..22a75306ff0 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalNodes.ts @@ -25,8 +25,12 @@ export class HierarchicalElement implements ITestTreeElement { return this.test.item.label; } - public get location() { - return this.test.item.location; + public get uri() { + return this.test.item.uri; + } + + public get range() { + return this.test.item.range; } public get runnable(): Iterable { @@ -79,6 +83,10 @@ export class HierarchicalFolder implements ITestTreeElement { return Iterable.concatNested(Iterable.map(this.children, c => c.runnable)); } + public get uri() { + return this.folder.uri; + } + public get debuggable() { return Iterable.concatNested(Iterable.map(this.children, c => c.debuggable)); } diff --git a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts index 1be1e0a4caa..8b6094e2da1 100644 --- a/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts +++ b/src/vs/workbench/contrib/testing/browser/explorerProjections/index.ts @@ -9,7 +9,7 @@ import { FuzzyScore } from 'vs/base/common/filters'; 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 { IRange } from 'vs/editor/common/core/range'; import { TestResult } from 'vs/workbench/api/common/extHostTypes'; import { InternalTestItem, TestIdWithSrc, TestItemExpandState } from 'vs/workbench/contrib/testing/common/testCollection'; @@ -62,10 +62,15 @@ export interface ITestTreeElement { */ readonly treeId: string; + /** + * URI associated with the test item. + */ + readonly uri: URI; + /** * Location of the test, if any. */ - readonly location?: { uri: URI; range: ITextEditorSelection }; + readonly range?: IRange; /** * Test item, if any. diff --git a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts index e964b6c14b2..0cf8a1fe68f 100644 --- a/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts +++ b/src/vs/workbench/contrib/testing/browser/testExplorerActions.ts @@ -9,6 +9,7 @@ import { Codicon } from 'vs/base/common/codicons'; import { Iterable } from 'vs/base/common/iterator'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { isDefined } from 'vs/base/common/types'; +import { Range } from 'vs/editor/common/core/range'; import { localize } from 'vs/nls'; import { Action2, MenuId } from 'vs/platform/actions/common/actions'; import { ContextKeyAndExpr, ContextKeyEqualsExpr, ContextKeyFalseExpr, ContextKeyTrueExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -588,7 +589,7 @@ abstract class RunOrDebugAtCursor extends Action2 { for (const id of candidates) { const candidate = collection.object.getNodeById(id); if (candidate) { - if (depth > bestDepth && this.filter(candidate) && candidate.item.location?.range.containsPosition(position)) { + if (depth > bestDepth && this.filter(candidate) && candidate.item.range && Range.containsPosition(candidate.item.range, position)) { bestDepth = depth; bestNode = candidate; } diff --git a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts index f4ddd718331..ef1698ab2a6 100644 --- a/src/vs/workbench/contrib/testing/browser/testingDecorations.ts +++ b/src/vs/workbench/contrib/testing/browser/testingDecorations.ts @@ -101,7 +101,7 @@ export class TestingDecorations extends Disposable implements IEditorContributio })); this._register(this.results.onTestChanged(({ item: result }) => { - if (this.currentUri && result.item.location?.uri.toString() === this.currentUri.toString()) { + if (this.currentUri && result.item.uri.toString() === this.currentUri.toString()) { this.setDecorations(this.currentUri); } })); @@ -125,18 +125,18 @@ export class TestingDecorations extends Disposable implements IEditorContributio return; } - const collection = this.collection.value = this.testService.subscribeToDiffs(ExtHostTestingResource.TextDocument, uri, diff => { + this.collection.value = this.testService.subscribeToDiffs(ExtHostTestingResource.TextDocument, uri, diff => { this.setDecorations(uri!); for (const op of diff) { if (op[0] === TestDiffOpType.Add && !op[1].parent) { - collection.object?.expand(op[1].item.extId, Infinity); + this.collection.value?.object.expand(op[1].item.extId, Infinity); } } }); - for (const root of collection.object.rootIds) { - collection.object.expand(root, Infinity); + for (const root of this.collection.value.object.rootIds) { + this.collection.value.object.expand(root, Infinity); } this.setDecorations(uri); @@ -152,9 +152,9 @@ export class TestingDecorations extends Disposable implements IEditorContributio const newDecorations: ITestDecoration[] = []; for (const test of ref.object.all) { const stateLookup = this.results.getStateById(test.item.extId); - if (hasValidLocation(uri, test.item)) { + if (test.item.range) { newDecorations.push(this.instantiationService.createInstance( - RunTestDecoration, test, ref.object, test.item.location, this.editor, stateLookup?.[1])); + RunTestDecoration, test, ref.object, test.item.range, this.editor, stateLookup?.[1])); } if (!stateLookup) { @@ -241,7 +241,7 @@ class RunTestDecoration extends Disposable implements ITestDecoration { constructor( private readonly test: IncrementalTestCollectionItem, private readonly collection: IMainThreadTestCollection, - private readonly location: IRichLocation, + range: IRange, private readonly editor: ICodeEditor, stateItem: TestResultItem | undefined, @ITestService private readonly testService: ITestService, @@ -249,7 +249,7 @@ class RunTestDecoration extends Disposable implements ITestDecoration { @ICommandService private readonly commandService: ICommandService, ) { super(); - this.line = location.range.startLineNumber; + this.line = range.startLineNumber; const icon = stateItem?.computedState !== undefined && stateItem.computedState !== TestResult.Unset ? testingStatesToIcons.get(stateItem.computedState)! @@ -267,7 +267,7 @@ class RunTestDecoration extends Disposable implements ITestDecoration { } this.editorDecoration = { - range: firstLineRange(this.location.range), + range: firstLineRange(range), options: { isWholeLine: true, hoverMessage, diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts index 1800815b5be..b3861f952fa 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerView.ts @@ -478,15 +478,10 @@ export class TestingExplorerViewModel extends Disposable { return; } - const location = item?.location; - if (!location) { - return; - } - const pane = await this.editorService.openEditor({ - resource: location.uri, + resource: item.uri, options: { - selection: { startColumn: location.range.startColumn, startLineNumber: location.range.startLineNumber }, + selection: item.range && { startColumn: item.range.startColumn, startLineNumber: item.range.startLineNumber }, preserveFocus, }, }); @@ -677,11 +672,7 @@ class TestsFilter implements ITreeFilter { } for (let e: ITestTreeElement | null = element; e; e = e!.parentItem) { - if (!e.location) { - continue; - } - - return e.location.uri.toString() === this._filterToUri + return e.uri.toString() === this._filterToUri ? FilterResult.Include : FilterResult.Exclude; } @@ -723,8 +714,8 @@ class TreeSorter implements ITreeSorter { return delta; } - if (this.viewModel.viewSorting === TestExplorerViewSorting.ByLocation && a.location && b.location && a.location.uri.toString() === b.location.uri.toString()) { - delta = a.location.range.startLineNumber - b.location.range.startLineNumber; + if (this.viewModel.viewSorting === TestExplorerViewSorting.ByLocation && a.range && b.range && a.uri.toString() === b.uri.toString()) { + delta = a.range.startLineNumber - b.range.startLineNumber; if (delta !== 0) { return delta; } @@ -847,9 +838,7 @@ class TestsRenderer extends Disposable implements ITreeRenderer e.getModel()?.uri.toString() === testUri))) { return; } diff --git a/src/vs/workbench/contrib/testing/common/testCollection.ts b/src/vs/workbench/contrib/testing/common/testCollection.ts index f667a2e918b..aaebb85b789 100644 --- a/src/vs/workbench/contrib/testing/common/testCollection.ts +++ b/src/vs/workbench/contrib/testing/common/testCollection.ts @@ -5,7 +5,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent'; import { URI } from 'vs/base/common/uri'; -import { Range } from 'vs/editor/common/core/range'; +import { IRange, Range } from 'vs/editor/common/core/range'; import { ExtHostTestingResource } from 'vs/workbench/api/common/extHost.protocol'; import { TestMessageSeverity, TestResult } from 'vs/workbench/api/common/extHostTypes'; @@ -70,7 +70,8 @@ export interface ITestItem { extId: string; label: string; children?: never; - location: IRichLocation | undefined; + uri: URI; + range: IRange | undefined; description: string | undefined; runnable: boolean; debuggable: boolean; diff --git a/src/vs/workbench/contrib/testing/common/testResultService.ts b/src/vs/workbench/contrib/testing/common/testResultService.ts index 2fcf867d0f1..ffbd0d2d36a 100644 --- a/src/vs/workbench/contrib/testing/common/testResultService.ts +++ b/src/vs/workbench/contrib/testing/common/testResultService.ts @@ -440,10 +440,7 @@ export class HydratedTestResult implements ITestResult { for (const item of serialized.items) { const cast: TestResultItem = { ...item, retired: true, children: new Set(item.children) }; - if (cast.item.location) { - cast.item.location.uri = URI.revive(cast.item.location.uri); - cast.item.location.range = Range.lift(cast.item.location.range); - } + cast.item.uri = URI.revive(cast.item.uri); for (const message of cast.state.messages) { if (message.location) { diff --git a/src/vs/workbench/contrib/testing/common/testStubs.ts b/src/vs/workbench/contrib/testing/common/testStubs.ts index 9c771bde997..ebe00df6fc0 100644 --- a/src/vs/workbench/contrib/testing/common/testStubs.ts +++ b/src/vs/workbench/contrib/testing/common/testStubs.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { URI } from 'vs/base/common/uri'; import { IProgress } from 'vs/platform/progress/common/progress'; import { TestItem, TestResult } from 'vs/workbench/api/common/extHostTypes'; @@ -10,7 +11,7 @@ export class StubTestItem extends TestItem { parent: StubTestItem | undefined; constructor(id: string, label: string, private readonly pendingChildren: StubTestItem[]) { - super(id, label, pendingChildren.length > 0); + super(id, label, URI.file('/'), pendingChildren.length > 0); } public discoverChildren(progress: IProgress<{ busy: boolean }>) { diff --git a/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts b/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts index 8cdb2ec4308..379253588f7 100644 --- a/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts +++ b/src/vs/workbench/contrib/testing/test/common/testResultService.test.ts @@ -155,10 +155,11 @@ suite('Workbench - Test Results Service', () => { ); const [rehydrated, actual] = results.getStateById('id-root')!; - const expected = r.getStateById('id-root')!; + const expected: any = { ...r.getStateById('id-root')! }; delete expected.state.duration; // delete undefined props that don't survive serialization - delete expected.item.location; + delete expected.item.range; delete expected.item.description; + expected.item.uri = actual.item.uri; assert.deepStrictEqual(actual, { ...expected, retired: true }); assert.deepStrictEqual(rehydrated.counts, r.counts); diff --git a/src/vs/workbench/test/browser/api/extHostTesting.test.ts b/src/vs/workbench/test/browser/api/extHostTesting.test.ts index 1a62bedc264..cb245d0f3b1 100644 --- a/src/vs/workbench/test/browser/api/extHostTesting.test.ts +++ b/src/vs/workbench/test/browser/api/extHostTesting.test.ts @@ -13,7 +13,8 @@ import { TestItem } from 'vscode'; const simplify = (item: TestItem) => ({ id: item.id, label: item.label, - location: item.location, + uri: item.uri, + range: item.range, runnable: item.runnable, debuggable: item.debuggable, });