summaryrefslogtreecommitdiff
path: root/test/parallel/test-readline-interface.js
diff options
context:
space:
mode:
authorAvi ד <avi.the.coder@gmail.com>2019-01-25 21:15:06 -0500
committerRuben Bridgewater <ruben@bridgewater.de>2019-03-01 15:59:58 +0100
commitfedc31bb3c46511d1fd1c906ee149d60f1c51bbf (patch)
tree5fd06a46ff30ccbe04be1fcaa14368945c413fff /test/parallel/test-readline-interface.js
parent0fd5b458bec739eb8b4cea4dc362a36eb3e61fde (diff)
downloadandroid-node-v8-fedc31bb3c46511d1fd1c906ee149d60f1c51bbf.tar.gz
android-node-v8-fedc31bb3c46511d1fd1c906ee149d60f1c51bbf.tar.bz2
android-node-v8-fedc31bb3c46511d1fd1c906ee149d60f1c51bbf.zip
readline: improve Unicode handling
Prevents moving left or right from placing the cursor in between code units comprising a code point. PR-URL: https://github.com/nodejs/node/pull/25723 Fixes: https://github.com/nodejs/node/issues/25693 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'test/parallel/test-readline-interface.js')
-rw-r--r--test/parallel/test-readline-interface.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js
index 6cbd0b08ac..90cb8f1584 100644
--- a/test/parallel/test-readline-interface.js
+++ b/test/parallel/test-readline-interface.js
@@ -650,6 +650,115 @@ function isWarned(emitter) {
rli.close();
}
+ // Back and Forward one astral character
+ {
+ const fi = new FakeInput();
+ const rli = new readline.Interface({
+ input: fi,
+ output: fi,
+ prompt: '',
+ terminal: terminal
+ });
+ fi.emit('data', '💻');
+
+ // move left one character/code point
+ fi.emit('keypress', '.', { name: 'left' });
+ let cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ assert.strictEqual(cursorPos.cols, 0);
+
+ // move right one character/code point
+ fi.emit('keypress', '.', { name: 'right' });
+ cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ if (common.hasIntl) {
+ assert.strictEqual(cursorPos.cols, 2);
+ } else {
+ assert.strictEqual(cursorPos.cols, 1);
+ }
+
+ rli.on('line', common.mustCall((line) => {
+ assert.strictEqual(line, '💻');
+ }));
+ fi.emit('data', '\n');
+ rli.close();
+ }
+
+ // Two astral characters left
+ {
+ const fi = new FakeInput();
+ const rli = new readline.Interface({
+ input: fi,
+ output: fi,
+ prompt: '',
+ terminal: terminal
+ });
+ fi.emit('data', '💻');
+
+ // move left one character/code point
+ fi.emit('keypress', '.', { name: 'left' });
+ let cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ assert.strictEqual(cursorPos.cols, 0);
+
+ fi.emit('data', '🐕');
+ cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+
+ if (common.hasIntl) {
+ assert.strictEqual(cursorPos.cols, 2);
+ } else {
+ assert.strictEqual(cursorPos.cols, 1);
+ // Fix cursor position without internationalization
+ fi.emit('keypress', '.', { name: 'left' });
+ }
+
+ rli.on('line', common.mustCall((line) => {
+ assert.strictEqual(line, '🐕💻');
+ }));
+ fi.emit('data', '\n');
+ rli.close();
+ }
+
+ // Two astral characters right
+ {
+ const fi = new FakeInput();
+ const rli = new readline.Interface({
+ input: fi,
+ output: fi,
+ prompt: '',
+ terminal: terminal
+ });
+ fi.emit('data', '💻');
+
+ // move left one character/code point
+ fi.emit('keypress', '.', { name: 'right' });
+ let cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ if (common.hasIntl) {
+ assert.strictEqual(cursorPos.cols, 2);
+ } else {
+ assert.strictEqual(cursorPos.cols, 1);
+ // Fix cursor position without internationalization
+ fi.emit('keypress', '.', { name: 'right' });
+ }
+
+ fi.emit('data', '🐕');
+ cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ if (common.hasIntl) {
+ assert.strictEqual(cursorPos.cols, 4);
+ } else {
+ assert.strictEqual(cursorPos.cols, 2);
+ }
+
+ rli.on('line', common.mustCall((line) => {
+ assert.strictEqual(line, '💻🐕');
+ }));
+ fi.emit('data', '\n');
+ rli.close();
+ }
+
{
// `wordLeft` and `wordRight`
const fi = new FakeInput();
@@ -791,6 +900,35 @@ function isWarned(emitter) {
rli.close();
}
+ // deleteLeft astral character
+ {
+ const fi = new FakeInput();
+ const rli = new readline.Interface({
+ input: fi,
+ output: fi,
+ prompt: '',
+ terminal: terminal
+ });
+ fi.emit('data', '💻');
+ let cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ if (common.hasIntl) {
+ assert.strictEqual(cursorPos.cols, 2);
+ } else {
+ assert.strictEqual(cursorPos.cols, 1);
+ }
+ // Delete left character
+ fi.emit('keypress', '.', { ctrl: true, name: 'h' });
+ cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ assert.strictEqual(cursorPos.cols, 0);
+ rli.on('line', common.mustCall((line) => {
+ assert.strictEqual(line, '');
+ }));
+ fi.emit('data', '\n');
+ rli.close();
+ }
+
// deleteRight
{
const fi = new FakeInput();
@@ -820,6 +958,34 @@ function isWarned(emitter) {
rli.close();
}
+ // deleteRight astral character
+ {
+ const fi = new FakeInput();
+ const rli = new readline.Interface({
+ input: fi,
+ output: fi,
+ prompt: '',
+ terminal: terminal
+ });
+ fi.emit('data', '💻');
+
+ // Go to the start of the line
+ fi.emit('keypress', '.', { ctrl: true, name: 'a' });
+ let cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ assert.strictEqual(cursorPos.cols, 0);
+
+ // Delete right character
+ fi.emit('keypress', '.', { ctrl: true, name: 'd' });
+ cursorPos = rli._getCursorPos();
+ assert.strictEqual(cursorPos.rows, 0);
+ assert.strictEqual(cursorPos.cols, 0);
+ rli.on('line', common.mustCall((line) => {
+ assert.strictEqual(line, '');
+ }));
+ fi.emit('data', '\n');
+ rli.close();
+ }
// deleteLineLeft
{