• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const { spawn } = require('child_process');
5
6const replProcess = spawn(process.argv0, ['--interactive'], {
7  stdio: ['pipe', 'pipe', 'inherit'],
8  windowsHide: true,
9});
10
11replProcess.on('error', common.mustNotCall());
12
13const replReadyState = (async function* () {
14  let ready;
15  const SPACE = ' '.charCodeAt();
16  const BRACKET = '>'.charCodeAt();
17  const DOT = '.'.charCodeAt();
18  replProcess.stdout.on('data', (data) => {
19    ready = data[data.length - 1] === SPACE && (
20      data[data.length - 2] === BRACKET || (
21        data[data.length - 2] === DOT &&
22        data[data.length - 3] === DOT &&
23        data[data.length - 4] === DOT
24      ));
25  });
26
27  const processCrashed = new Promise((resolve, reject) =>
28    replProcess.on('exit', reject)
29  );
30  while (true) {
31    await Promise.race([new Promise(setImmediate), processCrashed]);
32    if (ready) {
33      ready = false;
34      yield;
35    }
36  }
37})();
38async function writeLn(data, expectedOutput) {
39  await replReadyState.next();
40  if (expectedOutput) {
41    replProcess.stdout.once('data', common.mustCall((data) =>
42      assert.match(data.toString('utf8'), expectedOutput)
43    ));
44  }
45  await new Promise((resolve, reject) => replProcess.stdin.write(
46    `${data}\n`,
47    (err) => (err ? reject(err) : resolve())
48  ));
49}
50
51async function main() {
52  await writeLn(
53    'const ArrayIteratorPrototype =' +
54      '  Object.getPrototypeOf(Array.prototype[Symbol.iterator]());'
55  );
56  await writeLn('delete Array.prototype[Symbol.iterator];');
57  await writeLn('delete ArrayIteratorPrototype.next;');
58
59  await writeLn(
60    'for(const x of [3, 2, 1]);',
61    /Uncaught TypeError: \[3,2,1\] is not iterable/
62  );
63  await writeLn('.exit');
64
65  assert(!replProcess.connected);
66}
67
68main().then(common.mustCall());
69