1'use strict';
2const common = require('../common');
3const fixtures = require('../common/fixtures');
4const assert = require('assert');
5const { spawnSync, spawn } = require('child_process');
6const { once } = require('events');
7const { finished } = require('stream/promises');
8
9async function runAndKill(file) {
10  if (common.isWindows) {
11    common.printSkipMessage(`signals are not supported in windows, skipping ${file}`);
12    return;
13  }
14  let stdout = '';
15  const child = spawn(process.execPath, ['--test', file]);
16  child.stdout.setEncoding('utf8');
17  child.stdout.on('data', (chunk) => {
18    if (!stdout.length) child.kill('SIGINT');
19    stdout += chunk;
20  });
21  const [code, signal] = await once(child, 'exit');
22  await finished(child.stdout);
23  assert(stdout.startsWith('TAP version 13\n'));
24  assert.strictEqual(signal, null);
25  assert.strictEqual(code, 1);
26}
27
28if (process.argv[2] === 'child') {
29  const test = require('node:test');
30
31  if (process.argv[3] === 'pass') {
32    test('passing test', () => {
33      assert.strictEqual(true, true);
34    });
35  } else if (process.argv[3] === 'fail') {
36    assert.strictEqual(process.argv[3], 'fail');
37    test('failing test', () => {
38      assert.strictEqual(true, false);
39    });
40  } else assert.fail('unreachable');
41} else {
42  let child = spawnSync(process.execPath, [__filename, 'child', 'pass']);
43  assert.strictEqual(child.status, 0);
44  assert.strictEqual(child.signal, null);
45
46  child = spawnSync(process.execPath, [
47    '--test',
48    fixtures.path('test-runner', 'default-behavior', 'subdir', 'subdir_test.js'),
49  ]);
50  assert.strictEqual(child.status, 0);
51  assert.strictEqual(child.signal, null);
52
53
54  child = spawnSync(process.execPath, [
55    '--test',
56    fixtures.path('test-runner', 'todo_exit_code.js'),
57  ]);
58  assert.strictEqual(child.status, 0);
59  assert.strictEqual(child.signal, null);
60  const stdout = child.stdout.toString();
61  assert.match(stdout, /# tests 3/);
62  assert.match(stdout, /# pass 0/);
63  assert.match(stdout, /# fail 0/);
64  assert.match(stdout, /# todo 3/);
65
66  child = spawnSync(process.execPath, [__filename, 'child', 'fail']);
67  assert.strictEqual(child.status, 1);
68  assert.strictEqual(child.signal, null);
69
70  runAndKill(fixtures.path('test-runner', 'never_ending_sync.js')).then(common.mustCall());
71  runAndKill(fixtures.path('test-runner', 'never_ending_async.js')).then(common.mustCall());
72}
73