|
1 | | -// https://github.com/nodejs/node/blob/e2225ba8e1c00995c0f8bd56e607ea7c5b463ab9/lib/internal/main/test_runner.js |
| 1 | +// https://github.com/nodejs/node/blob/389b7e138e89a339fabe4ad628bf09cd9748f957/lib/internal/main/test_runner.js |
2 | 2 | 'use strict' |
3 | 3 | const { |
4 | 4 | ArrayFrom, |
5 | 5 | ArrayPrototypeFilter, |
6 | 6 | ArrayPrototypeIncludes, |
| 7 | + ArrayPrototypeJoin, |
7 | 8 | ArrayPrototypePush, |
8 | 9 | ArrayPrototypeSlice, |
9 | 10 | ArrayPrototypeSort, |
10 | | - Promise, |
11 | | - PromiseAll, |
12 | | - SafeArrayIterator, |
| 11 | + SafePromiseAll, |
13 | 12 | SafeSet |
14 | 13 | } = require('#internal/per_context/primordials') |
15 | 14 | const { |
16 | 15 | prepareMainThreadExecution |
17 | 16 | } = require('#internal/bootstrap/pre_execution') |
18 | 17 | const { spawn } = require('child_process') |
19 | 18 | const { readdirSync, statSync } = require('fs') |
20 | | -const { finished } = require('#internal/streams/end-of-stream') |
21 | | -const console = require('#internal/console/global') |
22 | 19 | const { |
23 | 20 | codes: { |
24 | 21 | ERR_TEST_FAILURE |
25 | 22 | } |
26 | 23 | } = require('#internal/errors') |
| 24 | +const { toArray } = require('#internal/streams/operators').promiseReturningOperators |
27 | 25 | const { test } = require('#internal/test_runner/harness') |
28 | 26 | const { kSubtestsFailed } = require('#internal/test_runner/test') |
29 | 27 | const { |
30 | 28 | isSupportedFileType, |
31 | 29 | doesPathMatchFilter |
32 | 30 | } = require('#internal/test_runner/utils') |
33 | 31 | const { basename, join, resolve } = require('path') |
| 32 | +const { once } = require('events') |
34 | 33 | const kFilterArgs = ['--test'] |
35 | 34 |
|
36 | 35 | prepareMainThreadExecution(false) |
@@ -104,53 +103,39 @@ function filterExecArgv (arg) { |
104 | 103 | } |
105 | 104 |
|
106 | 105 | function runTestFile (path) { |
107 | | - return test(path, () => { |
108 | | - return new Promise((resolve, reject) => { |
109 | | - const args = ArrayPrototypeFilter(process.execArgv, filterExecArgv) |
110 | | - ArrayPrototypePush(args, path) |
111 | | - |
112 | | - const child = spawn(process.execPath, args) |
113 | | - // TODO(cjihrig): Implement a TAP parser to read the child's stdout |
114 | | - // instead of just displaying it all if the child fails. |
115 | | - let stdout = '' |
116 | | - let stderr = '' |
117 | | - let err |
118 | | - |
119 | | - child.on('error', (error) => { |
120 | | - err = error |
121 | | - }) |
122 | | - |
123 | | - child.stdout.setEncoding('utf8') |
124 | | - child.stderr.setEncoding('utf8') |
125 | | - |
126 | | - child.stdout.on('data', (chunk) => { |
127 | | - stdout += chunk |
128 | | - }) |
129 | | - |
130 | | - child.stderr.on('data', (chunk) => { |
131 | | - stderr += chunk |
132 | | - }) |
133 | | - |
134 | | - child.once('exit', async (code, signal) => { |
135 | | - if (code !== 0 || signal !== null) { |
136 | | - if (!err) { |
137 | | - await PromiseAll(new SafeArrayIterator([finished(child.stderr), finished(child.stdout)])) |
138 | | - err = new ERR_TEST_FAILURE('test failed', kSubtestsFailed) |
139 | | - err.exitCode = code |
140 | | - err.signal = signal |
141 | | - err.stdout = stdout |
142 | | - err.stderr = stderr |
143 | | - // The stack will not be useful since the failures came from tests |
144 | | - // in a child process. |
145 | | - err.stack = undefined |
146 | | - } |
147 | | - |
148 | | - return reject(err) |
149 | | - } |
150 | | - |
151 | | - resolve() |
152 | | - }) |
| 106 | + return test(path, async (t) => { |
| 107 | + const args = ArrayPrototypeFilter(process.execArgv, filterExecArgv) |
| 108 | + ArrayPrototypePush(args, path) |
| 109 | + |
| 110 | + const child = spawn(process.execPath, args, { signal: t.signal, encoding: 'utf8' }) |
| 111 | + // TODO(cjihrig): Implement a TAP parser to read the child's stdout |
| 112 | + // instead of just displaying it all if the child fails. |
| 113 | + let err |
| 114 | + |
| 115 | + child.on('error', (error) => { |
| 116 | + err = error |
153 | 117 | }) |
| 118 | + |
| 119 | + const { 0: { 0: code, 1: signal }, 1: stdout, 2: stderr } = await SafePromiseAll([ |
| 120 | + once(child, 'exit', { signal: t.signal }), |
| 121 | + toArray.call(child.stdout, { signal: t.signal }), |
| 122 | + toArray.call(child.stderr, { signal: t.signal }) |
| 123 | + ]) |
| 124 | + |
| 125 | + if (code !== 0 || signal !== null) { |
| 126 | + if (!err) { |
| 127 | + err = new ERR_TEST_FAILURE('test failed', kSubtestsFailed) |
| 128 | + err.exitCode = code |
| 129 | + err.signal = signal |
| 130 | + err.stdout = ArrayPrototypeJoin(stdout, '') |
| 131 | + err.stderr = ArrayPrototypeJoin(stderr, '') |
| 132 | + // The stack will not be useful since the failures came from tests |
| 133 | + // in a child process. |
| 134 | + err.stack = undefined |
| 135 | + } |
| 136 | + |
| 137 | + throw err |
| 138 | + } |
154 | 139 | }) |
155 | 140 | } |
156 | 141 |
|
|
0 commit comments