diff options
author | Avi ד <avi.the.coder@gmail.com> | 2019-01-25 21:15:06 -0500 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2019-03-01 15:59:58 +0100 |
commit | fedc31bb3c46511d1fd1c906ee149d60f1c51bbf (patch) | |
tree | 5fd06a46ff30ccbe04be1fcaa14368945c413fff /test | |
parent | 0fd5b458bec739eb8b4cea4dc362a36eb3e61fde (diff) | |
download | android-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')
-rw-r--r-- | test/parallel/test-readline-interface.js | 166 |
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 { |