11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common');
51cb0ef41Sopenharmony_ciconst assert = require('assert');
61cb0ef41Sopenharmony_ciconst readline = require('readline');
71cb0ef41Sopenharmony_ciconst { Writable } = require('stream');
81cb0ef41Sopenharmony_ciconst { CSI } = require('internal/readline/utils');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci{
111cb0ef41Sopenharmony_ci  assert(CSI);
121cb0ef41Sopenharmony_ci  assert.strictEqual(CSI.kClearToLineBeginning, '\x1b[1K');
131cb0ef41Sopenharmony_ci  assert.strictEqual(CSI.kClearToLineEnd, '\x1b[0K');
141cb0ef41Sopenharmony_ci  assert.strictEqual(CSI.kClearLine, '\x1b[2K');
151cb0ef41Sopenharmony_ci  assert.strictEqual(CSI.kClearScreenDown, '\x1b[0J');
161cb0ef41Sopenharmony_ci  assert.strictEqual(CSI`1${2}3`, '\x1b[123');
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass TestWritable extends Writable {
201cb0ef41Sopenharmony_ci  constructor() {
211cb0ef41Sopenharmony_ci    super();
221cb0ef41Sopenharmony_ci    this.data = '';
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci  _write(chunk, encoding, callback) {
251cb0ef41Sopenharmony_ci    this.data += chunk.toString();
261cb0ef41Sopenharmony_ci    callback();
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciconst writable = new TestWritable();
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearScreenDown(writable), true);
331cb0ef41Sopenharmony_ciassert.deepStrictEqual(writable.data, CSI.kClearScreenDown);
341cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearScreenDown(writable, common.mustCall()), true);
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci// Verify that clearScreenDown() throws on invalid callback.
371cb0ef41Sopenharmony_ciassert.throws(() => {
381cb0ef41Sopenharmony_ci  readline.clearScreenDown(writable, null);
391cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_TYPE/);
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci// Verify that clearScreenDown() does not throw on null or undefined stream.
421cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearScreenDown(null, common.mustCall((err) => {
431cb0ef41Sopenharmony_ci  assert.strictEqual(err, null);
441cb0ef41Sopenharmony_ci})), true);
451cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearScreenDown(undefined, common.mustCall()),
461cb0ef41Sopenharmony_ci                   true);
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciwritable.data = '';
491cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(writable, -1), true);
501cb0ef41Sopenharmony_ciassert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciwritable.data = '';
531cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(writable, 1), true);
541cb0ef41Sopenharmony_ciassert.deepStrictEqual(writable.data, CSI.kClearToLineEnd);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciwritable.data = '';
571cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(writable, 0), true);
581cb0ef41Sopenharmony_ciassert.deepStrictEqual(writable.data, CSI.kClearLine);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciwritable.data = '';
611cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(writable, -1, common.mustCall()), true);
621cb0ef41Sopenharmony_ciassert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning);
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci// Verify that clearLine() throws on invalid callback.
651cb0ef41Sopenharmony_ciassert.throws(() => {
661cb0ef41Sopenharmony_ci  readline.clearLine(writable, 0, null);
671cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_TYPE/);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci// Verify that clearLine() does not throw on null or undefined stream.
701cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(null, 0), true);
711cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(undefined, 0), true);
721cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(null, 0, common.mustCall((err) => {
731cb0ef41Sopenharmony_ci  assert.strictEqual(err, null);
741cb0ef41Sopenharmony_ci})), true);
751cb0ef41Sopenharmony_ciassert.strictEqual(readline.clearLine(undefined, 0, common.mustCall()), true);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci// Nothing is written when moveCursor 0, 0
781cb0ef41Sopenharmony_ci[
791cb0ef41Sopenharmony_ci  [0, 0, ''],
801cb0ef41Sopenharmony_ci  [1, 0, '\x1b[1C'],
811cb0ef41Sopenharmony_ci  [-1, 0, '\x1b[1D'],
821cb0ef41Sopenharmony_ci  [0, 1, '\x1b[1B'],
831cb0ef41Sopenharmony_ci  [0, -1, '\x1b[1A'],
841cb0ef41Sopenharmony_ci  [1, 1, '\x1b[1C\x1b[1B'],
851cb0ef41Sopenharmony_ci  [-1, 1, '\x1b[1D\x1b[1B'],
861cb0ef41Sopenharmony_ci  [-1, -1, '\x1b[1D\x1b[1A'],
871cb0ef41Sopenharmony_ci  [1, -1, '\x1b[1C\x1b[1A'],
881cb0ef41Sopenharmony_ci].forEach((set) => {
891cb0ef41Sopenharmony_ci  writable.data = '';
901cb0ef41Sopenharmony_ci  assert.strictEqual(readline.moveCursor(writable, set[0], set[1]), true);
911cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, set[2]);
921cb0ef41Sopenharmony_ci  writable.data = '';
931cb0ef41Sopenharmony_ci  assert.strictEqual(
941cb0ef41Sopenharmony_ci    readline.moveCursor(writable, set[0], set[1], common.mustCall()),
951cb0ef41Sopenharmony_ci    true
961cb0ef41Sopenharmony_ci  );
971cb0ef41Sopenharmony_ci  assert.deepStrictEqual(writable.data, set[2]);
981cb0ef41Sopenharmony_ci});
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci// Verify that moveCursor() throws on invalid callback.
1011cb0ef41Sopenharmony_ciassert.throws(() => {
1021cb0ef41Sopenharmony_ci  readline.moveCursor(writable, 1, 1, null);
1031cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_TYPE/);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci// Verify that moveCursor() does not throw on null or undefined stream.
1061cb0ef41Sopenharmony_ciassert.strictEqual(readline.moveCursor(null, 1, 1), true);
1071cb0ef41Sopenharmony_ciassert.strictEqual(readline.moveCursor(undefined, 1, 1), true);
1081cb0ef41Sopenharmony_ciassert.strictEqual(readline.moveCursor(null, 1, 1, common.mustCall((err) => {
1091cb0ef41Sopenharmony_ci  assert.strictEqual(err, null);
1101cb0ef41Sopenharmony_ci})), true);
1111cb0ef41Sopenharmony_ciassert.strictEqual(readline.moveCursor(undefined, 1, 1, common.mustCall()),
1121cb0ef41Sopenharmony_ci                   true);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// Undefined or null as stream should not throw.
1151cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(null), true);
1161cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(), true);
1171cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(null, 1, 1, common.mustCall()), true);
1181cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(undefined, 1, 1, common.mustCall((err) => {
1191cb0ef41Sopenharmony_ci  assert.strictEqual(err, null);
1201cb0ef41Sopenharmony_ci})), true);
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ciwritable.data = '';
1231cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 'a'), true);
1241cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '');
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciwritable.data = '';
1271cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 'a', 'b'), true);
1281cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '');
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ciwritable.data = '';
1311cb0ef41Sopenharmony_ciassert.throws(
1321cb0ef41Sopenharmony_ci  () => readline.cursorTo(writable, 'a', 1),
1331cb0ef41Sopenharmony_ci  {
1341cb0ef41Sopenharmony_ci    name: 'TypeError',
1351cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_CURSOR_POS',
1361cb0ef41Sopenharmony_ci    message: 'Cannot set cursor row without setting its column'
1371cb0ef41Sopenharmony_ci  });
1381cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '');
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ciwritable.data = '';
1411cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 1, 'a'), true);
1421cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '\x1b[2G');
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciwritable.data = '';
1451cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 1), true);
1461cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '\x1b[2G');
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciwritable.data = '';
1491cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 1, 2), true);
1501cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '\x1b[3;2H');
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ciwritable.data = '';
1531cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 1, 2, common.mustCall()), true);
1541cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '\x1b[3;2H');
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ciwritable.data = '';
1571cb0ef41Sopenharmony_ciassert.strictEqual(readline.cursorTo(writable, 1, common.mustCall()), true);
1581cb0ef41Sopenharmony_ciassert.strictEqual(writable.data, '\x1b[2G');
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci// Verify that cursorTo() throws on invalid callback.
1611cb0ef41Sopenharmony_ciassert.throws(() => {
1621cb0ef41Sopenharmony_ci  readline.cursorTo(writable, 1, 1, null);
1631cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_TYPE/);
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci// Verify that cursorTo() throws if x or y is NaN.
1661cb0ef41Sopenharmony_ciassert.throws(() => {
1671cb0ef41Sopenharmony_ci  readline.cursorTo(writable, NaN);
1681cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_VALUE/);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciassert.throws(() => {
1711cb0ef41Sopenharmony_ci  readline.cursorTo(writable, 1, NaN);
1721cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_VALUE/);
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ciassert.throws(() => {
1751cb0ef41Sopenharmony_ci  readline.cursorTo(writable, NaN, NaN);
1761cb0ef41Sopenharmony_ci}, /ERR_INVALID_ARG_VALUE/);
177