11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciimport '../common/index.mjs';
51cb0ef41Sopenharmony_ciimport assert from 'assert';
61cb0ef41Sopenharmony_ciimport { Readline } from 'readline/promises';
71cb0ef41Sopenharmony_ciimport { setImmediate } from 'timers/promises';
81cb0ef41Sopenharmony_ciimport { Writable } from 'stream';
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciimport utils from 'internal/readline/utils';
111cb0ef41Sopenharmony_ciconst { CSI } = utils;
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciconst INVALID_ARG = {
141cb0ef41Sopenharmony_ci  name: 'TypeError',
151cb0ef41Sopenharmony_ci  code: 'ERR_INVALID_ARG_TYPE',
161cb0ef41Sopenharmony_ci};
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciclass TestWritable extends Writable {
191cb0ef41Sopenharmony_ci  data = '';
201cb0ef41Sopenharmony_ci  _write(chunk, encoding, callback) {
211cb0ef41Sopenharmony_ci    this.data += chunk.toString();
221cb0ef41Sopenharmony_ci    callback();
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci}
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci[
271cb0ef41Sopenharmony_ci  undefined, null,
281cb0ef41Sopenharmony_ci  0, 1, 1n, 1.1, NaN, Infinity,
291cb0ef41Sopenharmony_ci  true, false,
301cb0ef41Sopenharmony_ci  Symbol(),
311cb0ef41Sopenharmony_ci  '', '1',
321cb0ef41Sopenharmony_ci  [], {}, () => {},
331cb0ef41Sopenharmony_ci].forEach((arg) =>
341cb0ef41Sopenharmony_ci  assert.throws(() => new Readline(arg), INVALID_ARG)
351cb0ef41Sopenharmony_ci);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci{
381cb0ef41Sopenharmony_ci  const writable = new TestWritable();
391cb0ef41Sopenharmony_ci  const readline = new Readline(writable);
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  await readline.clearScreenDown().commit();
421cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearScreenDown);
431cb0ef41Sopenharmony_ci  await readline.clearScreenDown().commit();
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  writable.data = '';
461cb0ef41Sopenharmony_ci  await readline.clearScreenDown().rollback();
471cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '');
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  writable.data = '';
501cb0ef41Sopenharmony_ci  await readline.clearLine(-1).commit();
511cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning);
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  writable.data = '';
541cb0ef41Sopenharmony_ci  await readline.clearLine(1).commit();
551cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearToLineEnd);
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  writable.data = '';
581cb0ef41Sopenharmony_ci  await readline.clearLine(0).commit();
591cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearLine);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  writable.data = '';
621cb0ef41Sopenharmony_ci  await readline.clearLine(-1).commit();
631cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning);
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  await readline.clearLine(0, null).commit();
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  // Nothing is written when moveCursor 0, 0
681cb0ef41Sopenharmony_ci  for (const set of
691cb0ef41Sopenharmony_ci    [
701cb0ef41Sopenharmony_ci      [0, 0, ''],
711cb0ef41Sopenharmony_ci      [1, 0, '\x1b[1C'],
721cb0ef41Sopenharmony_ci      [-1, 0, '\x1b[1D'],
731cb0ef41Sopenharmony_ci      [0, 1, '\x1b[1B'],
741cb0ef41Sopenharmony_ci      [0, -1, '\x1b[1A'],
751cb0ef41Sopenharmony_ci      [1, 1, '\x1b[1C\x1b[1B'],
761cb0ef41Sopenharmony_ci      [-1, 1, '\x1b[1D\x1b[1B'],
771cb0ef41Sopenharmony_ci      [-1, -1, '\x1b[1D\x1b[1A'],
781cb0ef41Sopenharmony_ci      [1, -1, '\x1b[1C\x1b[1A'],
791cb0ef41Sopenharmony_ci    ]) {
801cb0ef41Sopenharmony_ci    writable.data = '';
811cb0ef41Sopenharmony_ci    await readline.moveCursor(set[0], set[1]).commit();
821cb0ef41Sopenharmony_ci    assert.deepStrictEqual(writable.data, set[2]);
831cb0ef41Sopenharmony_ci    writable.data = '';
841cb0ef41Sopenharmony_ci    await readline.moveCursor(set[0], set[1]).commit();
851cb0ef41Sopenharmony_ci    assert.deepStrictEqual(writable.data, set[2]);
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  await readline.moveCursor(1, 1, null).commit();
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  writable.data = '';
921cb0ef41Sopenharmony_ci  [
931cb0ef41Sopenharmony_ci    undefined, null,
941cb0ef41Sopenharmony_ci    true, false,
951cb0ef41Sopenharmony_ci    Symbol(),
961cb0ef41Sopenharmony_ci    '', '1',
971cb0ef41Sopenharmony_ci    [], {}, () => {},
981cb0ef41Sopenharmony_ci  ].forEach((arg) =>
991cb0ef41Sopenharmony_ci    assert.throws(() => readline.cursorTo(arg), INVALID_ARG)
1001cb0ef41Sopenharmony_ci  );
1011cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '');
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  writable.data = '';
1041cb0ef41Sopenharmony_ci  assert.throws(() => readline.cursorTo('a', 'b'), INVALID_ARG);
1051cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '');
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  writable.data = '';
1081cb0ef41Sopenharmony_ci  assert.throws(() => readline.cursorTo('a', 1), INVALID_ARG);
1091cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '');
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  writable.data = '';
1121cb0ef41Sopenharmony_ci  assert.throws(() => readline.cursorTo(1, 'a'), INVALID_ARG);
1131cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '');
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  writable.data = '';
1161cb0ef41Sopenharmony_ci  await readline.cursorTo(1).commit();
1171cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '\x1b[2G');
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  writable.data = '';
1201cb0ef41Sopenharmony_ci  await readline.cursorTo(1, 2).commit();
1211cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '\x1b[3;2H');
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  writable.data = '';
1241cb0ef41Sopenharmony_ci  await readline.cursorTo(1, 2).commit();
1251cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '\x1b[3;2H');
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  writable.data = '';
1281cb0ef41Sopenharmony_ci  await readline.cursorTo(1).cursorTo(1, 2).commit();
1291cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '\x1b[2G\x1b[3;2H');
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  writable.data = '';
1321cb0ef41Sopenharmony_ci  await readline.cursorTo(1).commit();
1331cb0ef41Sopenharmony_ci  assert.strictEqual(writable.data, '\x1b[2G');
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  // Verify that cursorTo() rejects if x or y is NaN.
1361cb0ef41Sopenharmony_ci  [1.1, NaN, Infinity].forEach((arg) => {
1371cb0ef41Sopenharmony_ci    assert.throws(() => readline.cursorTo(arg), {
1381cb0ef41Sopenharmony_ci      code: 'ERR_OUT_OF_RANGE',
1391cb0ef41Sopenharmony_ci      name: 'RangeError',
1401cb0ef41Sopenharmony_ci    });
1411cb0ef41Sopenharmony_ci  });
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  [1.1, NaN, Infinity].forEach((arg) => {
1441cb0ef41Sopenharmony_ci    assert.throws(() => readline.cursorTo(1, arg), {
1451cb0ef41Sopenharmony_ci      code: 'ERR_OUT_OF_RANGE',
1461cb0ef41Sopenharmony_ci      name: 'RangeError',
1471cb0ef41Sopenharmony_ci    });
1481cb0ef41Sopenharmony_ci  });
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  assert.throws(() => readline.cursorTo(NaN, NaN), {
1511cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE',
1521cb0ef41Sopenharmony_ci    name: 'RangeError',
1531cb0ef41Sopenharmony_ci  });
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci{
1571cb0ef41Sopenharmony_ci  const error = new Error();
1581cb0ef41Sopenharmony_ci  const writable = new class extends Writable {
1591cb0ef41Sopenharmony_ci    _write() { throw error; }
1601cb0ef41Sopenharmony_ci  }();
1611cb0ef41Sopenharmony_ci  const readline = new Readline(writable);
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci  await assert.rejects(readline.cursorTo(1).commit(), error);
1641cb0ef41Sopenharmony_ci}
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci{
1671cb0ef41Sopenharmony_ci  const writable = new TestWritable();
1681cb0ef41Sopenharmony_ci  const readline = new Readline(writable, { autoCommit: true });
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  await readline.clearScreenDown();
1711cb0ef41Sopenharmony_ci  await setImmediate(); // Wait for next tick as auto commit is asynchronous.
1721cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, CSI.kClearScreenDown);
1731cb0ef41Sopenharmony_ci}
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci{
1761cb0ef41Sopenharmony_ci  const writable = new TestWritable();
1771cb0ef41Sopenharmony_ci  const readline = new Readline(writable, { autoCommit: true });
1781cb0ef41Sopenharmony_ci  for (const [dir, data] of
1791cb0ef41Sopenharmony_ci    [
1801cb0ef41Sopenharmony_ci      [-1, CSI.kClearToLineBeginning],
1811cb0ef41Sopenharmony_ci      [1, CSI.kClearToLineEnd],
1821cb0ef41Sopenharmony_ci      [0, CSI.kClearLine],
1831cb0ef41Sopenharmony_ci    ]) {
1841cb0ef41Sopenharmony_ci    writable.data = '';
1851cb0ef41Sopenharmony_ci    readline.clearLine(dir);
1861cb0ef41Sopenharmony_ci    await setImmediate(); // Wait for next tick as auto commit is asynchronous.
1871cb0ef41Sopenharmony_ci    assert.deepStrictEqual(writable.data, data);
1881cb0ef41Sopenharmony_ci  }
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci{
1921cb0ef41Sopenharmony_ci  const writable = new TestWritable();
1931cb0ef41Sopenharmony_ci  const readline = new Readline(writable, { autoCommit: true });
1941cb0ef41Sopenharmony_ci  for (const [x, y, data] of
1951cb0ef41Sopenharmony_ci    [
1961cb0ef41Sopenharmony_ci      [0, 0, ''],
1971cb0ef41Sopenharmony_ci      [1, 0, '\x1b[1C'],
1981cb0ef41Sopenharmony_ci      [-1, 0, '\x1b[1D'],
1991cb0ef41Sopenharmony_ci      [0, 1, '\x1b[1B'],
2001cb0ef41Sopenharmony_ci      [0, -1, '\x1b[1A'],
2011cb0ef41Sopenharmony_ci      [1, 1, '\x1b[1C\x1b[1B'],
2021cb0ef41Sopenharmony_ci      [-1, 1, '\x1b[1D\x1b[1B'],
2031cb0ef41Sopenharmony_ci      [-1, -1, '\x1b[1D\x1b[1A'],
2041cb0ef41Sopenharmony_ci      [1, -1, '\x1b[1C\x1b[1A'],
2051cb0ef41Sopenharmony_ci    ]) {
2061cb0ef41Sopenharmony_ci    writable.data = '';
2071cb0ef41Sopenharmony_ci    readline.moveCursor(x, y);
2081cb0ef41Sopenharmony_ci    await setImmediate(); // Wait for next tick as auto commit is asynchronous.
2091cb0ef41Sopenharmony_ci    assert.deepStrictEqual(writable.data, data);
2101cb0ef41Sopenharmony_ci  }
2111cb0ef41Sopenharmony_ci}
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci{
2141cb0ef41Sopenharmony_ci  const writable = new TestWritable();
2151cb0ef41Sopenharmony_ci  const readline = new Readline(writable, { autoCommit: true });
2161cb0ef41Sopenharmony_ci  for (const [x, y, data] of
2171cb0ef41Sopenharmony_ci    [
2181cb0ef41Sopenharmony_ci      [1, undefined, '\x1b[2G'],
2191cb0ef41Sopenharmony_ci      [1, 2, '\x1b[3;2H'],
2201cb0ef41Sopenharmony_ci    ]) {
2211cb0ef41Sopenharmony_ci    writable.data = '';
2221cb0ef41Sopenharmony_ci    readline.cursorTo(x, y);
2231cb0ef41Sopenharmony_ci    await setImmediate(); // Wait for next tick as auto commit is asynchronous.
2241cb0ef41Sopenharmony_ci    assert.deepStrictEqual(writable.data, data);
2251cb0ef41Sopenharmony_ci  }
2261cb0ef41Sopenharmony_ci}
227