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