Skip to content

Commit a13a4ef

Browse files
committed
fix: resolve file field for suites based on tests when using mocha exports ui
1 parent a67b802 commit a13a4ef

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

src/test-reader/mocha-reader/tree-builder-decorator.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { Suite, Test, Hook } = require("../test-object");
22
const crypto = require("../../utils/crypto");
3+
const { computeFile } = require("./utils");
34

45
class TreeBuilderDecorator {
56
#treeBuilder;
@@ -17,7 +18,9 @@ class TreeBuilderDecorator {
1718
}
1819

1920
addSuite(mochaSuite) {
20-
const { id: mochaId, file } = mochaSuite;
21+
const { id: mochaId } = mochaSuite;
22+
const file = computeFile(mochaSuite) ?? "unknown-file";
23+
2124
const positionInFile = this.#suiteCounter.get(file) || 0;
2225
const id = mochaSuite.root ? mochaId : crypto.getShortMD5(file) + positionInFile;
2326
const suite = this.#mkTestObject(Suite, mochaSuite, { id });
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// When using "exports" mocha interface, "file" field is absent on suites, and available on tests only.
2+
// This helper tries to resolve "file" field for suites, drilling down to child tests and using their file field.
3+
4+
const findTopmostSuite = mochaSuite => {
5+
if (mochaSuite.parent && mochaSuite.parent.root) {
6+
return mochaSuite;
7+
}
8+
9+
if (!mochaSuite.parent) {
10+
return null;
11+
}
12+
13+
return findTopmostSuite(mochaSuite.parent);
14+
};
15+
16+
const getFile = mochaSuite => {
17+
if (mochaSuite.file) {
18+
return mochaSuite.file;
19+
}
20+
21+
if (mochaSuite.tests.length > 0 && mochaSuite.tests[0].file) {
22+
return mochaSuite.tests[0].file;
23+
}
24+
25+
for (const childSuite of mochaSuite.suites) {
26+
const computedFile = getFile(childSuite);
27+
if (computedFile) {
28+
return computedFile;
29+
}
30+
}
31+
32+
return null;
33+
};
34+
35+
const fillSuitesFileField = (mochaSuite, file) => {
36+
mochaSuite.file = file;
37+
38+
if (mochaSuite.suites) {
39+
for (const childSuite of mochaSuite.suites) {
40+
fillSuitesFileField(childSuite, file);
41+
}
42+
}
43+
};
44+
45+
const computeFile = mochaSuite => {
46+
if (mochaSuite.file) {
47+
return mochaSuite.file;
48+
}
49+
50+
const topmostSuite = findTopmostSuite(mochaSuite);
51+
const file = topmostSuite && getFile(topmostSuite);
52+
53+
if (topmostSuite && file) {
54+
fillSuitesFileField(topmostSuite, file);
55+
56+
return file;
57+
}
58+
59+
return null;
60+
};
61+
62+
module.exports = {
63+
computeFile,
64+
};

0 commit comments

Comments
 (0)