Skip to content

Commit 21ec251

Browse files
authored
testing: add proposed testInvalidateResults API (microsoft#183370)
* testing: add proposed testInvalidateResults API For microsoft#134970 * fix tests
1 parent 11cabc6 commit 21ec251

File tree

12 files changed

+78
-6
lines changed

12 files changed

+78
-6
lines changed

extensions/vscode-api-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"tokenInformation",
4444
"treeItemCheckbox",
4545
"treeViewReveal",
46+
"testInvalidateResults",
4647
"workspaceTrust",
4748
"telemetry",
4849
"windowActivity",

src/vs/base/test/browser/dom.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ suite('dom', () => {
1818
assert(!element.classList.contains('bar'));
1919
assert(!element.classList.contains('foo'));
2020
assert(!element.classList.contains(''));
21+
22+
2123
});
2224

2325
test('removeClass', () => {

src/vs/workbench/api/browser/mainThreadTesting.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh
5252
}));
5353
}
5454

55+
/**
56+
* @inheritdoc
57+
*/
58+
$markTestRetired(testId: string): void {
59+
for (const result of this.resultService.results) {
60+
// all non-live results are already entirely outdated
61+
if (result instanceof LiveTestResult) {
62+
result.markRetired(testId);
63+
}
64+
}
65+
}
66+
5567
/**
5668
* @inheritdoc
5769
*/

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,8 @@ export interface MainThreadTestingShape {
25012501
$startedExtensionTestRun(req: ExtensionRunTestsRequest): void;
25022502
/** Signals that an extension-provided test run finished. */
25032503
$finishedExtensionTestRun(runId: string): void;
2504+
/** Marks a test (or controller) as retired in all results. */
2505+
$markTestRetired(testId: string): void;
25042506
}
25052507

25062508
// --- proxy identifiers

src/vs/workbench/api/common/extHostTesting.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { TestCommandId } from 'vs/workbench/contrib/testing/common/constants';
2727
import { TestId, TestIdPathParts, TestPosition } from 'vs/workbench/contrib/testing/common/testId';
2828
import { InvalidTestItemError } from 'vs/workbench/contrib/testing/common/testItemCollection';
2929
import { AbstractIncrementalTestCollection, CoverageDetails, ICallProfileRunHandler, IFileCoverage, ISerializedTestResults, IStartControllerTests, IStartControllerTestsResult, ITestItem, ITestItemContext, IncrementalChangeCollector, IncrementalTestCollectionItem, InternalTestItem, TestResultState, TestRunProfileBitset, TestsDiff, TestsDiffOp, isStartControllerTests } from 'vs/workbench/contrib/testing/common/testTypes';
30+
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
3031
import type * as vscode from 'vscode';
3132

3233
interface ControllerInfo {
@@ -137,6 +138,11 @@ export class ExtHostTesting implements ExtHostTestingShape {
137138
createTestRun: (request, name, persist = true) => {
138139
return this.runTracker.createTestRun(controllerId, collection, request, name, persist);
139140
},
141+
invalidateTestResults: item => {
142+
checkProposedApiEnabled(extension, 'testInvalidateResults');
143+
const id = item ? TestId.fromExtHostTestItem(item, controllerId).toString() : controllerId;
144+
return this.proxy.$markTestRetired(id);
145+
},
140146
set resolveHandler(fn) {
141147
collection.resolveHandler = fn;
142148
},

src/vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ export class HierarchicalByLocationProjection extends Disposable implements ITes
8787
// when test states change, reflect in the tree
8888
this._register(results.onTestChanged(ev => {
8989
let result = ev.item;
90-
if (result.ownComputedState === TestResultState.Unset) {
90+
// if the state is unset, or the latest run is not making the change,
91+
// double check that it's valid. Retire calls might cause previous
92+
// emit a state change for a test run that's already long completed.
93+
if (result.ownComputedState === TestResultState.Unset || ev.result !== results.results[0]) {
9194
const fallback = results.getStateById(result.item.extId);
9295
if (fallback) {
9396
result = fallback[1];

src/vs/workbench/contrib/testing/common/testResult.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,18 @@ export class LiveTestResult implements ITestResult {
449449
this.completeEmitter.fire();
450450
}
451451

452+
/**
453+
* Marks the test and all of its children in the run as retired.
454+
*/
455+
public markRetired(testId: string) {
456+
for (const [id, test] of this.testById) {
457+
if (!test.retired && id === testId || TestId.isChild(testId, id)) {
458+
test.retired = true;
459+
this.changeEmitter.fire({ reason: TestResultItemChangeReason.ComputedStateChange, item: test, result: this });
460+
}
461+
}
462+
}
463+
452464
/**
453465
* @inheritdoc
454466
*/

src/vs/workbench/contrib/testing/common/testTypes.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -469,28 +469,28 @@ export interface TestResultItem extends InternalTestItem {
469469
}
470470

471471
export namespace TestResultItem {
472-
/** Serialized version of the TestResultItem */
472+
/**
473+
* Serialized version of the TestResultItem. Note that 'retired' is not
474+
* included since all hydrated items are automatically retired.
475+
*/
473476
export interface Serialized extends InternalTestItem.Serialized {
474477
tasks: ITestTaskState.Serialized[];
475478
ownComputedState: TestResultState;
476479
computedState: TestResultState;
477-
retired?: boolean;
478480
}
479481

480482
export const serializeWithoutMessages = (original: TestResultItem): Serialized => ({
481483
...InternalTestItem.serialize(original),
482484
ownComputedState: original.ownComputedState,
483485
computedState: original.computedState,
484486
tasks: original.tasks.map(ITestTaskState.serializeWithoutMessages),
485-
retired: original.retired,
486487
});
487488

488489
export const serialize = (original: TestResultItem): Serialized => ({
489490
...InternalTestItem.serialize(original),
490491
ownComputedState: original.ownComputedState,
491492
computedState: original.computedState,
492493
tasks: original.tasks.map(ITestTaskState.serialize),
493-
retired: original.retired,
494494
});
495495

496496
export const deserialize = (serialized: Serialized): TestResultItem => ({

src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
2323
setup(() => {
2424
onTestChanged = new Emitter();
2525
resultsService = {
26+
results: [],
2627
onResultsChanged: () => undefined,
2728
onTestChanged: onTestChanged.event,
2829
getStateById: () => ({ state: { state: 0 }, computedState: 0 }),
@@ -102,7 +103,6 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
102103

103104
test('applies state changes', async () => {
104105
harness.flush();
105-
resultsService.getStateById = () => [undefined, resultInState(TestResultState.Failed)];
106106

107107
const resultInState = (state: TestResultState): TestResultItem => ({
108108
item: {
@@ -124,6 +124,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
124124
});
125125

126126
// Applies the change:
127+
resultsService.getStateById = () => [undefined, resultInState(TestResultState.Queued)];
127128
onTestChanged.fire({
128129
reason: TestResultItemChangeReason.OwnStateChange,
129130
result: null as any,
@@ -139,6 +140,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
139140
]);
140141

141142
// Falls back if moved into unset state:
143+
resultsService.getStateById = () => [undefined, resultInState(TestResultState.Failed)];
142144
onTestChanged.fire({
143145
reason: TestResultItemChangeReason.OwnStateChange,
144146
result: null as any,

src/vs/workbench/services/extensions/common/extensionsApiProposals.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export const allApiProposals = Object.freeze({
8383
terminalDimensions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts',
8484
terminalQuickFixProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts',
8585
testCoverage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testCoverage.d.ts',
86+
testInvalidateResults: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testInvalidateResults.d.ts',
8687
testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts',
8788
textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts',
8889
timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts',

0 commit comments

Comments
 (0)