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 'Object.defineProperty(Array.prototype, "-1", ' + 54 '{ get() { return this[this.length - 1]; } });' 55 ); 56 57 await writeLn( 58 '[3, 2, 1][-1];', 59 /^1\n(>\s)?$/ 60 ); 61 await writeLn('.exit'); 62 63 assert(!replProcess.connected); 64} 65 66main().then(common.mustCall()); 67