11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --expose-internals
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciconst readline = require('readline');
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ciconst EventEmitter = require('events').EventEmitter;
91cb0ef41Sopenharmony_ciconst { getStringWidth } = require('internal/util/inspect');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cicommon.skipIfDumbTerminal();
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci// This test verifies that the tab completion supports unicode and the writes
141cb0ef41Sopenharmony_ci// are limited to the minimum.
151cb0ef41Sopenharmony_ci[
161cb0ef41Sopenharmony_ci  'あ',
171cb0ef41Sopenharmony_ci  '�',
181cb0ef41Sopenharmony_ci  '�',
191cb0ef41Sopenharmony_ci].forEach((char) => {
201cb0ef41Sopenharmony_ci  [true, false].forEach((lineBreak) => {
211cb0ef41Sopenharmony_ci    const completer = (line) => [
221cb0ef41Sopenharmony_ci      [
231cb0ef41Sopenharmony_ci        'First group',
241cb0ef41Sopenharmony_ci        '',
251cb0ef41Sopenharmony_ci        `${char}${'a'.repeat(10)}`, `${char}${'b'.repeat(10)}`, char.repeat(11),
261cb0ef41Sopenharmony_ci      ],
271cb0ef41Sopenharmony_ci      line,
281cb0ef41Sopenharmony_ci    ];
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci    let output = '';
311cb0ef41Sopenharmony_ci    const width = getStringWidth(char) - 1;
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    class FakeInput extends EventEmitter {
341cb0ef41Sopenharmony_ci      columns = ((width + 1) * 10 + (lineBreak ? 0 : 10)) * 3;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci      write = common.mustCall((data) => {
371cb0ef41Sopenharmony_ci        output += data;
381cb0ef41Sopenharmony_ci      }, 6);
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci      resume() {}
411cb0ef41Sopenharmony_ci      pause() {}
421cb0ef41Sopenharmony_ci      end() {}
431cb0ef41Sopenharmony_ci    }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci    const fi = new FakeInput();
461cb0ef41Sopenharmony_ci    const rli = new readline.Interface({
471cb0ef41Sopenharmony_ci      input: fi,
481cb0ef41Sopenharmony_ci      output: fi,
491cb0ef41Sopenharmony_ci      terminal: true,
501cb0ef41Sopenharmony_ci      completer: common.mustCallAtLeast(completer),
511cb0ef41Sopenharmony_ci    });
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci    const last = '\r\nFirst group\r\n\r\n' +
541cb0ef41Sopenharmony_ci    `${char}${'a'.repeat(10)}${' '.repeat(2 + width * 10)}` +
551cb0ef41Sopenharmony_ci      `${char}${'b'.repeat(10)}` +
561cb0ef41Sopenharmony_ci      (lineBreak ? '\r\n' : ' '.repeat(2 + width * 10)) +
571cb0ef41Sopenharmony_ci      `${char.repeat(11)}\r\n` +
581cb0ef41Sopenharmony_ci    `\r\n\u001b[1G\u001b[0J> ${char}\u001b[${4 + width}G`;
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci    const expectations = [char, '', last];
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci    rli.on('line', common.mustNotCall());
631cb0ef41Sopenharmony_ci    for (const character of `${char}\t\t`) {
641cb0ef41Sopenharmony_ci      fi.emit('data', character);
651cb0ef41Sopenharmony_ci      assert.strictEqual(output, expectations.shift());
661cb0ef41Sopenharmony_ci      output = '';
671cb0ef41Sopenharmony_ci    }
681cb0ef41Sopenharmony_ci    rli.close();
691cb0ef41Sopenharmony_ci  });
701cb0ef41Sopenharmony_ci});
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci{
731cb0ef41Sopenharmony_ci  let output = '';
741cb0ef41Sopenharmony_ci  class FakeInput extends EventEmitter {
751cb0ef41Sopenharmony_ci    columns = 80;
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    write = common.mustCall((data) => {
781cb0ef41Sopenharmony_ci      output += data;
791cb0ef41Sopenharmony_ci    }, 1);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    resume() {}
821cb0ef41Sopenharmony_ci    pause() {}
831cb0ef41Sopenharmony_ci    end() {}
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  const fi = new FakeInput();
871cb0ef41Sopenharmony_ci  const rli = new readline.Interface({
881cb0ef41Sopenharmony_ci    input: fi,
891cb0ef41Sopenharmony_ci    output: fi,
901cb0ef41Sopenharmony_ci    terminal: true,
911cb0ef41Sopenharmony_ci    completer:
921cb0ef41Sopenharmony_ci        common.mustCallAtLeast((_, cb) => cb(new Error('message'))),
931cb0ef41Sopenharmony_ci  });
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  rli.on('line', common.mustNotCall());
961cb0ef41Sopenharmony_ci  fi.emit('data', '\t');
971cb0ef41Sopenharmony_ci  queueMicrotask(() => {
981cb0ef41Sopenharmony_ci    assert.match(output, /^Tab completion error: Error: message/);
991cb0ef41Sopenharmony_ci    output = '';
1001cb0ef41Sopenharmony_ci  });
1011cb0ef41Sopenharmony_ci  rli.close();
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci{
1051cb0ef41Sopenharmony_ci  let output = '';
1061cb0ef41Sopenharmony_ci  class FakeInput extends EventEmitter {
1071cb0ef41Sopenharmony_ci    columns = 80;
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci    write = common.mustCall((data) => {
1101cb0ef41Sopenharmony_ci      output += data;
1111cb0ef41Sopenharmony_ci    }, 9);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci    resume() {}
1141cb0ef41Sopenharmony_ci    pause() {}
1151cb0ef41Sopenharmony_ci    end() {}
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  const fi = new FakeInput();
1191cb0ef41Sopenharmony_ci  const rli = new readline.Interface({
1201cb0ef41Sopenharmony_ci    input: fi,
1211cb0ef41Sopenharmony_ci    output: fi,
1221cb0ef41Sopenharmony_ci    terminal: true,
1231cb0ef41Sopenharmony_ci    completer: common.mustCall((input, cb) => {
1241cb0ef41Sopenharmony_ci      cb(null, [[input[0].toUpperCase() + input.slice(1)], input]);
1251cb0ef41Sopenharmony_ci    }),
1261cb0ef41Sopenharmony_ci  });
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  rli.on('line', common.mustNotCall());
1291cb0ef41Sopenharmony_ci  fi.emit('data', 'input');
1301cb0ef41Sopenharmony_ci  queueMicrotask(() => {
1311cb0ef41Sopenharmony_ci    fi.emit('data', '\t');
1321cb0ef41Sopenharmony_ci    queueMicrotask(() => {
1331cb0ef41Sopenharmony_ci      assert.match(output, /> Input/);
1341cb0ef41Sopenharmony_ci      output = '';
1351cb0ef41Sopenharmony_ci      rli.close();
1361cb0ef41Sopenharmony_ci    });
1371cb0ef41Sopenharmony_ci  });
1381cb0ef41Sopenharmony_ci}
139