@@ -44,6 +44,53 @@ function addTest(sequences, expectedKeys) {
4444 assert.deepStrictEqual(keys, expectedKeys);
4545}
4646
47+ // Simulate key interval test cases
48+ // Returns a function that takes `next` test case and returns a thunk
49+ // that can be called to run tests in sequence
50+ // e.g.
51+ // addKeyIntervalTest(..)
52+ // (addKeyIntervalTest(..)
53+ // (addKeyIntervalTest(..)(noop)))()
54+ // where noop is a terminal function(() => {}).
55+
56+ const addKeyIntervalTest = (sequences, expectedKeys, interval,
57+ assertDelay) => {
58+ if (!interval) interval = 550;
59+ if (!assertDelay) assertDelay = 550;
60+ return (next) => () => {
61+
62+ if (!Array.isArray(sequences)) {
63+ sequences = [ sequences ];
64+ }
65+
66+ if (!Array.isArray(expectedKeys)) {
67+ expectedKeys = [ expectedKeys ];
68+ }
69+
70+ expectedKeys = expectedKeys.map(function(k) {
71+ return k ? extend({ ctrl: false, meta: false, shift: false }, k) : k;
72+ });
73+
74+ const keys = [];
75+ fi.on('keypress', (s, k) => keys.push(k));
76+
77+ const emitKeys = (arr) => {
78+ var head = arr.shift();
79+ var tail = arr;
80+ if (head) {
81+ fi.write(head);
82+ setTimeout(() => emitKeys(tail), interval);
83+ } else {
84+ setTimeout(() => {
85+ next();
86+ assert.deepStrictEqual(keys, expectedKeys);
87+ }, assertDelay);
88+ }
89+ };
90+ emitKeys(sequences);
91+ };
92+ };
93+
4794// regular alphanumerics
4895addTest('io.JS', [
4996 { name: 'i', sequence: 'i' },
@@ -149,3 +196,22 @@ addTest('\x1b[31ma\x1b[39ma', [
149196 { name: 'undefined', sequence: '\x1b[39m', code: '[39m' },
150197 { name: 'a', sequence: 'a' },
151198]);
199+
200+ // Reduce array of addKeyIntervalTest(..) right to left
201+ // with () => {} as initial function
202+ const runKeyIntervalTests = [
203+ // escape character
204+ addKeyIntervalTest('\x1b', [
205+ { name: 'escape', sequence: '\x1b', meta: true }
206+ ]),
207+ // chain of escape characters
208+ addKeyIntervalTest('\x1b\x1b\x1b\x1b'.split(''), [
209+ { name: 'escape', sequence: '\x1b', meta: true },
210+ { name: 'escape', sequence: '\x1b', meta: true },
211+ { name: 'escape', sequence: '\x1b', meta: true },
212+ { name: 'escape', sequence: '\x1b', meta: true }
213+ ])
214+ ].reverse().reduce((acc, fn) => fn(acc), () => {});
215+
216+ // run key interval tests one after another
217+ runKeyIntervalTests();
0 commit comments