Skip to content

Commit

Permalink
setup and teardown keypress events on stdin
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadim Demedes committed Jul 12, 2017
1 parent a5bb287 commit 696d0fb
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 17 deletions.
21 changes: 19 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

const readline = require('readline');
const logUpdate = require('log-update');
const StringComponent = require('./lib/string-component');
const Component = require('./lib/component');
Expand Down Expand Up @@ -42,13 +43,27 @@ exports.diff = diff;

exports.renderToString = (...args) => renderToString(build(...args));

exports.render = (tree, stream = process.stdout) => {
const log = logUpdate.create(stream);
exports.render = (tree, options) => {
if (options && typeof options.write === 'function') {
options = {
stdout: options
};
}

const {stdin, stdout} = Object.assign({
stdin: process.stdin,
stdout: process.stdout
}, options);

const log = logUpdate.create(stdout);

const context = {};
let isUnmounted = false;
let currentTree;

readline.emitKeypressEvents(stdin);
stdin.setRawMode(true);

const update = () => {
const nextTree = build(tree, currentTree, onUpdate, context, false); // eslint-disable-line no-use-before-define
log(renderToString(nextTree));
Expand All @@ -73,6 +88,8 @@ exports.render = (tree, stream = process.stdout) => {
return;
}

stdin.setRawMode(false);

isUnmounted = true;
unmount(currentTree);
log.done();
Expand Down
62 changes: 47 additions & 15 deletions test/render.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import EventEmitter from 'events';
import stripAnsi from 'strip-ansi';
import {spy} from 'sinon';
import test from 'ava';
Expand All @@ -6,6 +7,34 @@ import {rerender} from '../lib/render-queue';

const stripOutput = str => stripAnsi(str).trim();

const createStdin = () => {
const events = new EventEmitter();
events.setRawMode = spy();

return events;
};

const createStdout = () => ({
write: spy()
});

test('set up stdin to emit keypress events', t => {
const Test = () => 'Test';

const stdin = createStdin();
const stdout = createStdout();
const unmount = render(<Test/>, {stdin, stdout});

t.true(stdin.setRawMode.calledOnce);
t.deepEqual(stdin.setRawMode.firstCall.args, [true]);
t.deepEqual(stdin.eventNames(), ['newListener']);

unmount();

t.true(stdin.setRawMode.calledTwice);
t.deepEqual(stdin.setRawMode.secondCall.args, [false]);
});

test('update output', t => {
class Test extends Component {
constructor(props) {
Expand All @@ -27,20 +56,21 @@ test('update output', t => {
component = ref;
};

const stream = {write: spy()};
render(<Test ref={setRef}/>, stream);
const stdin = createStdin();
const stdout = createStdout();
render(<Test ref={setRef}/>, {stdin, stdout});

t.true(stream.write.calledOnce);
t.is(stripOutput(stream.write.firstCall.args[0]), '0');
t.true(stdout.write.calledOnce);
t.is(stripOutput(stdout.write.firstCall.args[0]), '0');

component.setState({
i: 1
});

rerender();

t.true(stream.write.calledTwice);
t.is(stripOutput(stream.write.secondCall.args[0]), '1');
t.true(stdout.write.calledTwice);
t.is(stripOutput(stdout.write.secondCall.args[0]), '1');
});

test('unmount', t => {
Expand All @@ -60,11 +90,12 @@ test('unmount', t => {

spy(Test.prototype, 'componentWillUnmount');

const stream = {write: spy()};
const unmount = render(<Test/>, stream);
const stdin = createStdin();
const stdout = createStdout();
const unmount = render(<Test/>, {stdin, stdout});

t.true(stream.write.calledOnce);
t.is(stripOutput(stream.write.firstCall.args[0]), '0');
t.true(stdout.write.calledOnce);
t.is(stripOutput(stdout.write.firstCall.args[0]), '0');

unmount();

Expand All @@ -90,11 +121,12 @@ test('ignore updates when unmounted', t => {
}
}

const stream = {write: spy()};
const unmount = render(<Test/>, stream);
const stdin = createStdin();
const stdout = createStdout();
const unmount = render(<Test/>, {stdin, stdout});

t.true(stream.write.calledOnce);
t.is(stripOutput(stream.write.firstCall.args[0]), '0');
t.true(stdout.write.calledOnce);
t.is(stripOutput(stdout.write.firstCall.args[0]), '0');

unmount();

Expand All @@ -104,5 +136,5 @@ test('ignore updates when unmounted', t => {

rerender();

t.true(stream.write.calledOnce);
t.true(stdout.write.calledOnce);
});

0 comments on commit 696d0fb

Please sign in to comment.