Skip to content

Commit 161c11a

Browse files
committed
feat(vscode): eagerly scan all test files on init to populate test tree
- Add scanAllTestFiles() in src/testTree.ts to find **/*.test.* and **/*.spec.* across workspace, create root TestItems, and parse contents to build children. - Invoke scanAllTestFiles() in extension constructor and on root resolve to ensure the TestController includes all tests without opening files. - Keep existing FS watchers for incremental updates.
1 parent 5c967da commit 161c11a

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

packages/vscode/src/extension.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RstestApi } from './master';
33
import {
44
gatherTestItems,
55
getContentFromFilesystem,
6+
scanAllTestFiles,
67
TestCase,
78
TestFile,
89
testData,
@@ -43,6 +44,10 @@ class Rstest {
4344
this.setupTestController();
4445
this.api = new RstestApi();
4546
this.api.createChildProcess();
47+
48+
// Populate the test tree eagerly on construction
49+
// (does not rely on the Testing view resolving the root)
50+
scanAllTestFiles(this.ctrl);
4651
}
4752

4853
private setupEventHandlers(context: vscode.ExtensionContext) {
@@ -152,6 +157,8 @@ class Rstest {
152157
this.context.subscriptions.push(
153158
...startWatchingWorkspace(this.ctrl, this.fileChangedEmitter),
154159
);
160+
// Ensure all test files are discovered and parsed at startup
161+
// await scanAllTestFiles(this.ctrl);
155162
return;
156163
}
157164

packages/vscode/src/testTree.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,62 @@ export function gatherTestItems(collection: vscode.TestItemCollection) {
3232
return items;
3333
}
3434

35+
/**
36+
* Scans the workspace for all test files and ensures they exist as root
37+
* TestItems on the provided controller. Also parses their contents so the
38+
* initial tree includes discovered tests without requiring files to open.
39+
*/
40+
export async function scanAllTestFiles(
41+
controller: vscode.TestController,
42+
): Promise<void> {
43+
if (!vscode.workspace.workspaceFolders?.length) return;
44+
45+
const globs = ['**/*.test.*', '**/*.spec.*'];
46+
const uris = new Set<string>();
47+
48+
// Collect and dedupe all matching files across workspace folders
49+
for (const folder of vscode.workspace.workspaceFolders) {
50+
for (const g of globs) {
51+
const pattern = new vscode.RelativePattern(folder, g);
52+
const found = await vscode.workspace.findFiles(pattern);
53+
for (const f of found) uris.add(f.toString());
54+
}
55+
}
56+
57+
const tasks: Promise<void>[] = [];
58+
59+
for (const uriStr of uris) {
60+
const uri = vscode.Uri.parse(uriStr);
61+
let item = controller.items.get(uriStr);
62+
let fileData: TestFile | undefined;
63+
64+
if (!item) {
65+
item = controller.createTestItem(
66+
uriStr,
67+
uri.path.split('/').pop() || uriStr,
68+
uri,
69+
);
70+
controller.items.add(item);
71+
fileData = new TestFile();
72+
testData.set(item, fileData);
73+
item.canResolveChildren = true;
74+
} else {
75+
const data = testData.get(item);
76+
if (data instanceof TestFile) {
77+
fileData = data;
78+
} else {
79+
fileData = new TestFile();
80+
testData.set(item, fileData);
81+
}
82+
}
83+
84+
// Parse immediately so children are available in the tree
85+
tasks.push(fileData.updateFromDisk(controller, item));
86+
}
87+
88+
await Promise.all(tasks);
89+
}
90+
3591
export class TestFile {
3692
public didResolve = false;
3793

0 commit comments

Comments
 (0)