Skip to content

Commit 99fda75

Browse files
fix: discovering last test in identical-named suites only
1 parent ee39d46 commit 99fda75

File tree

2 files changed

+63
-10
lines changed

2 files changed

+63
-10
lines changed

src/controller.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,20 +200,31 @@ export class Controller {
200200
const add = (
201201
parent: vscode.TestItem,
202202
node: IParsedNode,
203+
id: string,
203204
start: vscode.Location,
204205
end: vscode.Location,
205206
): vscode.TestItem => {
206-
let item = parent.children.get(node.name);
207+
let item = parent.children.get(id);
207208
if (!item) {
208-
item = this.ctrl.createTestItem(node.name, node.name, start.uri);
209+
item = this.ctrl.createTestItem(id, node.name, start.uri);
209210
testMetadata.set(item, { type: ItemType.Test });
210211
parent.children.add(item);
211212
}
212213
item.range = new vscode.Range(start.range.start, end.range.end);
213214

214215
const seen = new Map<string, vscode.TestItem>();
216+
const level2Dupes = new Map<string, vscode.TestItem>();
217+
for (const [, sibling] of parent.children) {
218+
if (sibling.id == item.id || sibling.label !== node.name) {
219+
continue;
220+
}
221+
222+
for (const [, cousin] of sibling.children) {
223+
level2Dupes.set(cousin.label, cousin);
224+
}
225+
}
215226
for (const child of node.children) {
216-
const existing = seen.get(child.name);
227+
const existing = seen.get(child.name) || level2Dupes.get(child.name);
217228
const start = sourceMap.originalPositionFor(
218229
child.location.start.line,
219230
child.location.start.column,
@@ -227,7 +238,7 @@ export class Controller {
227238
continue;
228239
}
229240

230-
seen.set(child.name, add(item, child, start, end));
241+
seen.set(child.name, add(item, child, child.name, start, end));
231242
}
232243

233244
for (const [id] of item.children) {
@@ -243,6 +254,7 @@ export class Controller {
243254
// source file. This is probably a good assumption. Likewise we assume that a single
244255
// a single describe/test is not split between different files.
245256
const newTestsInFile = new Map<string, vscode.TestItem>();
257+
let nId: number = 0;
246258
for (const node of tree) {
247259
const start = sourceMap.originalPositionFor(
248260
node.location.start.line,
@@ -251,7 +263,14 @@ export class Controller {
251263
const end = sourceMap.originalPositionFor(node.location.end.line, node.location.end.column);
252264
const file = last(this.getContainingItemsForFile(start.uri, { compiledFile: uri }))!.item!;
253265
diagnosticCollection.delete(start.uri);
254-
newTestsInFile.set(node.name, add(file, node, start, end));
266+
if (newTestsInFile.has(node.name) && ["describe", "suite"].includes(node.fn)) {
267+
const id = `${node.name}#${nId++}`;
268+
newTestsInFile.set(id, add(file, node, id, start, end));
269+
}
270+
else {
271+
nId = 0;
272+
newTestsInFile.set(node.name, add(file, node, node.name, start, end));
273+
}
255274
}
256275

257276
if (previous) {

src/runner.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,33 @@ export class TestRunner implements vscode.Disposable {
9999
const concurrency = this.concurrency.value || cpus().length;
100100
const getTestByPath = (path: string[]): vscode.TestItem | undefined => {
101101
const uri = vscode.Uri.parse(path[0]);
102-
let item = last(getContainingItemsForFile(wf, ctrl, uri))!.item;
103-
if (!item) {
102+
let fileItem = last(getContainingItemsForFile(wf, ctrl, uri))!.item;
103+
if (!fileItem) {
104104
return undefined;
105105
}
106106

107-
for (let i = 1; item && i < path.length; i++) {
108-
item = item.children.get(path[i]);
107+
let item: vscode.TestItem;
108+
const searchPath = (test: vscode.TestItem, pathIndex: number) => {
109+
let id = path[pathIndex];
110+
let nId = 0;
111+
let child;
112+
do {
113+
child = test.children.get(id);
114+
if (child && path[pathIndex + 1] === undefined) {
115+
item = child;
116+
}
117+
else {
118+
child && searchPath(child, pathIndex + 1);
119+
}
120+
121+
id = `${path[pathIndex]}#${nId++}`;
122+
}
123+
while (child)
109124
}
110125

111-
return item;
126+
searchPath(fileItem, 1);
127+
128+
return item!;
112129
};
113130

114131
// inline source maps read from the runtime. These will both be definitive
@@ -422,6 +439,23 @@ export class TestRunner implements vscode.Disposable {
422439
const modernNamePatterns = nodeMajorVersion >= 22;
423440

424441
const addTestsToFileRecord = (record: IIncludeFile, queue: vscode.TestItem[]) => {
442+
//merge queue-items with the same (extended) id
443+
for (let i = 0; i < queue.length; i++) {
444+
let nId = 0;
445+
for (let j = 0; j < queue.length; j++) {
446+
if (i == j) continue;
447+
448+
if (`${queue[i].id}#${nId++}` === queue[j].id) {
449+
for (const [, child] of queue[j].children) {
450+
queue[i].children.add(child);
451+
}
452+
queue.splice(j, 1);
453+
j--;
454+
if (i > j) i--;
455+
}
456+
}
457+
}
458+
425459
record.include ??= new Set();
426460

427461
while (queue.length) {

0 commit comments

Comments
 (0)