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')); });