Skip to content

Commit

Permalink
Test tags from suites should be inherited (#1015)
Browse files Browse the repository at this point in the history
Tags defined on swift-testing suites are meant to be inherited by child
suites/tests. VS Code doesn't apply this inheritance automatically, so
we must set a suite's tags on its children ourselves.

Issue: #1014
  • Loading branch information
plemarquand committed Aug 19, 2024
1 parent d131215 commit d801d41
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
27 changes: 27 additions & 0 deletions src/TestExplorer/TestDiscovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,27 @@ function deepMergeTestItemChildren(existingItem: vscode.TestItem, newItem: vscod
);
}

/**
* Given a `TestClass` adds the TestClasses tags to each of its children.
* Does not apply recursively.
* @param testClass A test class whose tags should be propagated to its children.
* @returns A `TestClass` whose children include the parent's tags.
*/
function applyTagsToChildren(testClass: TestClass): TestClass {
return {
...testClass,
children: testClass.children.reduce((children, child) => {
return [
...children,
{
...child,
tags: [...child.tags, ...testClass.tags],
},
];
}, [] as TestClass[]),
};
}

/**
* Updates the existing `vscode.TestItem` if it exists with the same ID as the `TestClass`,
* otherwise creates an add a new one. The location on the returned vscode.TestItem is always updated.
Expand Down Expand Up @@ -203,6 +224,12 @@ export function upsertTestItem(
deepMergeTestItemChildren(existingItem, newItem);
}

// In VS Code tags are not inherited automatically, so if we're recieving a suite we need
// to set a suites tag on all of its children. Because test items are added top down the children
// aren't updated recursively all at once, but rather one level at a time which then propagages
// parent tags down the tree as children are upserted.
testItem = applyTagsToChildren(testItem);

// Manually add the test style as a tag so we can filter by test type.
newItem.tags = [{ id: testItem.style }, ...testItem.tags];

Expand Down
74 changes: 68 additions & 6 deletions test/suite/testexplorer/TestDiscovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ suite("TestDiscovery Suite", () => {
interface SimplifiedTestItem {
id: string;
children: SimplifiedTestItem[];
tags: readonly { id: string }[];
}

function testControllerChildren(collection: vscode.TestItemCollection): SimplifiedTestItem[] {
return reduceTestItemChildren(
collection,
(acc, item) => [
...acc,
{ id: item.id, children: testControllerChildren(item.children) },
{
id: item.id,
tags: [...item.tags.map(tag => ({ id: tag.id }))],
children: testControllerChildren(item.children),
},
],
[] as SimplifiedTestItem[]
);
Expand Down Expand Up @@ -77,7 +82,7 @@ suite("TestDiscovery Suite", () => {
updateTests(testController, [testItem("bar")]);

assert.deepStrictEqual(testControllerChildren(testController.items), [
{ id: "bar", children: [] },
{ id: "bar", tags: [{ id: "XCTest" }, { id: "runnable" }], children: [] },
]);
});

Expand Down Expand Up @@ -109,9 +114,10 @@ suite("TestDiscovery Suite", () => {
assert.deepStrictEqual(testControllerChildren(testController.items), [
{
id: "foo",
tags: [{ id: "XCTest" }, { id: "runnable" }],
children: [
{ id: "baz", children: [] },
{ id: "bar", children: [] },
{ id: "baz", tags: [{ id: "XCTest" }, { id: "runnable" }], children: [] },
{ id: "bar", tags: [{ id: "XCTest" }, { id: "runnable" }], children: [] },
],
},
]);
Expand Down Expand Up @@ -140,7 +146,13 @@ suite("TestDiscovery Suite", () => {
updateTests(testController, [newFoo]);

assert.deepStrictEqual(testControllerChildren(testController.items), [
{ id: "foo", children: [{ id: "bar", children: [] }] },
{
id: "foo",
tags: [{ id: "XCTest" }, { id: "runnable" }],
children: [
{ id: "bar", tags: [{ id: "XCTest" }, { id: "runnable" }], children: [] },
],
},
]);
assert.deepStrictEqual(testController.items.get("foo")?.uri, newLocation.uri);
assert.deepStrictEqual(testController.items.get("foo")?.label, "New Label");
Expand Down Expand Up @@ -168,7 +180,57 @@ suite("TestDiscovery Suite", () => {
updateTestsFromClasses(testController, swiftPackage, [item]);

assert.deepStrictEqual(testControllerChildren(testController.items), [
{ id: "TestTarget", children: [{ id: "bar", children: [] }] },
{
id: "TestTarget",
tags: [{ id: "test-target" }, { id: "runnable" }],
children: [
{ id: "bar", tags: [{ id: "XCTest" }, { id: "runnable" }], children: [] },
],
},
]);
});

test("Children in suites with tags inherit the suite's tags", async () => {
const testSuite = testItem("suite");
testSuite.tags = [{ id: "rootTag" }];
const childSuite = testItem("childSuite");
childSuite.tags = [{ id: "childSuiteTag" }];
const childTest = testItem("childTest");
childTest.tags = [{ id: "childTestTag" }];
childSuite.children = [childTest];
testSuite.children = [childSuite];

updateTests(testController, [testSuite]);

assert.deepEqual(testControllerChildren(testController.items), [
{
id: "suite",
tags: [{ id: "XCTest" }, { id: "rootTag" }, { id: "runnable" }],
children: [
{
id: "childSuite",
tags: [
{ id: "XCTest" },
{ id: "childSuiteTag" },
{ id: "rootTag" },
{ id: "runnable" },
],
children: [
{
id: "childTest",
children: [],
tags: [
{ id: "XCTest" },
{ id: "childTestTag" },
{ id: "childSuiteTag" },
{ id: "rootTag" },
{ id: "runnable" },
],
},
],
},
],
},
]);
});
});

0 comments on commit d801d41

Please sign in to comment.