11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_cirequire('../common'); 41cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 51cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 61cb0ef41Sopenharmony_ciconst { describe, it } = require('node:test'); 71cb0ef41Sopenharmony_ciconst { spawnSync } = require('node:child_process'); 81cb0ef41Sopenharmony_ciconst assert = require('node:assert'); 91cb0ef41Sopenharmony_ciconst path = require('node:path'); 101cb0ef41Sopenharmony_ciconst fs = require('node:fs'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst testFile = fixtures.path('test-runner/reporters.js'); 131cb0ef41Sopenharmony_citmpdir.refresh(); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cilet tmpFiles = 0; 161cb0ef41Sopenharmony_cidescribe('node:test reporters', { concurrency: true }, () => { 171cb0ef41Sopenharmony_ci it('should default to outputing TAP to stdout', async () => { 181cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, ['--test', testFile]); 191cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 201cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /TAP version 13/); 211cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /ok 1 - ok/); 221cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /not ok 2 - failing/); 231cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /ok 2 - top level/); 241cb0ef41Sopenharmony_ci }); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci it('should default destination to stdout when passing a single reporter', async () => { 271cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', testFile]); 281cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 291cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), '.XX.\n'); 301cb0ef41Sopenharmony_ci }); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci it('should throw when passing reporters without a destination', async () => { 331cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', '--test-reporter', 'tap', testFile]); 341cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /The argument '--test-reporter' must match the number of specified '--test-reporter-destination'\. Received \[ 'dot', 'tap' \]/); 351cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 361cb0ef41Sopenharmony_ci }); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci it('should throw when passing a destination without a reporter', async () => { 391cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, ['--test', '--test-reporter-destination', 'tap', testFile]); 401cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /The argument '--test-reporter' must match the number of specified '--test-reporter-destination'\. Received \[\]/); 411cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 421cb0ef41Sopenharmony_ci }); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci it('should support stdout as a destination', async () => { 451cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 461cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stdout', testFile]); 471cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 481cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), '.XX.\n'); 491cb0ef41Sopenharmony_ci }); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci it('should support stderr as a destination', async () => { 521cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 531cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stderr', testFile]); 541cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), '.XX.\n'); 551cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 561cb0ef41Sopenharmony_ci }); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci it('should support a file as a destination', async () => { 591cb0ef41Sopenharmony_ci const file = path.join(tmpdir.path, `${tmpFiles++}.out`); 601cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 611cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 'dot', '--test-reporter-destination', file, testFile]); 621cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 631cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 641cb0ef41Sopenharmony_ci assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n'); 651cb0ef41Sopenharmony_ci }); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci it('should disallow using v8-serializer as reporter', async () => { 681cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'v8-serializer', testFile]); 691cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 701cb0ef41Sopenharmony_ci assert(child.status > 0); 711cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /ERR_MODULE_NOT_FOUND/); 721cb0ef41Sopenharmony_ci }); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci it('should support multiple reporters', async () => { 751cb0ef41Sopenharmony_ci const file = path.join(tmpdir.path, `${tmpFiles++}.out`); 761cb0ef41Sopenharmony_ci const file2 = path.join(tmpdir.path, `${tmpFiles++}.out`); 771cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 781cb0ef41Sopenharmony_ci ['--test', 791cb0ef41Sopenharmony_ci '--test-reporter', 'dot', '--test-reporter-destination', file, 801cb0ef41Sopenharmony_ci '--test-reporter', 'spec', '--test-reporter-destination', file2, 811cb0ef41Sopenharmony_ci '--test-reporter', 'tap', '--test-reporter-destination', 'stdout', 821cb0ef41Sopenharmony_ci testFile]); 831cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /TAP version 13/); 841cb0ef41Sopenharmony_ci assert.match(child.stdout.toString(), /# duration_ms/); 851cb0ef41Sopenharmony_ci assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n'); 861cb0ef41Sopenharmony_ci const file2Contents = fs.readFileSync(file2, 'utf8'); 871cb0ef41Sopenharmony_ci assert.match(file2Contents, /▶ nested/); 881cb0ef41Sopenharmony_ci assert.match(file2Contents, /✔ ok/); 891cb0ef41Sopenharmony_ci assert.match(file2Contents, /✖ failing/); 901cb0ef41Sopenharmony_ci }); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci ['js', 'cjs', 'mjs'].forEach((ext) => { 931cb0ef41Sopenharmony_ci it(`should support a '${ext}' file as a custom reporter`, async () => { 941cb0ef41Sopenharmony_ci const filename = `custom.${ext}`; 951cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 961cb0ef41Sopenharmony_ci ['--test', '--test-reporter', fixtures.fileURL('test-runner/custom_reporters/', filename), 971cb0ef41Sopenharmony_ci testFile]); 981cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 991cb0ef41Sopenharmony_ci const stdout = child.stdout.toString(); 1001cb0ef41Sopenharmony_ci assert.match(stdout, /{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/); 1011cb0ef41Sopenharmony_ci assert.strictEqual(stdout.slice(0, filename.length + 2), `${filename} {`); 1021cb0ef41Sopenharmony_ci }); 1031cb0ef41Sopenharmony_ci }); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci it('should support a custom reporter from node_modules', async () => { 1061cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 1071cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 'reporter-cjs', 'reporters.js'], 1081cb0ef41Sopenharmony_ci { cwd: fixtures.path('test-runner') }); 1091cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 1101cb0ef41Sopenharmony_ci assert.match( 1111cb0ef41Sopenharmony_ci child.stdout.toString(), 1121cb0ef41Sopenharmony_ci /^package: reporter-cjs{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/, 1131cb0ef41Sopenharmony_ci ); 1141cb0ef41Sopenharmony_ci }); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci it('should support a custom ESM reporter from node_modules', async () => { 1171cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 1181cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 'reporter-esm', 'reporters.js'], 1191cb0ef41Sopenharmony_ci { cwd: fixtures.path('test-runner') }); 1201cb0ef41Sopenharmony_ci assert.strictEqual(child.stderr.toString(), ''); 1211cb0ef41Sopenharmony_ci assert.match( 1221cb0ef41Sopenharmony_ci child.stdout.toString(), 1231cb0ef41Sopenharmony_ci /^package: reporter-esm{"test:enqueue":5,"test:dequeue":5,"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/, 1241cb0ef41Sopenharmony_ci ); 1251cb0ef41Sopenharmony_ci }); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci it('should throw when reporter setup throws asynchronously', async () => { 1281cb0ef41Sopenharmony_ci const child = spawnSync( 1291cb0ef41Sopenharmony_ci process.execPath, 1301cb0ef41Sopenharmony_ci ['--test', '--test-reporter', fixtures.fileURL('empty.js'), 'reporters.js'], 1311cb0ef41Sopenharmony_ci { cwd: fixtures.path('test-runner') } 1321cb0ef41Sopenharmony_ci ); 1331cb0ef41Sopenharmony_ci assert.strictEqual(child.status, 7); 1341cb0ef41Sopenharmony_ci assert.strictEqual(child.signal, null); 1351cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), ''); 1361cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /ERR_INVALID_ARG_TYPE/); 1371cb0ef41Sopenharmony_ci }); 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci it('should throw when reporter errors', async () => { 1401cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 1411cb0ef41Sopenharmony_ci ['--test', '--test-reporter', fixtures.fileURL('test-runner/custom_reporters/throwing.js'), 1421cb0ef41Sopenharmony_ci fixtures.path('test-runner/default-behavior/index.test.js')]); 1431cb0ef41Sopenharmony_ci assert.strictEqual(child.status, 7); 1441cb0ef41Sopenharmony_ci assert.strictEqual(child.signal, null); 1451cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), 'Going to throw an error\n'); 1461cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /Error: Reporting error\r?\n\s+at customReporter/); 1471cb0ef41Sopenharmony_ci }); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci it('should throw when reporter errors asynchronously', async () => { 1501cb0ef41Sopenharmony_ci const child = spawnSync(process.execPath, 1511cb0ef41Sopenharmony_ci ['--test', '--test-reporter', 1521cb0ef41Sopenharmony_ci fixtures.fileURL('test-runner/custom_reporters/throwing-async.js'), 1531cb0ef41Sopenharmony_ci fixtures.path('test-runner/default-behavior/index.test.js')]); 1541cb0ef41Sopenharmony_ci assert.strictEqual(child.status, 7); 1551cb0ef41Sopenharmony_ci assert.strictEqual(child.signal, null); 1561cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), 'Going to throw an error\n'); 1571cb0ef41Sopenharmony_ci assert.match(child.stderr.toString(), /Emitted 'error' event on Duplex instance/); 1581cb0ef41Sopenharmony_ci }); 1591cb0ef41Sopenharmony_ci}); 160