Skip to content

Commit 91f8ced

Browse files
cjihrigehsankhfr
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: nodejs#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 ab6ffb0 commit 91f8ced

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
@@ -3204,6 +3204,16 @@ test('top level test', (t) => {
32043204
});
32053205
```
32063206

3207+
### `context.filePath`
3208+
3209+
<!-- YAML
3210+
added: REPLACEME
3211+
-->
3212+
3213+
The absolute path of the test file that created the current test. If a test file
3214+
imports additional modules that generate tests, the imported tests will return
3215+
the path of the root test file.
3216+
32073217
### `context.fullName`
32083218

32093219
<!-- YAML
@@ -3438,6 +3448,16 @@ An instance of `SuiteContext` is passed to each suite function in order to
34383448
interact with the test runner. However, the `SuiteContext` constructor is not
34393449
exposed as part of the API.
34403450

3451+
### `context.filePath`
3452+
3453+
<!-- YAML
3454+
added: REPLACEME
3455+
-->
3456+
3457+
The absolute path of the test file that created the current suite. If a test
3458+
file imports additional modules that generate suites, the imported suites will
3459+
return the path of the root test file.
3460+
34413461
### `context.name`
34423462

34433463
<!-- 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)