11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// Flags: --expose-internals
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciconst readline = require('readline/promises');
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ciconst { EventEmitter } = require('events');
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    [
221cb0ef41Sopenharmony_ci      (line) => [
231cb0ef41Sopenharmony_ci        ['First group', '',
241cb0ef41Sopenharmony_ci         `${char}${'a'.repeat(10)}`,
251cb0ef41Sopenharmony_ci         `${char}${'b'.repeat(10)}`,
261cb0ef41Sopenharmony_ci         char.repeat(11),
271cb0ef41Sopenharmony_ci        ],
281cb0ef41Sopenharmony_ci        line,
291cb0ef41Sopenharmony_ci      ],
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci      async (line) => [
321cb0ef41Sopenharmony_ci        ['First group', '',
331cb0ef41Sopenharmony_ci         `${char}${'a'.repeat(10)}`,
341cb0ef41Sopenharmony_ci         `${char}${'b'.repeat(10)}`,
351cb0ef41Sopenharmony_ci         char.repeat(11),
361cb0ef41Sopenharmony_ci        ],
371cb0ef41Sopenharmony_ci        line,
381cb0ef41Sopenharmony_ci      ],
391cb0ef41Sopenharmony_ci    ].forEach((completer) => {
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci      let output = '';
421cb0ef41Sopenharmony_ci      const width = getStringWidth(char) - 1;
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci      class FakeInput extends EventEmitter {
451cb0ef41Sopenharmony_ci        columns = ((width + 1) * 10 + (lineBreak ? 0 : 10)) * 3;
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci        write = common.mustCall((data) => {
481cb0ef41Sopenharmony_ci          output += data;
491cb0ef41Sopenharmony_ci        }, 6);
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci        resume() {}
521cb0ef41Sopenharmony_ci        pause() {}
531cb0ef41Sopenharmony_ci        end() {}
541cb0ef41Sopenharmony_ci      }
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci      const fi = new FakeInput();
571cb0ef41Sopenharmony_ci      const rli = new readline.Interface({
581cb0ef41Sopenharmony_ci        input: fi,
591cb0ef41Sopenharmony_ci        output: fi,
601cb0ef41Sopenharmony_ci        terminal: true,
611cb0ef41Sopenharmony_ci        completer: common.mustCallAtLeast(completer),
621cb0ef41Sopenharmony_ci      });
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci      const last = '\r\nFirst group\r\n\r\n' +
651cb0ef41Sopenharmony_ci        `${char}${'a'.repeat(10)}${' '.repeat(2 + width * 10)}` +
661cb0ef41Sopenharmony_ci        `${char}${'b'.repeat(10)}` +
671cb0ef41Sopenharmony_ci        (lineBreak ? '\r\n' : ' '.repeat(2 + width * 10)) +
681cb0ef41Sopenharmony_ci        `${char.repeat(11)}\r\n` +
691cb0ef41Sopenharmony_ci        `\r\n\u001b[1G\u001b[0J> ${char}\u001b[${4 + width}G`;
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci      const expectations = [char, '', last];
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci      rli.on('line', common.mustNotCall());
741cb0ef41Sopenharmony_ci      for (const character of `${char}\t\t`) {
751cb0ef41Sopenharmony_ci        fi.emit('data', character);
761cb0ef41Sopenharmony_ci        queueMicrotask(() => {
771cb0ef41Sopenharmony_ci          assert.strictEqual(output, expectations.shift());
781cb0ef41Sopenharmony_ci          output = '';
791cb0ef41Sopenharmony_ci        });
801cb0ef41Sopenharmony_ci      }
811cb0ef41Sopenharmony_ci      rli.close();
821cb0ef41Sopenharmony_ci    });
831cb0ef41Sopenharmony_ci  });
841cb0ef41Sopenharmony_ci});
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci{
871cb0ef41Sopenharmony_ci  let output = '';
881cb0ef41Sopenharmony_ci  class FakeInput extends EventEmitter {
891cb0ef41Sopenharmony_ci    columns = 80;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci    write = common.mustCall((data) => {
921cb0ef41Sopenharmony_ci      output += data;
931cb0ef41Sopenharmony_ci    }, 1);
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci    resume() {}
961cb0ef41Sopenharmony_ci    pause() {}
971cb0ef41Sopenharmony_ci    end() {}
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  const fi = new FakeInput();
1011cb0ef41Sopenharmony_ci  const rli = new readline.Interface({
1021cb0ef41Sopenharmony_ci    input: fi,
1031cb0ef41Sopenharmony_ci    output: fi,
1041cb0ef41Sopenharmony_ci    terminal: true,
1051cb0ef41Sopenharmony_ci    completer:
1061cb0ef41Sopenharmony_ci        common.mustCallAtLeast(() => Promise.reject(new Error('message'))),
1071cb0ef41Sopenharmony_ci  });
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  rli.on('line', common.mustNotCall());
1101cb0ef41Sopenharmony_ci  fi.emit('data', '\t');
1111cb0ef41Sopenharmony_ci  queueMicrotask(() => {
1121cb0ef41Sopenharmony_ci    assert.match(output, /^Tab completion error: Error: message/);
1131cb0ef41Sopenharmony_ci    output = '';
1141cb0ef41Sopenharmony_ci  });
1151cb0ef41Sopenharmony_ci  rli.close();
1161cb0ef41Sopenharmony_ci}
117