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