Skip to content

Commit

Permalink
testing: improve test children API
Browse files Browse the repository at this point in the history
This changeset results from the discussion in and fixes microsoft#126987.
Migration for these changes should take about 15-20 minutes.

- `createTestItem` no longer takes a parent. Instead, it creates a free-
  floating test item, which can be added as a child of a parent.
- The `TestItem.children` is now a `TestItemCollection`, a set-like
  interface that also allows replacing items (intelligently diffing
	them internally) wholesale. This removes the need for the "generation
	counter" used in samples previously.
- There is no longer a `root` on the test controller, but instead an
  `items` property which is the same `TestItemCollection`
- The `tests` in the `TestRunRequest` has been replaced with an `include`
  property. If undefined, the extension should run all tests. (Since
	there is no longer a root to reference).

Here's some example migrations:

- microsoft/vscode-extension-samples@3fad3d6
- microsoft/vscode-selfhost-test-provider@3aff746
  • Loading branch information
connor4312 committed Jul 15, 2021
1 parent 039582c commit 581ff12
Show file tree
Hide file tree
Showing 18 changed files with 662 additions and 367 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
"type": "pwa-chrome",
"request": "launch",
"name": "Launch VS Code Internal",
"trace": true,
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.bat"
},
Expand Down
91 changes: 53 additions & 38 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,16 @@ declare module 'vscode' {
*/
export function createTestObserver(): TestObserver;

/**
* Creates a new managed {@link TestItem} instance. It can be added into
* the {@link TestItem.children} of an existing item, or into the
* {@link TestController.items}.
* @param id Unique identifier for the TestItem.
* @param label Human-readable label of the test item.
* @param uri URI this TestItem is associated with. May be a file or directory.
*/
export function createTestItem(id: string, label: string, uri?: Uri): TestItem;

/**
* List of test results stored by the editor, sorted in descending
* order by their `completedAt` time.
Expand Down Expand Up @@ -1937,8 +1947,8 @@ declare module 'vscode' {
label: string;

/**
* Root test item. Tests in the workspace should be added as children of
* the root. The extension controls when to add these, although the
* Available test items. Tests in the workspace should be added in this
* collection. The extension controls when to add these, although the
* editor may request children using the {@link resolveChildrenHandler},
* and the extension should add tests for a file when
* {@link vscode.workspace.onDidOpenTextDocument} fires in order for
Expand All @@ -1948,9 +1958,7 @@ declare module 'vscode' {
* as files change. See {@link resolveChildrenHandler} for details around
* for the lifecycle of watches.
*/
// todo@API a little weird? what is its label, id, busy state etc? Can I dispose this?
// todo@API allow createTestItem-calls without parent and simply treat them as root (similar to createSourceControlResourceGroup)
readonly root: TestItem;
readonly items: TestItemCollection;

/**
* Creates a configuration used for running tests. Extensions must create
Expand All @@ -1962,28 +1970,11 @@ declare module 'vscode' {
*/
createRunConfiguration(label: string, group: TestRunConfigurationGroup, runHandler: TestRunHandler, isDefault?: boolean): TestRunConfiguration;

/**
* Creates a new managed {@link TestItem} instance as a child of this
* one.
* @param id Unique identifier for the TestItem.
* @param label Human-readable label of the test item.
* @param parent Parent of the item. This is required; top-level items
* should be created as children of the {@link root}.
* @param uri URI this TestItem is associated with. May be a file or directory.
* @param data Custom data to be stored in {@link TestItem.data}
*/
createTestItem(
id: string,
label: string,
parent: TestItem,
uri?: Uri,
): TestItem;

/**
* A function provided by the extension that the editor may call to request
* children of a test item, if the {@link TestItem.canExpand} is `true`.
* When called, the item should discover children and call
* {@link TestController.createTestItem} as children are discovered.
* {@link vscode.test.createTestItem} as children are discovered.
*
* The item in the explorer will automatically be marked as "busy" until
* the function returns or the returned thenable resolves.
Expand Down Expand Up @@ -2030,11 +2021,12 @@ declare module 'vscode' {
*/
export class TestRunRequest {
/**
* Array of specific tests to run. The controllers should run all of the
* given tests and all children of the given tests, excluding any tests
* that appear in {@link TestRunRequest.exclude}.
* Filter for specific tests to run. If given, the extension should run all
* of the given tests and all children of the given tests, excluding
* any tests that appear in {@link TestRunRequest.exclude}. If this is
* not given, then the extension should simply run all tests.
*/
tests: TestItem[];
include?: TestItem[];

/**
* An array of tests the user has marked as excluded in the editor. May be
Expand All @@ -2051,11 +2043,11 @@ declare module 'vscode' {
configuration?: TestRunConfiguration;

/**
* @param tests Array of specific tests to run.
* @param tests Array of specific tests to run, or undefined to run all tests
* @param exclude Tests to exclude from the run
* @param configuration The run configuration used for this request.
*/
constructor(tests: readonly TestItem[], exclude?: readonly TestItem[], configuration?: TestRunConfiguration);
constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], configuration?: TestRunConfiguration);
}

/**
Expand Down Expand Up @@ -2115,6 +2107,34 @@ declare module 'vscode' {
end(): void;
}

/**
* Collection of test items, found in {@link TestItem.children} and
* {@link TestController.items}.
*/
export interface TestItemCollection {
/**
* A read-only array of all the test items children. Can be retrieved, or
* set in order to replace children in the collection.
*/
all: readonly TestItem[];

/**
* Adds the test item to the children. If an item with the same ID already
* exists, it'll be replaced.
*/
add(item: TestItem): void;

/**
* Removes the a single test item from the collection.
*/
remove(itemId: string): void;

/**
* Efficiently gets a test item by ID, if it exists, in the children.
*/
get(itemId: string): TestItem | undefined;
}

/**
* 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.
Expand All @@ -2135,12 +2155,12 @@ declare module 'vscode' {
/**
* A mapping of children by ID to the associated TestItem instances.
*/
//todo@API use array over es6-map
readonly children: ReadonlyMap<string, TestItem>;
readonly children: TestItemCollection;

/**
* The parent of this item, given in {@link TestController.createTestItem}.
* This is undefined only for the {@link TestController.root}.
* The parent of this item, given in {@link vscode.test.createTestItem}.
* This is undefined top-level items in the `TestController`, and for
* items that aren't yet assigned to a parent.
*/
readonly parent?: TestItem;

Expand Down Expand Up @@ -2193,11 +2213,6 @@ declare module 'vscode' {
* Extensions should generally not override this method.
*/
invalidateResults(): void;

/**
* Removes the test and its children from the tree.
*/
dispose(): void;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension);
return extHostTesting.createTestController(provider, label);
},
createTestItem(id, label, uri) {
checkProposedApiEnabled(extension);
return extHostTesting.createTestItem(id, label, uri);
},
createTestObserver() {
checkProposedApiEnabled(extension);
return extHostTesting.createTestObserver();
Expand Down
Loading

0 comments on commit 581ff12

Please sign in to comment.