11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst PassThrough = require('stream').PassThrough; 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst Interface = require('readline').Interface; 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciclass FakeInput extends PassThrough {} 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cifunction extend(k) { 101cb0ef41Sopenharmony_ci return Object.assign({ ctrl: false, meta: false, shift: false }, k); 111cb0ef41Sopenharmony_ci} 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst fi = new FakeInput(); 151cb0ef41Sopenharmony_ciconst fo = new FakeInput(); 161cb0ef41Sopenharmony_cinew Interface({ input: fi, output: fo, terminal: true }); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cilet keys = []; 191cb0ef41Sopenharmony_cifi.on('keypress', (s, k) => { 201cb0ef41Sopenharmony_ci keys.push(k); 211cb0ef41Sopenharmony_ci}); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cifunction addTest(sequences, expectedKeys) { 251cb0ef41Sopenharmony_ci if (!Array.isArray(sequences)) { 261cb0ef41Sopenharmony_ci sequences = [ sequences ]; 271cb0ef41Sopenharmony_ci } 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci if (!Array.isArray(expectedKeys)) { 301cb0ef41Sopenharmony_ci expectedKeys = [ expectedKeys ]; 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci expectedKeys = expectedKeys.map(extend); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci keys = []; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci sequences.forEach((sequence) => { 381cb0ef41Sopenharmony_ci fi.write(sequence); 391cb0ef41Sopenharmony_ci }); 401cb0ef41Sopenharmony_ci assert.deepStrictEqual(keys, expectedKeys); 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// Simulate key interval test cases 441cb0ef41Sopenharmony_ci// Returns a function that takes `next` test case and returns a thunk 451cb0ef41Sopenharmony_ci// that can be called to run tests in sequence 461cb0ef41Sopenharmony_ci// e.g. 471cb0ef41Sopenharmony_ci// addKeyIntervalTest(..) 481cb0ef41Sopenharmony_ci// (addKeyIntervalTest(..) 491cb0ef41Sopenharmony_ci// (addKeyIntervalTest(..)(noop)))() 501cb0ef41Sopenharmony_ci// where noop is a terminal function(() => {}). 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciconst addKeyIntervalTest = (sequences, expectedKeys, interval = 550, 531cb0ef41Sopenharmony_ci assertDelay = 550) => { 541cb0ef41Sopenharmony_ci const fn = common.mustCall((next) => () => { 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci if (!Array.isArray(sequences)) { 571cb0ef41Sopenharmony_ci sequences = [ sequences ]; 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci if (!Array.isArray(expectedKeys)) { 611cb0ef41Sopenharmony_ci expectedKeys = [ expectedKeys ]; 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci expectedKeys = expectedKeys.map(extend); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci const keys = []; 671cb0ef41Sopenharmony_ci fi.on('keypress', (s, k) => keys.push(k)); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci const emitKeys = ([head, ...tail]) => { 701cb0ef41Sopenharmony_ci if (head) { 711cb0ef41Sopenharmony_ci fi.write(head); 721cb0ef41Sopenharmony_ci setTimeout(() => emitKeys(tail), interval); 731cb0ef41Sopenharmony_ci } else { 741cb0ef41Sopenharmony_ci setTimeout(() => { 751cb0ef41Sopenharmony_ci next(); 761cb0ef41Sopenharmony_ci assert.deepStrictEqual(keys, expectedKeys); 771cb0ef41Sopenharmony_ci }, assertDelay); 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci }; 801cb0ef41Sopenharmony_ci emitKeys(sequences); 811cb0ef41Sopenharmony_ci }); 821cb0ef41Sopenharmony_ci return fn; 831cb0ef41Sopenharmony_ci}; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci// Regular alphanumerics 861cb0ef41Sopenharmony_ciaddTest('io.JS', [ 871cb0ef41Sopenharmony_ci { name: 'i', sequence: 'i' }, 881cb0ef41Sopenharmony_ci { name: 'o', sequence: 'o' }, 891cb0ef41Sopenharmony_ci { name: undefined, sequence: '.' }, 901cb0ef41Sopenharmony_ci { name: 'j', sequence: 'J', shift: true }, 911cb0ef41Sopenharmony_ci { name: 's', sequence: 'S', shift: true }, 921cb0ef41Sopenharmony_ci]); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci// Named characters 951cb0ef41Sopenharmony_ciaddTest('\n\r\t\x1b\n\x1b\r\x1b\t', [ 961cb0ef41Sopenharmony_ci { name: 'enter', sequence: '\n' }, 971cb0ef41Sopenharmony_ci { name: 'return', sequence: '\r' }, 981cb0ef41Sopenharmony_ci { name: 'tab', sequence: '\t' }, 991cb0ef41Sopenharmony_ci { name: 'enter', sequence: '\x1b\n', meta: true }, 1001cb0ef41Sopenharmony_ci { name: 'return', sequence: '\x1b\r', meta: true }, 1011cb0ef41Sopenharmony_ci { name: 'tab', sequence: '\x1b\t', meta: true }, 1021cb0ef41Sopenharmony_ci]); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// Space and backspace 1051cb0ef41Sopenharmony_ciaddTest('\b\x7f\x1b\b\x1b\x7f\x1b\x1b \x1b ', [ 1061cb0ef41Sopenharmony_ci { name: 'backspace', sequence: '\b' }, 1071cb0ef41Sopenharmony_ci { name: 'backspace', sequence: '\x7f' }, 1081cb0ef41Sopenharmony_ci { name: 'backspace', sequence: '\x1b\b', meta: true }, 1091cb0ef41Sopenharmony_ci { name: 'backspace', sequence: '\x1b\x7f', meta: true }, 1101cb0ef41Sopenharmony_ci { name: 'space', sequence: '\x1b\x1b ', meta: true }, 1111cb0ef41Sopenharmony_ci { name: 'space', sequence: ' ' }, 1121cb0ef41Sopenharmony_ci { name: 'space', sequence: '\x1b ', meta: true }, 1131cb0ef41Sopenharmony_ci]); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci// Escape key 1161cb0ef41Sopenharmony_ciaddTest('\x1b\x1b\x1b', [ 1171cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b\x1b\x1b', meta: true }, 1181cb0ef41Sopenharmony_ci]); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci// Escape sequence 1211cb0ef41Sopenharmony_ciaddTest('\x1b]', [{ name: undefined, sequence: '\x1B]', meta: true }]); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci// Control keys 1241cb0ef41Sopenharmony_ciaddTest('\x01\x0b\x10', [ 1251cb0ef41Sopenharmony_ci { name: 'a', sequence: '\x01', ctrl: true }, 1261cb0ef41Sopenharmony_ci { name: 'k', sequence: '\x0b', ctrl: true }, 1271cb0ef41Sopenharmony_ci { name: 'p', sequence: '\x10', ctrl: true }, 1281cb0ef41Sopenharmony_ci]); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci// Alt keys 1311cb0ef41Sopenharmony_ciaddTest('a\x1baA\x1bA', [ 1321cb0ef41Sopenharmony_ci { name: 'a', sequence: 'a' }, 1331cb0ef41Sopenharmony_ci { name: 'a', sequence: '\x1ba', meta: true }, 1341cb0ef41Sopenharmony_ci { name: 'a', sequence: 'A', shift: true }, 1351cb0ef41Sopenharmony_ci { name: 'a', sequence: '\x1bA', meta: true, shift: true }, 1361cb0ef41Sopenharmony_ci]); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci// xterm/gnome ESC [ letter (with modifiers) 1391cb0ef41Sopenharmony_ciaddTest('\x1b[2P\x1b[3P\x1b[4P\x1b[5P\x1b[6P\x1b[7P\x1b[8P\x1b[3Q\x1b[8Q\x1b[3R\x1b[8R\x1b[3S\x1b[8S', [ 1401cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[2P', code: '[P', shift: true, meta: false, ctrl: false }, 1411cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[3P', code: '[P', shift: false, meta: true, ctrl: false }, 1421cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[4P', code: '[P', shift: true, meta: true, ctrl: false }, 1431cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[5P', code: '[P', shift: false, meta: false, ctrl: true }, 1441cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[6P', code: '[P', shift: true, meta: false, ctrl: true }, 1451cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[7P', code: '[P', shift: false, meta: true, ctrl: true }, 1461cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[8P', code: '[P', shift: true, meta: true, ctrl: true }, 1471cb0ef41Sopenharmony_ci { name: 'f2', sequence: '\x1b[3Q', code: '[Q', meta: true }, 1481cb0ef41Sopenharmony_ci { name: 'f2', sequence: '\x1b[8Q', code: '[Q', shift: true, meta: true, ctrl: true }, 1491cb0ef41Sopenharmony_ci { name: 'f3', sequence: '\x1b[3R', code: '[R', meta: true }, 1501cb0ef41Sopenharmony_ci { name: 'f3', sequence: '\x1b[8R', code: '[R', shift: true, meta: true, ctrl: true }, 1511cb0ef41Sopenharmony_ci { name: 'f4', sequence: '\x1b[3S', code: '[S', meta: true }, 1521cb0ef41Sopenharmony_ci { name: 'f4', sequence: '\x1b[8S', code: '[S', shift: true, meta: true, ctrl: true }, 1531cb0ef41Sopenharmony_ci]); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci// xterm/gnome ESC O letter 1561cb0ef41Sopenharmony_ciaddTest('\x1bOP\x1bOQ\x1bOR\x1bOS', [ 1571cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1bOP', code: 'OP' }, 1581cb0ef41Sopenharmony_ci { name: 'f2', sequence: '\x1bOQ', code: 'OQ' }, 1591cb0ef41Sopenharmony_ci { name: 'f3', sequence: '\x1bOR', code: 'OR' }, 1601cb0ef41Sopenharmony_ci { name: 'f4', sequence: '\x1bOS', code: 'OS' }, 1611cb0ef41Sopenharmony_ci]); 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci// xterm/rxvt ESC [ number ~ */ 1641cb0ef41Sopenharmony_ciaddTest('\x1b[11~\x1b[12~\x1b[13~\x1b[14~', [ 1651cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[11~', code: '[11~' }, 1661cb0ef41Sopenharmony_ci { name: 'f2', sequence: '\x1b[12~', code: '[12~' }, 1671cb0ef41Sopenharmony_ci { name: 'f3', sequence: '\x1b[13~', code: '[13~' }, 1681cb0ef41Sopenharmony_ci { name: 'f4', sequence: '\x1b[14~', code: '[14~' }, 1691cb0ef41Sopenharmony_ci]); 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci// From Cygwin and used in libuv 1721cb0ef41Sopenharmony_ciaddTest('\x1b[[A\x1b[[B\x1b[[C\x1b[[D\x1b[[E', [ 1731cb0ef41Sopenharmony_ci { name: 'f1', sequence: '\x1b[[A', code: '[[A' }, 1741cb0ef41Sopenharmony_ci { name: 'f2', sequence: '\x1b[[B', code: '[[B' }, 1751cb0ef41Sopenharmony_ci { name: 'f3', sequence: '\x1b[[C', code: '[[C' }, 1761cb0ef41Sopenharmony_ci { name: 'f4', sequence: '\x1b[[D', code: '[[D' }, 1771cb0ef41Sopenharmony_ci { name: 'f5', sequence: '\x1b[[E', code: '[[E' }, 1781cb0ef41Sopenharmony_ci]); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci// Common 1811cb0ef41Sopenharmony_ciaddTest('\x1b[15~\x1b[17~\x1b[18~\x1b[19~\x1b[20~\x1b[21~\x1b[23~\x1b[24~', [ 1821cb0ef41Sopenharmony_ci { name: 'f5', sequence: '\x1b[15~', code: '[15~' }, 1831cb0ef41Sopenharmony_ci { name: 'f6', sequence: '\x1b[17~', code: '[17~' }, 1841cb0ef41Sopenharmony_ci { name: 'f7', sequence: '\x1b[18~', code: '[18~' }, 1851cb0ef41Sopenharmony_ci { name: 'f8', sequence: '\x1b[19~', code: '[19~' }, 1861cb0ef41Sopenharmony_ci { name: 'f9', sequence: '\x1b[20~', code: '[20~' }, 1871cb0ef41Sopenharmony_ci { name: 'f10', sequence: '\x1b[21~', code: '[21~' }, 1881cb0ef41Sopenharmony_ci { name: 'f11', sequence: '\x1b[23~', code: '[23~' }, 1891cb0ef41Sopenharmony_ci { name: 'f12', sequence: '\x1b[24~', code: '[24~' }, 1901cb0ef41Sopenharmony_ci]); 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci// xterm ESC [ letter 1931cb0ef41Sopenharmony_ciaddTest('\x1b[A\x1b[B\x1b[C\x1b[D\x1b[E\x1b[F\x1b[H', [ 1941cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1b[A', code: '[A' }, 1951cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1b[B', code: '[B' }, 1961cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1b[C', code: '[C' }, 1971cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[D', code: '[D' }, 1981cb0ef41Sopenharmony_ci { name: 'clear', sequence: '\x1b[E', code: '[E' }, 1991cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1b[F', code: '[F' }, 2001cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[H', code: '[H' }, 2011cb0ef41Sopenharmony_ci]); 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci// xterm/gnome ESC O letter 2041cb0ef41Sopenharmony_ciaddTest('\x1bOA\x1bOB\x1bOC\x1bOD\x1bOE\x1bOF\x1bOH', [ 2051cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1bOA', code: 'OA' }, 2061cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1bOB', code: 'OB' }, 2071cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1bOC', code: 'OC' }, 2081cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1bOD', code: 'OD' }, 2091cb0ef41Sopenharmony_ci { name: 'clear', sequence: '\x1bOE', code: 'OE' }, 2101cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1bOF', code: 'OF' }, 2111cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1bOH', code: 'OH' }, 2121cb0ef41Sopenharmony_ci]); 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci// Old xterm shift-arrows 2151cb0ef41Sopenharmony_ciaddTest('\x1bO2A\x1bO2B', [ 2161cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1bO2A', code: 'OA', shift: true }, 2171cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1bO2B', code: 'OB', shift: true }, 2181cb0ef41Sopenharmony_ci]); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci// xterm/rxvt ESC [ number ~ 2211cb0ef41Sopenharmony_ciaddTest('\x1b[1~\x1b[2~\x1b[3~\x1b[4~\x1b[5~\x1b[6~', [ 2221cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[1~', code: '[1~' }, 2231cb0ef41Sopenharmony_ci { name: 'insert', sequence: '\x1b[2~', code: '[2~' }, 2241cb0ef41Sopenharmony_ci { name: 'delete', sequence: '\x1b[3~', code: '[3~' }, 2251cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1b[4~', code: '[4~' }, 2261cb0ef41Sopenharmony_ci { name: 'pageup', sequence: '\x1b[5~', code: '[5~' }, 2271cb0ef41Sopenharmony_ci { name: 'pagedown', sequence: '\x1b[6~', code: '[6~' }, 2281cb0ef41Sopenharmony_ci]); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci// putty 2311cb0ef41Sopenharmony_ciaddTest('\x1b[[5~\x1b[[6~', [ 2321cb0ef41Sopenharmony_ci { name: 'pageup', sequence: '\x1b[[5~', code: '[[5~' }, 2331cb0ef41Sopenharmony_ci { name: 'pagedown', sequence: '\x1b[[6~', code: '[[6~' }, 2341cb0ef41Sopenharmony_ci]); 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci// rxvt 2371cb0ef41Sopenharmony_ciaddTest('\x1b[7~\x1b[8~', [ 2381cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[7~', code: '[7~' }, 2391cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1b[8~', code: '[8~' }, 2401cb0ef41Sopenharmony_ci]); 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci// gnome terminal 2431cb0ef41Sopenharmony_ciaddTest('\x1b[A\x1b[B\x1b[2A\x1b[2B', [ 2441cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1b[A', code: '[A' }, 2451cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1b[B', code: '[B' }, 2461cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1b[2A', code: '[A', shift: true }, 2471cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1b[2B', code: '[B', shift: true }, 2481cb0ef41Sopenharmony_ci]); 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci// `rxvt` keys with modifiers. 2511cb0ef41Sopenharmony_ciaddTest('\x1b[20~\x1b[2$\x1b[2^\x1b[3$\x1b[3^\x1b[5$\x1b[5^\x1b[6$\x1b[6^\x1b[7$\x1b[7^\x1b[8$\x1b[8^', [ 2521cb0ef41Sopenharmony_ci { name: 'f9', sequence: '\x1b[20~', code: '[20~' }, 2531cb0ef41Sopenharmony_ci { name: 'insert', sequence: '\x1b[2$', code: '[2$', shift: true }, 2541cb0ef41Sopenharmony_ci { name: 'insert', sequence: '\x1b[2^', code: '[2^', ctrl: true }, 2551cb0ef41Sopenharmony_ci { name: 'delete', sequence: '\x1b[3$', code: '[3$', shift: true }, 2561cb0ef41Sopenharmony_ci { name: 'delete', sequence: '\x1b[3^', code: '[3^', ctrl: true }, 2571cb0ef41Sopenharmony_ci { name: 'pageup', sequence: '\x1b[5$', code: '[5$', shift: true }, 2581cb0ef41Sopenharmony_ci { name: 'pageup', sequence: '\x1b[5^', code: '[5^', ctrl: true }, 2591cb0ef41Sopenharmony_ci { name: 'pagedown', sequence: '\x1b[6$', code: '[6$', shift: true }, 2601cb0ef41Sopenharmony_ci { name: 'pagedown', sequence: '\x1b[6^', code: '[6^', ctrl: true }, 2611cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[7$', code: '[7$', shift: true }, 2621cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[7^', code: '[7^', ctrl: true }, 2631cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1b[8$', code: '[8$', shift: true }, 2641cb0ef41Sopenharmony_ci { name: 'end', sequence: '\x1b[8^', code: '[8^', ctrl: true }, 2651cb0ef41Sopenharmony_ci]); 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci// Misc 2681cb0ef41Sopenharmony_ciaddTest('\x1b[Z', [ 2691cb0ef41Sopenharmony_ci { name: 'tab', sequence: '\x1b[Z', code: '[Z', shift: true }, 2701cb0ef41Sopenharmony_ci]); 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci// xterm + modifiers 2731cb0ef41Sopenharmony_ciaddTest('\x1b[20;5~\x1b[6;5^', [ 2741cb0ef41Sopenharmony_ci { name: 'f9', sequence: '\x1b[20;5~', code: '[20~', ctrl: true }, 2751cb0ef41Sopenharmony_ci { name: 'pagedown', sequence: '\x1b[6;5^', code: '[6^', ctrl: true }, 2761cb0ef41Sopenharmony_ci]); 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ciaddTest('\x1b[H\x1b[5H\x1b[1;5H', [ 2791cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[H', code: '[H' }, 2801cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[5H', code: '[H', ctrl: true }, 2811cb0ef41Sopenharmony_ci { name: 'home', sequence: '\x1b[1;5H', code: '[H', ctrl: true }, 2821cb0ef41Sopenharmony_ci]); 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci// Escape sequences broken into multiple data chunks 2851cb0ef41Sopenharmony_ciaddTest('\x1b[D\x1b[C\x1b[D\x1b[C'.split(''), [ 2861cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[D', code: '[D' }, 2871cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1b[C', code: '[C' }, 2881cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[D', code: '[D' }, 2891cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1b[C', code: '[C' }, 2901cb0ef41Sopenharmony_ci]); 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci// Escape sequences mixed with regular ones 2931cb0ef41Sopenharmony_ciaddTest('\x1b[DD\x1b[2DD\x1b[2^D', [ 2941cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[D', code: '[D' }, 2951cb0ef41Sopenharmony_ci { name: 'd', sequence: 'D', shift: true }, 2961cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[2D', code: '[D', shift: true }, 2971cb0ef41Sopenharmony_ci { name: 'd', sequence: 'D', shift: true }, 2981cb0ef41Sopenharmony_ci { name: 'insert', sequence: '\x1b[2^', code: '[2^', ctrl: true }, 2991cb0ef41Sopenharmony_ci { name: 'd', sequence: 'D', shift: true }, 3001cb0ef41Sopenharmony_ci]); 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci// Color sequences 3031cb0ef41Sopenharmony_ciaddTest('\x1b[31ma\x1b[39ma', [ 3041cb0ef41Sopenharmony_ci { name: 'undefined', sequence: '\x1b[31m', code: '[31m' }, 3051cb0ef41Sopenharmony_ci { name: 'a', sequence: 'a' }, 3061cb0ef41Sopenharmony_ci { name: 'undefined', sequence: '\x1b[39m', code: '[39m' }, 3071cb0ef41Sopenharmony_ci { name: 'a', sequence: 'a' }, 3081cb0ef41Sopenharmony_ci]); 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci// `rxvt` keys with modifiers. 3111cb0ef41Sopenharmony_ciaddTest('\x1b[a\x1b[b\x1b[c\x1b[d\x1b[e', [ 3121cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1b[a', code: '[a', shift: true }, 3131cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1b[b', code: '[b', shift: true }, 3141cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1b[c', code: '[c', shift: true }, 3151cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1b[d', code: '[d', shift: true }, 3161cb0ef41Sopenharmony_ci { name: 'clear', sequence: '\x1b[e', code: '[e', shift: true }, 3171cb0ef41Sopenharmony_ci]); 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ciaddTest('\x1bOa\x1bOb\x1bOc\x1bOd\x1bOe', [ 3201cb0ef41Sopenharmony_ci { name: 'up', sequence: '\x1bOa', code: 'Oa', ctrl: true }, 3211cb0ef41Sopenharmony_ci { name: 'down', sequence: '\x1bOb', code: 'Ob', ctrl: true }, 3221cb0ef41Sopenharmony_ci { name: 'right', sequence: '\x1bOc', code: 'Oc', ctrl: true }, 3231cb0ef41Sopenharmony_ci { name: 'left', sequence: '\x1bOd', code: 'Od', ctrl: true }, 3241cb0ef41Sopenharmony_ci { name: 'clear', sequence: '\x1bOe', code: 'Oe', ctrl: true }, 3251cb0ef41Sopenharmony_ci]); 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci// Reduce array of addKeyIntervalTest(..) right to left 3281cb0ef41Sopenharmony_ci// with () => {} as initial function. 3291cb0ef41Sopenharmony_ciconst runKeyIntervalTests = [ 3301cb0ef41Sopenharmony_ci // Escape character 3311cb0ef41Sopenharmony_ci addKeyIntervalTest('\x1b', [ 3321cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b', meta: true }, 3331cb0ef41Sopenharmony_ci ]), 3341cb0ef41Sopenharmony_ci // Chain of escape characters. 3351cb0ef41Sopenharmony_ci addKeyIntervalTest('\x1b\x1b\x1b\x1b'.split(''), [ 3361cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b', meta: true }, 3371cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b', meta: true }, 3381cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b', meta: true }, 3391cb0ef41Sopenharmony_ci { name: 'escape', sequence: '\x1b', meta: true }, 3401cb0ef41Sopenharmony_ci ]), 3411cb0ef41Sopenharmony_ci].reverse().reduce((acc, fn) => fn(acc), () => {}); 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci// Run key interval tests one after another. 3441cb0ef41Sopenharmony_cirunKeyIntervalTests(); 345