mirror of
https://github.com/nodejs/node.git
synced 2025-05-07 08:00:26 +00:00

Make changes so that tests will pass when the comma-dangle settings applied to the rest of the code base are also applied to tests. PR-URL: https://github.com/nodejs/node/pull/37930 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Derek Lewis <DerekNonGeneric@inf.is>
194 lines
5.4 KiB
JavaScript
194 lines
5.4 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const ArrayStream = require('../common/arraystream');
|
|
const assert = require('assert');
|
|
const { stripVTControlCharacters } = require('internal/util/inspect');
|
|
const repl = require('repl');
|
|
|
|
common.skipIfInspectorDisabled();
|
|
|
|
// Flags: --expose-internals --experimental-repl-await
|
|
|
|
const PROMPT = 'await repl > ';
|
|
|
|
class REPLStream extends ArrayStream {
|
|
constructor() {
|
|
super();
|
|
this.waitingForResponse = false;
|
|
this.lines = [''];
|
|
}
|
|
write(chunk, encoding, callback) {
|
|
if (Buffer.isBuffer(chunk)) {
|
|
chunk = chunk.toString(encoding);
|
|
}
|
|
const chunkLines = stripVTControlCharacters(chunk).split('\n');
|
|
this.lines[this.lines.length - 1] += chunkLines[0];
|
|
if (chunkLines.length > 1) {
|
|
this.lines.push(...chunkLines.slice(1));
|
|
}
|
|
this.emit('line');
|
|
if (callback) callback();
|
|
return true;
|
|
}
|
|
|
|
wait() {
|
|
if (this.waitingForResponse) {
|
|
throw new Error('Currently waiting for response to another command');
|
|
}
|
|
this.lines = [''];
|
|
return new Promise((resolve, reject) => {
|
|
const onError = (err) => {
|
|
this.removeListener('line', onLine);
|
|
reject(err);
|
|
};
|
|
const onLine = () => {
|
|
if (this.lines[this.lines.length - 1].includes(PROMPT)) {
|
|
this.removeListener('error', onError);
|
|
this.removeListener('line', onLine);
|
|
resolve(this.lines);
|
|
}
|
|
};
|
|
this.once('error', onError);
|
|
this.on('line', onLine);
|
|
});
|
|
}
|
|
}
|
|
|
|
const putIn = new REPLStream();
|
|
const testMe = repl.start({
|
|
prompt: PROMPT,
|
|
stream: putIn,
|
|
terminal: true,
|
|
useColors: true,
|
|
breakEvalOnSigint: true
|
|
});
|
|
|
|
function runAndWait(cmds) {
|
|
const promise = putIn.wait();
|
|
for (const cmd of cmds) {
|
|
if (typeof cmd === 'string') {
|
|
putIn.run([cmd]);
|
|
} else {
|
|
testMe.write('', cmd);
|
|
}
|
|
}
|
|
return promise;
|
|
}
|
|
|
|
async function ordinaryTests() {
|
|
// These tests were created based on
|
|
// https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-top-level-await.js?rcl=5d0ea979f0ba87655b7ef0e03b58fa3c04986ba6
|
|
putIn.run([
|
|
'function foo(x) { return x; }',
|
|
'function koo() { return Promise.resolve(4); }',
|
|
]);
|
|
const testCases = [
|
|
['await Promise.resolve(0)', '0'],
|
|
['{ a: await Promise.resolve(1) }', '{ a: 1 }'],
|
|
['_', '{ a: 1 }'],
|
|
['let { aa, bb } = await Promise.resolve({ aa: 1, bb: 2 }), f = 5;'],
|
|
['aa', '1'],
|
|
['bb', '2'],
|
|
['f', '5'],
|
|
['let cc = await Promise.resolve(2)'],
|
|
['cc', '2'],
|
|
['let dd;'],
|
|
['dd'],
|
|
['let [ii, { abc: { kk } }] = [0, { abc: { kk: 1 } }];'],
|
|
['ii', '0'],
|
|
['kk', '1'],
|
|
['var ll = await Promise.resolve(2);'],
|
|
['ll', '2'],
|
|
['foo(await koo())', '4'],
|
|
['_', '4'],
|
|
['const m = foo(await koo());'],
|
|
['m', '4'],
|
|
['const n = foo(await\nkoo());',
|
|
['const n = foo(await\r', '... koo());\r', 'undefined']],
|
|
['n', '4'],
|
|
// eslint-disable-next-line no-template-curly-in-string
|
|
['`status: ${(await Promise.resolve({ status: 200 })).status}`',
|
|
"'status: 200'"],
|
|
['for (let i = 0; i < 2; ++i) await i'],
|
|
['for (let i = 0; i < 2; ++i) { await i }'],
|
|
['await 0', '0'],
|
|
['await 0; function foo() {}'],
|
|
['foo', '[Function: foo]'],
|
|
['class Foo {}; await 1;', '1'],
|
|
['Foo', '[class Foo]'],
|
|
['if (await true) { function bar() {}; }'],
|
|
['bar', '[Function: bar]'],
|
|
['if (await true) { class Bar {}; }'],
|
|
['Bar', 'Uncaught ReferenceError: Bar is not defined'],
|
|
['await 0; function* gen(){}'],
|
|
['for (var i = 0; i < 10; ++i) { await i; }'],
|
|
['i', '10'],
|
|
['for (let j = 0; j < 5; ++j) { await j; }'],
|
|
['j', 'Uncaught ReferenceError: j is not defined', { line: 0 }],
|
|
['gen', '[GeneratorFunction: gen]'],
|
|
['return 42; await 5;', 'Uncaught SyntaxError: Illegal return statement',
|
|
{ line: 3 }],
|
|
['let o = await 1, p'],
|
|
['p'],
|
|
['let q = 1, s = await 2'],
|
|
['s', '2'],
|
|
['for await (let i of [1,2,3]) console.log(i)',
|
|
[
|
|
'for await (let i of [1,2,3]) console.log(i)\r',
|
|
'1',
|
|
'2',
|
|
'3',
|
|
'undefined',
|
|
],
|
|
],
|
|
];
|
|
|
|
for (const [input, expected = [`${input}\r`], options = {}] of testCases) {
|
|
console.log(`Testing ${input}`);
|
|
const toBeRun = input.split('\n');
|
|
const lines = await runAndWait(toBeRun);
|
|
if (Array.isArray(expected)) {
|
|
if (expected.length === 1)
|
|
expected.push('undefined');
|
|
if (lines[0] === input)
|
|
lines.shift();
|
|
assert.deepStrictEqual(lines, [...expected, PROMPT]);
|
|
} else if ('line' in options) {
|
|
assert.strictEqual(lines[toBeRun.length + options.line], expected);
|
|
} else {
|
|
const echoed = toBeRun.map((a, i) => `${i > 0 ? '... ' : ''}${a}\r`);
|
|
assert.deepStrictEqual(lines, [...echoed, expected, PROMPT]);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function ctrlCTest() {
|
|
putIn.run([
|
|
`const timeout = (msecs) => new Promise((resolve) => {
|
|
setTimeout(resolve, msecs).unref();
|
|
});`,
|
|
]);
|
|
|
|
console.log('Testing Ctrl+C');
|
|
assert.deepStrictEqual(await runAndWait([
|
|
'await timeout(100000)',
|
|
{ ctrl: true, name: 'c' },
|
|
]), [
|
|
'await timeout(100000)\r',
|
|
'Uncaught:',
|
|
'[Error [ERR_SCRIPT_EXECUTION_INTERRUPTED]: ' +
|
|
'Script execution was interrupted by `SIGINT`] {',
|
|
" code: 'ERR_SCRIPT_EXECUTION_INTERRUPTED'",
|
|
'}',
|
|
PROMPT,
|
|
]);
|
|
}
|
|
|
|
async function main() {
|
|
await ordinaryTests();
|
|
await ctrlCTest();
|
|
}
|
|
|
|
main();
|