Skip to content

Commit 698e44f

Browse files
cjihrigtargos
authored andcommitted
test_runner: add context.filePath
This commit adds a filePath getter to the TestContext and SuiteContext classes. This allows a context to be mapped back to the original test file that created it, even if it was imported from another file. This is useful for mapping features like test snapshots to the correct test file. This is also prep work for supporting running test files in the test runner process. PR-URL: #53853 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent bac3a48 commit 698e44f

File tree

4 files changed

+84
-2
lines changed

4 files changed

+84
-2
lines changed

doc/api/test.md

+20
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,16 @@ test('top level test', (t) => {
31943194
});
31953195
```
31963196

3197+
### `context.filePath`
3198+
3199+
<!-- YAML
3200+
added: REPLACEME
3201+
-->
3202+
3203+
The absolute path of the test file that created the current test. If a test file
3204+
imports additional modules that generate tests, the imported tests will return
3205+
the path of the root test file.
3206+
31973207
### `context.fullName`
31983208

31993209
<!-- YAML
@@ -3427,6 +3437,16 @@ An instance of `SuiteContext` is passed to each suite function in order to
34273437
interact with the test runner. However, the `SuiteContext` constructor is not
34283438
exposed as part of the API.
34293439

3440+
### `context.filePath`
3441+
3442+
<!-- YAML
3443+
added: REPLACEME
3444+
-->
3445+
3446+
The absolute path of the test file that created the current suite. If a test
3447+
file imports additional modules that generate suites, the imported suites will
3448+
return the path of the root test file.
3449+
34303450
### `context.name`
34313451

34323452
<!-- YAML

lib/internal/test_runner/harness.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ let globalRoot;
221221
let reportersSetup;
222222
function getGlobalRoot() {
223223
if (!globalRoot) {
224-
globalRoot = createTestTree();
224+
globalRoot = createTestTree({ __proto__: null, entryFile: process.argv?.[1] });
225225
globalRoot.reporter.on('test:fail', (data) => {
226226
if (data.todo === undefined || data.todo === false) {
227227
process.exitCode = kGenericUserError;

lib/internal/test_runner/test.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ class TestContext {
225225
return this.#test.name;
226226
}
227227

228+
get filePath() {
229+
return this.#test.entryFile;
230+
}
231+
228232
get fullName() {
229233
return getFullName(this.#test);
230234
}
@@ -343,6 +347,10 @@ class SuiteContext {
343347
return this.#suite.name;
344348
}
345349

350+
get filePath() {
351+
return this.#suite.entryFile;
352+
}
353+
346354
get fullName() {
347355
return getFullName(this.#suite);
348356
}
@@ -357,7 +365,7 @@ class Test extends AsyncResource {
357365
super('Test');
358366

359367
let { fn, name, parent } = options;
360-
const { concurrency, loc, only, timeout, todo, skip, signal, plan } = options;
368+
const { concurrency, entryFile, loc, only, timeout, todo, skip, signal, plan } = options;
361369

362370
if (typeof fn !== 'function') {
363371
fn = noop;
@@ -386,6 +394,7 @@ class Test extends AsyncResource {
386394
this.runOnlySubtests = this.only;
387395
this.childNumber = 0;
388396
this.timeout = kDefaultTimeout;
397+
this.entryFile = entryFile;
389398
this.root = this;
390399
this.hooks = {
391400
__proto__: null,
@@ -406,6 +415,7 @@ class Test extends AsyncResource {
406415
this.runOnlySubtests = !this.only;
407416
this.childNumber = parent.subtests.length + 1;
408417
this.timeout = parent.timeout;
418+
this.entryFile = parent.entryFile;
409419
this.root = parent.root;
410420
this.hooks = {
411421
__proto__: null,
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
require('../common');
3+
const tmpdir = require('../common/tmpdir');
4+
const { strictEqual } = require('node:assert');
5+
const { writeFileSync } = require('node:fs');
6+
const { suite, test } = require('node:test');
7+
8+
tmpdir.refresh();
9+
10+
suite('suite', (t) => {
11+
strictEqual(t.filePath, __filename);
12+
13+
test('test', (t) => {
14+
strictEqual(t.filePath, __filename);
15+
16+
t.test('subtest', (t) => {
17+
strictEqual(t.filePath, __filename);
18+
19+
t.test('subsubtest', (t) => {
20+
strictEqual(t.filePath, __filename);
21+
});
22+
});
23+
});
24+
});
25+
26+
test((t) => {
27+
strictEqual(t.filePath, __filename);
28+
});
29+
30+
const importedTestFile = tmpdir.resolve('temp.js');
31+
writeFileSync(importedTestFile, `
32+
'use strict';
33+
const { strictEqual } = require('node:assert');
34+
const { suite, test } = require('node:test');
35+
36+
suite('imported suite', (t) => {
37+
strictEqual(t.filePath, ${JSON.stringify(__filename)});
38+
39+
test('imported test', (t) => {
40+
strictEqual(t.filePath, ${JSON.stringify(__filename)});
41+
42+
t.test('imported subtest', (t) => {
43+
strictEqual(t.filePath, ${JSON.stringify(__filename)});
44+
45+
t.test('imported subsubtest', (t) => {
46+
strictEqual(t.filePath, ${JSON.stringify(__filename)});
47+
});
48+
});
49+
});
50+
});
51+
`);
52+
require(importedTestFile);

0 commit comments

Comments
 (0)