From 3db2b52568e476f49d934900b3ef5a769274c2fc Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Thu, 23 Mar 2023 20:48:33 +0200 Subject: [PATCH 1/7] test_runner: expose reporter for use in run api --- doc/api/test.md | 22 +++++++++++++++++++++- lib/test/reporters.js | 11 +++++++++++ test/parallel/test-runner-run.mjs | 20 ++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 lib/test/reporters.js diff --git a/doc/api/test.md b/doc/api/test.md index e59889fff78731..f07f3cf08aa944 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -546,6 +546,16 @@ Node.js, and should not be relied on programmatically. If programmatic access to the test runner's output is required, use the events emitted by the {TestsStream}. +The reporters are available via the `node:test/reporters` module: + +```mjs +import { tap, spec, dot } from 'node:test/reporters'; +``` + +```cjs +const { tap, spec, dot } = require('node:test/reporters'); +``` + ### Custom reporters [`--test-reporter`][] can be used to specify a path to custom reporter. @@ -739,8 +749,18 @@ added: **Default:** `undefined`. * Returns: {TestsStream} -```js +```mjs +import { tap } from 'node:test/reporters'; + +run({ files: [path.resolve('./tests/test.js')] }) + .compose(tap) + .pipe(process.stdout); +``` +```cjs +const { tap } = require('node:test/reporters'); + run({ files: [path.resolve('./tests/test.js')] }) + .compose(tap) .pipe(process.stdout); ``` diff --git a/lib/test/reporters.js b/lib/test/reporters.js new file mode 100644 index 00000000000000..6b1f2a52778044 --- /dev/null +++ b/lib/test/reporters.js @@ -0,0 +1,11 @@ +'use strict'; + +const dot = require('internal/test_runner/reporter/dot'); +const spec = require('internal/test_runner/reporter/spec'); +const tap = require('internal/test_runner/reporter/tap'); + +module.exports = { + dot, + spec, + tap, +}; diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 6ac007bfb5dd6c..f2f33c30b233f5 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -2,6 +2,8 @@ import * as common from '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; import { join } from 'node:path'; import { describe, it, run } from 'node:test'; +import { Writable } from 'node:stream'; +import { dot } from 'node:test/reporters'; import assert from 'node:assert'; const testFixtures = fixtures.path('test-runner'); @@ -65,4 +67,22 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { code: 'ERR_INVALID_ARG_TYPE' })); }); + + it('should be piped with dot', (ctx, done) => { + const written = []; + const writer = new Writable(); + writer._write = function(chunk, encoding, cb) { + written.push(chunk.toString()); + process.nextTick(cb); + }; + function finish() { + assert.deepStrictEqual(written, [ + '.', + '\n', + ]); + done(); + } + writer.on('finish', finish); + run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(dot).pipe(writer); + }); }); From 0e16ae4416dec767b610b980bbec697e9820b360 Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Fri, 24 Mar 2023 07:04:03 +0200 Subject: [PATCH 2/7] test_runner: CR - fix lint error & cleaner UT --- doc/api/test.md | 1 + test/parallel/test-runner-run.mjs | 22 ++++++---------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/doc/api/test.md b/doc/api/test.md index f07f3cf08aa944..1fd6d212b53309 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -751,6 +751,7 @@ added: ```mjs import { tap } from 'node:test/reporters'; +import process from 'node:process'; run({ files: [path.resolve('./tests/test.js')] }) .compose(tap) diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index f2f33c30b233f5..10c85fbae3b444 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -68,21 +68,11 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { })); }); - it('should be piped with dot', (ctx, done) => { - const written = []; - const writer = new Writable(); - writer._write = function(chunk, encoding, cb) { - written.push(chunk.toString()); - process.nextTick(cb); - }; - function finish() { - assert.deepStrictEqual(written, [ - '.', - '\n', - ]); - done(); - } - writer.on('finish', finish); - run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(dot).pipe(writer); + it('should be piped with dot', async () => { + const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(dot).toArray(); + assert.deepStrictEqual(result, [ + '.', + '\n', + ]); }); }); From 7d1ba82b9947b8ea00ffa827324b72b172ea74bd Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Fri, 24 Mar 2023 08:40:22 +0200 Subject: [PATCH 3/7] test_runner: fix lint error --- doc/api/test.md | 1 + test/parallel/test-runner-run.mjs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/test.md b/doc/api/test.md index 1fd6d212b53309..f2399c9401eddd 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -757,6 +757,7 @@ run({ files: [path.resolve('./tests/test.js')] }) .compose(tap) .pipe(process.stdout); ``` + ```cjs const { tap } = require('node:test/reporters'); diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 10c85fbae3b444..5b57d5585796fc 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -2,7 +2,6 @@ import * as common from '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; import { join } from 'node:path'; import { describe, it, run } from 'node:test'; -import { Writable } from 'node:stream'; import { dot } from 'node:test/reporters'; import assert from 'node:assert'; From 16edd363b5ca2cdf0370e1687a9dc02e515f7322 Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Sat, 25 Mar 2023 22:41:32 +0300 Subject: [PATCH 4/7] test_runner: CR add UT & lazy require --- doc/api/test.md | 4 +++ lib/test/reporters.js | 51 +++++++++++++++++++++++++------ test/parallel/test-runner-run.mjs | 30 +++++++++++++++++- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/doc/api/test.md b/doc/api/test.md index f2399c9401eddd..165d38f620b737 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -520,6 +520,10 @@ test('spies on an object method', (t) => { added: - v19.6.0 - v18.15.0 +changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/47238 + description: Reporters are now exposed at `node:test/reporters`. --> The `node:test` module supports passing [`--test-reporter`][] diff --git a/lib/test/reporters.js b/lib/test/reporters.js index 6b1f2a52778044..109ced8d291ba2 100644 --- a/lib/test/reporters.js +++ b/lib/test/reporters.js @@ -1,11 +1,44 @@ 'use strict'; -const dot = require('internal/test_runner/reporter/dot'); -const spec = require('internal/test_runner/reporter/spec'); -const tap = require('internal/test_runner/reporter/tap'); - -module.exports = { - dot, - spec, - tap, -}; +const { ObjectDefineProperty } = primordials; + +let dot; +let spec; +let tap; + +ObjectDefineProperty(module.exports, 'dot', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (dot === undefined) { + dot = require('internal/test_runner/reporter/dot'); + } + + return dot; + }, +}); +ObjectDefineProperty(module.exports, 'spec', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (spec === undefined) { + spec = require('internal/test_runner/reporter/spec'); + } + + return spec; + }, +}); +ObjectDefineProperty(module.exports, 'tap', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + if (tap === undefined) { + tap = require('internal/test_runner/reporter/tap'); + } + + return tap; + }, +}); diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 5b57d5585796fc..b56589cd4fe547 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -2,7 +2,7 @@ import * as common from '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; import { join } from 'node:path'; import { describe, it, run } from 'node:test'; -import { dot } from 'node:test/reporters'; +import { dot, spec, tap } from 'node:test/reporters'; import assert from 'node:assert'; const testFixtures = fixtures.path('test-runner'); @@ -74,4 +74,32 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { '\n', ]); }); + + it('should be piped with spec', async () => { + const specReporter = new spec(); + const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(specReporter).toArray(); + const stringResults = result.map((bfr) => bfr.toString()); + assert.strictEqual(stringResults.length, 2); + assert.match(stringResults[0], /this should pass/); + assert.match(stringResults[1], /tests 1/); + assert.match(stringResults[1], /pass 1/); + }); + + it('should be piped with tap', async () => { + const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(tap).toArray(); + assert.strictEqual(result.length, 13); + assert.strictEqual(result[0], 'TAP version 13\n'); + assert.strictEqual(result[1], '# Subtest: this should pass\n'); + assert.strictEqual(result[2], 'ok 1 - this should pass\n'); + assert.match(result[3], /duration_ms: \d+\.?\d*/); + assert.strictEqual(result[4], '1..1\n'); + assert.strictEqual(result[5], '# tests 1\n'); + assert.strictEqual(result[6], '# suites 0\n'); + assert.strictEqual(result[7], '# pass 1\n'); + assert.strictEqual(result[8], '# fail 0\n'); + assert.strictEqual(result[9], '# cancelled 0\n'); + assert.strictEqual(result[10], '# skipped 0\n'); + assert.strictEqual(result[11], '# todo 0\n'); + assert.match(result[12], /# duration_ms \d+\.?\d*/); + }); }); From 6f8b4ae1bd4defee20f9a45ccbcf47f15b941461 Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Sat, 25 Mar 2023 23:01:57 +0300 Subject: [PATCH 5/7] test_runner: CR cleanup --- lib/test/reporters.js | 59 +++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/lib/test/reporters.js b/lib/test/reporters.js index 109ced8d291ba2..ad0dbfdb98e447 100644 --- a/lib/test/reporters.js +++ b/lib/test/reporters.js @@ -1,44 +1,37 @@ 'use strict'; -const { ObjectDefineProperty } = primordials; +const { ObjectDefineProperties } = primordials; let dot; let spec; let tap; -ObjectDefineProperty(module.exports, 'dot', { - __proto__: null, - configurable: true, - enumerable: true, - get() { - if (dot === undefined) { - dot = require('internal/test_runner/reporter/dot'); - } - - return dot; +ObjectDefineProperties(module.exports, { + dot: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + dot ??= require('internal/test_runner/reporter/dot'); + return dot; + }, }, -}); -ObjectDefineProperty(module.exports, 'spec', { - __proto__: null, - configurable: true, - enumerable: true, - get() { - if (spec === undefined) { - spec = require('internal/test_runner/reporter/spec'); - } - - return spec; + spec: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + spec ??= require('internal/test_runner/reporter/spec'); + return spec; + }, }, -}); -ObjectDefineProperty(module.exports, 'tap', { - __proto__: null, - configurable: true, - enumerable: true, - get() { - if (tap === undefined) { - tap = require('internal/test_runner/reporter/tap'); - } - - return tap; + tap: { + __proto__: null, + configurable: true, + enumerable: true, + get() { + tap ??= require('internal/test_runner/reporter/tap'); + return tap; + }, }, }); From 58a5989e76226fff89da4b1486713dff1fd8eb59 Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Sun, 26 Mar 2023 10:02:06 +0300 Subject: [PATCH 6/7] fix test --- test/parallel/test-runner-run.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index b56589cd4fe547..b37bdf94f38c02 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -79,7 +79,6 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { const specReporter = new spec(); const result = await run({ files: [join(testFixtures, 'test/random.cjs')] }).compose(specReporter).toArray(); const stringResults = result.map((bfr) => bfr.toString()); - assert.strictEqual(stringResults.length, 2); assert.match(stringResults[0], /this should pass/); assert.match(stringResults[1], /tests 1/); assert.match(stringResults[1], /pass 1/); From b123070defc703ff3ac810f7e48b106eb4580a9c Mon Sep 17 00:00:00 2001 From: atlowChemi Date: Sun, 26 Mar 2023 10:11:14 +0300 Subject: [PATCH 7/7] cr proto:null --- lib/test/reporters.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/test/reporters.js b/lib/test/reporters.js index ad0dbfdb98e447..287c07510bc13a 100644 --- a/lib/test/reporters.js +++ b/lib/test/reporters.js @@ -7,6 +7,7 @@ let spec; let tap; ObjectDefineProperties(module.exports, { + __proto__: null, dot: { __proto__: null, configurable: true,