11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst events = require('events');
61cb0ef41Sopenharmony_ciconst { REPLServer } = require('repl');
71cb0ef41Sopenharmony_ciconst { Stream } = require('stream');
81cb0ef41Sopenharmony_ciconst { inspect } = require('util');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cicommon.skipIfInspectorDisabled();
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci// Ignore terminal settings. This is so the test can be run intact if TERM=dumb.
131cb0ef41Sopenharmony_ciprocess.env.TERM = '';
141cb0ef41Sopenharmony_ciconst PROMPT = 'repl > ';
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciclass REPLStream extends Stream {
171cb0ef41Sopenharmony_ci  readable = true;
181cb0ef41Sopenharmony_ci  writable = true;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  constructor() {
211cb0ef41Sopenharmony_ci    super();
221cb0ef41Sopenharmony_ci    this.lines = [''];
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci  run(data) {
251cb0ef41Sopenharmony_ci    for (const entry of data) {
261cb0ef41Sopenharmony_ci      this.emit('data', entry);
271cb0ef41Sopenharmony_ci    }
281cb0ef41Sopenharmony_ci    this.emit('data', '\n');
291cb0ef41Sopenharmony_ci  }
301cb0ef41Sopenharmony_ci  write(chunk) {
311cb0ef41Sopenharmony_ci    const chunkLines = chunk.toString('utf8').split('\n');
321cb0ef41Sopenharmony_ci    this.lines[this.lines.length - 1] += chunkLines[0];
331cb0ef41Sopenharmony_ci    if (chunkLines.length > 1) {
341cb0ef41Sopenharmony_ci      this.lines.push(...chunkLines.slice(1));
351cb0ef41Sopenharmony_ci    }
361cb0ef41Sopenharmony_ci    this.emit('line', this.lines[this.lines.length - 1]);
371cb0ef41Sopenharmony_ci    return true;
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci  async wait() {
401cb0ef41Sopenharmony_ci    this.lines = [''];
411cb0ef41Sopenharmony_ci    for await (const [line] of events.on(this, 'line')) {
421cb0ef41Sopenharmony_ci      if (line.includes(PROMPT)) {
431cb0ef41Sopenharmony_ci        return this.lines;
441cb0ef41Sopenharmony_ci      }
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci  pause() {}
481cb0ef41Sopenharmony_ci  resume() {}
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_cifunction runAndWait(cmds, repl) {
521cb0ef41Sopenharmony_ci  const promise = repl.inputStream.wait();
531cb0ef41Sopenharmony_ci  for (const cmd of cmds) {
541cb0ef41Sopenharmony_ci    repl.inputStream.run(cmd);
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci  return promise;
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciasync function tests(options) {
601cb0ef41Sopenharmony_ci  const repl = REPLServer({
611cb0ef41Sopenharmony_ci    prompt: PROMPT,
621cb0ef41Sopenharmony_ci    stream: new REPLStream(),
631cb0ef41Sopenharmony_ci    ignoreUndefined: true,
641cb0ef41Sopenharmony_ci    useColors: true,
651cb0ef41Sopenharmony_ci    ...options
661cb0ef41Sopenharmony_ci  });
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  repl.inputStream.run([
691cb0ef41Sopenharmony_ci    'function foo(x) { return x; }',
701cb0ef41Sopenharmony_ci    'function koo() { console.log("abc"); }',
711cb0ef41Sopenharmony_ci    'a = undefined;',
721cb0ef41Sopenharmony_ci  ]);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  const testCases = [{
751cb0ef41Sopenharmony_ci    input: 'foo',
761cb0ef41Sopenharmony_ci    noPreview: '[Function: foo]',
771cb0ef41Sopenharmony_ci    preview: [
781cb0ef41Sopenharmony_ci      'foo',
791cb0ef41Sopenharmony_ci      '\x1B[90m[Function: foo]\x1B[39m\x1B[11G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
801cb0ef41Sopenharmony_ci      '\x1B[36m[Function: foo]\x1B[39m',
811cb0ef41Sopenharmony_ci    ]
821cb0ef41Sopenharmony_ci  }, {
831cb0ef41Sopenharmony_ci    input: 'koo',
841cb0ef41Sopenharmony_ci    noPreview: '[Function: koo]',
851cb0ef41Sopenharmony_ci    preview: [
861cb0ef41Sopenharmony_ci      'k\x1B[90moo\x1B[39m\x1B[9G',
871cb0ef41Sopenharmony_ci      '\x1B[90m[Function: koo]\x1B[39m\x1B[9G\x1B[1A\x1B[1B\x1B[2K\x1B[1A' +
881cb0ef41Sopenharmony_ci        '\x1B[0Ko\x1B[90mo\x1B[39m\x1B[10G',
891cb0ef41Sopenharmony_ci      '\x1B[90m[Function: koo]\x1B[39m\x1B[10G\x1B[1A\x1B[1B\x1B[2K\x1B[1A' +
901cb0ef41Sopenharmony_ci        '\x1B[0Ko',
911cb0ef41Sopenharmony_ci      '\x1B[90m[Function: koo]\x1B[39m\x1B[11G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
921cb0ef41Sopenharmony_ci      '\x1B[36m[Function: koo]\x1B[39m',
931cb0ef41Sopenharmony_ci    ]
941cb0ef41Sopenharmony_ci  }, {
951cb0ef41Sopenharmony_ci    input: 'a',
961cb0ef41Sopenharmony_ci    noPreview: 'repl > ', // No "undefined" output.
971cb0ef41Sopenharmony_ci    preview: ['a\r'] // No "undefined" preview.
981cb0ef41Sopenharmony_ci  }, {
991cb0ef41Sopenharmony_ci    input: " { b: 1 }['b'] === 1",
1001cb0ef41Sopenharmony_ci    noPreview: '\x1B[33mtrue\x1B[39m',
1011cb0ef41Sopenharmony_ci    preview: [
1021cb0ef41Sopenharmony_ci      " { b: 1 }['b']",
1031cb0ef41Sopenharmony_ci      '\x1B[90m1\x1B[39m\x1B[22G\x1B[1A\x1B[1B\x1B[2K\x1B[1A ',
1041cb0ef41Sopenharmony_ci      '\x1B[90m1\x1B[39m\x1B[23G\x1B[1A\x1B[1B\x1B[2K\x1B[1A=== 1',
1051cb0ef41Sopenharmony_ci      '\x1B[90mtrue\x1B[39m\x1B[28G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1061cb0ef41Sopenharmony_ci      '\x1B[33mtrue\x1B[39m',
1071cb0ef41Sopenharmony_ci    ]
1081cb0ef41Sopenharmony_ci  }, {
1091cb0ef41Sopenharmony_ci    input: "{ b: 1 }['b'] === 1;",
1101cb0ef41Sopenharmony_ci    noPreview: '\x1B[33mfalse\x1B[39m',
1111cb0ef41Sopenharmony_ci    preview: [
1121cb0ef41Sopenharmony_ci      "{ b: 1 }['b']",
1131cb0ef41Sopenharmony_ci      '\x1B[90m1\x1B[39m\x1B[21G\x1B[1A\x1B[1B\x1B[2K\x1B[1A ',
1141cb0ef41Sopenharmony_ci      '\x1B[90m1\x1B[39m\x1B[22G\x1B[1A\x1B[1B\x1B[2K\x1B[1A=== 1',
1151cb0ef41Sopenharmony_ci      '\x1B[90mtrue\x1B[39m\x1B[27G\x1B[1A\x1B[1B\x1B[2K\x1B[1A;',
1161cb0ef41Sopenharmony_ci      '\x1B[90mfalse\x1B[39m\x1B[28G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1171cb0ef41Sopenharmony_ci      '\x1B[33mfalse\x1B[39m',
1181cb0ef41Sopenharmony_ci    ]
1191cb0ef41Sopenharmony_ci  }, {
1201cb0ef41Sopenharmony_ci    input: '{ a: true }',
1211cb0ef41Sopenharmony_ci    noPreview: '{ a: \x1B[33mtrue\x1B[39m }',
1221cb0ef41Sopenharmony_ci    preview: [
1231cb0ef41Sopenharmony_ci      '{ a: tru\x1B[90me\x1B[39m\x1B[16G\x1B[0Ke }\r',
1241cb0ef41Sopenharmony_ci      '{ a: \x1B[33mtrue\x1B[39m }',
1251cb0ef41Sopenharmony_ci    ]
1261cb0ef41Sopenharmony_ci  }, {
1271cb0ef41Sopenharmony_ci    input: '{ a: true };',
1281cb0ef41Sopenharmony_ci    noPreview: '\x1B[33mtrue\x1B[39m',
1291cb0ef41Sopenharmony_ci    preview: [
1301cb0ef41Sopenharmony_ci      '{ a: tru\x1B[90me\x1B[39m\x1B[16G\x1B[0Ke };',
1311cb0ef41Sopenharmony_ci      '\x1B[90mtrue\x1B[39m\x1B[20G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1321cb0ef41Sopenharmony_ci      '\x1B[33mtrue\x1B[39m',
1331cb0ef41Sopenharmony_ci    ]
1341cb0ef41Sopenharmony_ci  }, {
1351cb0ef41Sopenharmony_ci    input: ' \t { a: true};',
1361cb0ef41Sopenharmony_ci    noPreview: '\x1B[33mtrue\x1B[39m',
1371cb0ef41Sopenharmony_ci    preview: [
1381cb0ef41Sopenharmony_ci      '  { a: tru\x1B[90me\x1B[39m\x1B[18G\x1B[0Ke}',
1391cb0ef41Sopenharmony_ci      '\x1B[90m{ a: true }\x1B[39m\x1B[20G\x1B[1A\x1B[1B\x1B[2K\x1B[1A;',
1401cb0ef41Sopenharmony_ci      '\x1B[90mtrue\x1B[39m\x1B[21G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1411cb0ef41Sopenharmony_ci      '\x1B[33mtrue\x1B[39m',
1421cb0ef41Sopenharmony_ci    ]
1431cb0ef41Sopenharmony_ci  }, {
1441cb0ef41Sopenharmony_ci    input: '1n + 2n',
1451cb0ef41Sopenharmony_ci    noPreview: '\x1B[33m3n\x1B[39m',
1461cb0ef41Sopenharmony_ci    preview: [
1471cb0ef41Sopenharmony_ci      '1n + 2',
1481cb0ef41Sopenharmony_ci      '\x1B[90mType[39m\x1B[14G\x1B[1A\x1B[1B\x1B[2K\x1B[1An',
1491cb0ef41Sopenharmony_ci      '\x1B[90m3n\x1B[39m\x1B[15G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1501cb0ef41Sopenharmony_ci      '\x1B[33m3n\x1B[39m',
1511cb0ef41Sopenharmony_ci    ]
1521cb0ef41Sopenharmony_ci  }, {
1531cb0ef41Sopenharmony_ci    input: '{};1',
1541cb0ef41Sopenharmony_ci    noPreview: '\x1B[33m1\x1B[39m',
1551cb0ef41Sopenharmony_ci    preview: [
1561cb0ef41Sopenharmony_ci      '{};1',
1571cb0ef41Sopenharmony_ci      '\x1B[90m1\x1B[39m\x1B[12G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r',
1581cb0ef41Sopenharmony_ci      '\x1B[33m1\x1B[39m',
1591cb0ef41Sopenharmony_ci    ]
1601cb0ef41Sopenharmony_ci  }];
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  const hasPreview = repl.terminal &&
1631cb0ef41Sopenharmony_ci    (options.preview !== undefined ? !!options.preview : true);
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  for (const { input, noPreview, preview } of testCases) {
1661cb0ef41Sopenharmony_ci    console.log(`Testing ${input}`);
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci    const toBeRun = input.split('\n');
1691cb0ef41Sopenharmony_ci    let lines = await runAndWait(toBeRun, repl);
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci    if (hasPreview) {
1721cb0ef41Sopenharmony_ci      // Remove error messages. That allows the code to run in different
1731cb0ef41Sopenharmony_ci      // engines.
1741cb0ef41Sopenharmony_ci      // eslint-disable-next-line no-control-regex
1751cb0ef41Sopenharmony_ci      lines = lines.map((line) => line.replace(/Error: .+?\x1B/, ''));
1761cb0ef41Sopenharmony_ci      assert.strictEqual(lines.pop(), '\x1B[1G\x1B[0Jrepl > \x1B[8G');
1771cb0ef41Sopenharmony_ci      assert.deepStrictEqual(lines, preview);
1781cb0ef41Sopenharmony_ci    } else {
1791cb0ef41Sopenharmony_ci      assert.ok(lines[0].includes(noPreview), lines.map(inspect));
1801cb0ef41Sopenharmony_ci      if (preview.length !== 1 || preview[0] !== `${input}\r`)
1811cb0ef41Sopenharmony_ci        assert.strictEqual(lines.length, 2);
1821cb0ef41Sopenharmony_ci    }
1831cb0ef41Sopenharmony_ci  }
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_citests({ terminal: false }); // No preview
1871cb0ef41Sopenharmony_citests({ terminal: true }); // Preview
1881cb0ef41Sopenharmony_citests({ terminal: false, preview: false }); // No preview
1891cb0ef41Sopenharmony_citests({ terminal: false, preview: true }); // No preview
1901cb0ef41Sopenharmony_citests({ terminal: true, preview: true }); // Preview
191