Skip to content

Commit bd4697a

Browse files
atlowChemiRafaelGSS
authored andcommitted
test_runner: expose reporter for use in run api
PR-URL: #47238 Fixes: #47231 Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 7e24498 commit bd4697a

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

doc/api/test.md

+35-2
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,13 @@ test('spies on an object method', (t) => {
509509
## Test reporters
510510

511511
<!-- YAML
512-
added: v19.6.0
512+
added:
513+
- v19.6.0
514+
- v18.15.0
515+
changes:
516+
- version: REPLACEME
517+
pr-url: https://github.com/nodejs/node/pull/47238
518+
description: Reporters are now exposed at `node:test/reporters`.
513519
-->
514520

515521
The `node:test` module supports passing [`--test-reporter`][]
@@ -531,6 +537,21 @@ The following built-reporters are supported:
531537
When `stdout` is a [TTY][], the `spec` reporter is used by default.
532538
Otherwise, the `tap` reporter is used by default.
533539

540+
The exact output of these reporters is subject to change between versions of
541+
Node.js, and should not be relied on programmatically. If programmatic access
542+
to the test runner's output is required, use the events emitted by the
543+
{TestsStream}.
544+
545+
The reporters are available via the `node:test/reporters` module:
546+
547+
```mjs
548+
import { tap, spec, dot } from 'node:test/reporters';
549+
```
550+
551+
```cjs
552+
const { tap, spec, dot } = require('node:test/reporters');
553+
```
554+
534555
### Custom reporters
535556

536557
[`--test-reporter`][] can be used to specify a path to custom reporter.
@@ -722,8 +743,20 @@ added: v18.9.0
722743
**Default:** `undefined`.
723744
* Returns: {TestsStream}
724745

725-
```js
746+
```mjs
747+
import { tap } from 'node:test/reporters';
748+
import process from 'node:process';
749+
750+
run({ files: [path.resolve('./tests/test.js')] })
751+
.compose(tap)
752+
.pipe(process.stdout);
753+
```
754+
755+
```cjs
756+
const { tap } = require('node:test/reporters');
757+
726758
run({ files: [path.resolve('./tests/test.js')] })
759+
.compose(tap)
727760
.pipe(process.stdout);
728761
```
729762

lib/test/reporters.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
const { ObjectDefineProperties } = primordials;
4+
5+
let dot;
6+
let spec;
7+
let tap;
8+
9+
ObjectDefineProperties(module.exports, {
10+
__proto__: null,
11+
dot: {
12+
__proto__: null,
13+
configurable: true,
14+
enumerable: true,
15+
get() {
16+
dot ??= require('internal/test_runner/reporter/dot');
17+
return dot;
18+
},
19+
},
20+
spec: {
21+
__proto__: null,
22+
configurable: true,
23+
enumerable: true,
24+
get() {
25+
spec ??= require('internal/test_runner/reporter/spec');
26+
return spec;
27+
},
28+
},
29+
tap: {
30+
__proto__: null,
31+
configurable: true,
32+
enumerable: true,
33+
get() {
34+
tap ??= require('internal/test_runner/reporter/tap');
35+
return tap;
36+
},
37+
},
38+
});

test/parallel/test-runner-run.mjs

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as common from '../common/index.mjs';
22
import * as fixtures from '../common/fixtures.mjs';
33
import { join } from 'node:path';
44
import { describe, it, run } from 'node:test';
5+
import { dot, spec, tap } from 'node:test/reporters';
56
import assert from 'node:assert';
67

78
const testFixtures = fixtures.path('test-runner');
@@ -65,4 +66,39 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
6566
code: 'ERR_INVALID_ARG_TYPE'
6667
}));
6768
});
69+
70+
it('should be piped with dot', async () => {
71+
const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(dot).toArray();
72+
assert.deepStrictEqual(result, [
73+
'.',
74+
'\n',
75+
]);
76+
});
77+
78+
it('should be piped with spec', async () => {
79+
const specReporter = new spec();
80+
const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(specReporter).toArray();
81+
const stringResults = result.map((bfr) => bfr.toString());
82+
assert.match(stringResults[0], /this should pass/);
83+
assert.match(stringResults[1], /tests 1/);
84+
assert.match(stringResults[1], /pass 1/);
85+
});
86+
87+
it('should be piped with tap', async () => {
88+
const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(tap).toArray();
89+
assert.strictEqual(result.length, 13);
90+
assert.strictEqual(result[0], 'TAP version 13\n');
91+
assert.strictEqual(result[1], '# Subtest: this should pass\n');
92+
assert.strictEqual(result[2], 'ok 1 - this should pass\n');
93+
assert.match(result[3], /duration_ms: \d+\.?\d*/);
94+
assert.strictEqual(result[4], '1..1\n');
95+
assert.strictEqual(result[5], '# tests 1\n');
96+
assert.strictEqual(result[6], '# suites 0\n');
97+
assert.strictEqual(result[7], '# pass 1\n');
98+
assert.strictEqual(result[8], '# fail 0\n');
99+
assert.strictEqual(result[9], '# cancelled 0\n');
100+
assert.strictEqual(result[10], '# skipped 0\n');
101+
assert.strictEqual(result[11], '# todo 0\n');
102+
assert.match(result[12], /# duration_ms \d+\.?\d*/);
103+
});
68104
});

0 commit comments

Comments
 (0)