diff --git a/test/fixtures/use-input.js b/test/fixtures/use-input.js
index 08a9e3498..82618d2b7 100644
--- a/test/fixtures/use-input.js
+++ b/test/fixtures/use-input.js
@@ -2,19 +2,57 @@
const React = require('react');
const {render, useInput, AppContext} = require('../..');
-const UserInput = () => {
+const UserInput = ({test}) => {
const {exit} = React.useContext(AppContext);
- useInput(input => {
- if (input === 'q') {
+ useInput((input, key) => {
+ if (test === 'lowercase' && input === 'q') {
exit();
+ return;
}
+
+ if (test === 'uppercase' && input === 'Q' && key.shift) {
+ exit();
+ return;
+ }
+
+ if (test === 'escape' && key.escape) {
+ exit();
+ return;
+ }
+
+ if (test === 'ctrl' && input === 'f' && key.ctrl) {
+ exit();
+ return;
+ }
+
+ if (test === 'upArrow' && key.upArrow) {
+ exit();
+ return;
+ }
+
+ if (test === 'downArrow' && key.downArrow) {
+ exit();
+ return;
+ }
+
+ if (test === 'leftArrow' && key.leftArrow) {
+ exit();
+ return;
+ }
+
+ if (test === 'rightArrow' && key.rightArrow) {
+ exit();
+ return;
+ }
+
+ throw new Error('Crash');
});
return null;
};
-const app = render();
+const app = render();
(async () => {
await app.waitUntilExit();
diff --git a/test/hooks.js b/test/hooks.js
index 900457467..0bc1105d9 100644
--- a/test/hooks.js
+++ b/test/hooks.js
@@ -1,44 +1,97 @@
import {serial as test} from 'ava';
import {spawn} from 'node-pty';
-test.cb('exit when user types "q" character', t => {
- const term = spawn('node', ['./fixtures/run', './use-input'], {
+const term = (fixture, args = []) => {
+ let resolve;
+ let reject;
+
+ // eslint-disable-next-line promise/param-names
+ const exitPromise = new Promise((resolve2, reject2) => {
+ resolve = resolve2;
+ reject = reject2;
+ });
+
+ const ps = spawn('node', ['./fixtures/run', `./${fixture}`, ...args], {
name: 'xterm-color',
cols: 100,
cwd: __dirname,
env: process.env
});
- let output = '';
+ const result = {
+ write: input => ps.write(input),
+ output: '',
+ waitForExit: () => exitPromise
+ };
- term.on('data', data => {
- output += data;
+ ps.on('data', data => {
+ result.output += data;
});
- let isExited = false;
-
- term.on('exit', code => {
- isExited = true;
-
+ ps.on('exit', code => {
if (code === 0) {
- t.true(output.includes('exited'));
- t.pass();
- t.end();
+ resolve();
return;
}
- t.fail();
- t.end();
+ reject(new Error(`Process exited with non-zero exit code: ${code}`));
});
- setTimeout(() => {
- t.false(isExited);
- term.write('q');
- }, 1000);
+ return result;
+};
+
+test('handle lowercase character', async t => {
+ const ps = term('use-input', ['lowercase']);
+ ps.write('q');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle uppercase character', async t => {
+ const ps = term('use-input', ['uppercase']);
+ ps.write('Q');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle escape', async t => {
+ const ps = term('use-input', ['escape']);
+ ps.write('\u001B');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle ctrl', async t => {
+ const ps = term('use-input', ['ctrl']);
+ ps.write('\u0006');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle up arrow', async t => {
+ const ps = term('use-input', ['upArrow']);
+ ps.write('\u001B[A');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle down arrow', async t => {
+ const ps = term('use-input', ['downArrow']);
+ ps.write('\u001B[B');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
+
+test('handle left arrow', async t => {
+ const ps = term('use-input', ['leftArrow']);
+ ps.write('\u001B[D');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
+});
- setTimeout(() => {
- term.kill();
- t.fail();
- t.end();
- }, 1500);
+test('handle right arrow', async t => {
+ const ps = term('use-input', ['rightArrow']);
+ ps.write('\u001B[C');
+ await ps.waitForExit();
+ t.true(ps.output.includes('exited'));
});