|
1 | 1 | 'use strict'; |
2 | | -// Regression test for the REPL crashing when an incomplete `import` statement |
3 | | -// is entered. Typing `import` alone used to trigger V8's "Cannot use import |
4 | | -// statement outside a module" SyntaxError, which the REPL tried to enrich with |
5 | | -// a dynamic-import suggestion. Building that suggestion called acorn to parse |
6 | | -// the line; acorn threw on the incomplete input, and the exception escaped to |
7 | | -// terminate the process. |
8 | | -// Refs: https://github.com/nodejs/node/issues/63551 |
| 2 | +// Regression test for https://github.com/nodejs/node/issues/63551: |
| 3 | +// Typing a bare `import` keyword in the REPL used to terminate the process. |
| 4 | +// |
| 5 | +// V8 throws SyntaxError("Cannot use import statement outside a module"), |
| 6 | +// which the REPL enriched with a dynamic-import suggestion via |
| 7 | +// `toDynamicImport`. That helper called acorn without a try/catch; on |
| 8 | +// incomplete input acorn threw, and the exception escaped the REPL's input |
| 9 | +// pipeline to crash the process. |
| 10 | +// |
| 11 | +// The fix wraps the acorn call in try/catch and falls back to a plain |
| 12 | +// error message when the line cannot be parsed as a complete import |
| 13 | +// statement. This test asserts that: |
| 14 | +// 1. Emitting an incomplete `import` line through the REPL does not |
| 15 | +// throw out of the line-handler, and |
| 16 | +// 2. The REPL still surfaces a SyntaxError to the user. |
9 | 17 |
|
10 | 18 | require('../common'); |
11 | 19 | const assert = require('assert'); |
12 | | -const child_process = require('child_process'); |
| 20 | +const { startNewREPLServer } = require('../common/repl'); |
13 | 21 |
|
14 | | -const child = child_process.spawn(process.execPath, ['--interactive'], { |
15 | | - stdio: 'pipe', |
16 | | -}); |
| 22 | +const { replServer, output } = startNewREPLServer(); |
17 | 23 |
|
18 | | -let stdout = ''; |
19 | | -child.stdout.setEncoding('utf8'); |
20 | | -child.stdout.on('data', (chunk) => { stdout += chunk; }); |
| 24 | +replServer.emit('line', 'import'); |
| 25 | +replServer.emit('line', '.exit'); |
21 | 26 |
|
22 | | -child.stdin.write('import\n'); |
23 | | -child.stdin.write('.exit\n'); |
24 | | - |
25 | | -child.on('exit', (code, signal) => { |
26 | | - assert.strictEqual(signal, null); |
27 | | - assert.strictEqual(code, 0, |
28 | | - `REPL exited with code ${code} (expected 0). ` + |
29 | | - `stdout was:\n${stdout}`); |
30 | | - // The REPL should still have printed a SyntaxError message describing the |
31 | | - // issue with the input, rather than crashing silently. |
32 | | - assert.match(stdout, /SyntaxError/); |
33 | | -}); |
| 27 | +assert.match(output.accumulator, /SyntaxError/); |
| 28 | +assert.match( |
| 29 | + output.accumulator, |
| 30 | + /Cannot use import statement inside the Node\.js REPL\b/, |
| 31 | +); |
0 commit comments