Skip to content

Commit

Permalink
feat: support prompt (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 authored and popomore committed Aug 1, 2018
1 parent 91d05b4 commit b0e16e0
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 177 deletions.
36 changes: 36 additions & 0 deletions README.md
Expand Up @@ -94,6 +94,42 @@ The opposite assertion of `expect`.

Write data to stdin, see example above.

#### coffee.waitForPrompt(bool)

If you set false, coffee will write stdin immediately, otherwise will wait for `prompt` message.

```js
coffee.fork('/path/to/cli', ['abcdefg'])
.waitForPrompt()
.write('tz\n')
.write('2\n');
.end(done);
```

cli process should emit `prompt` message:

```js
const readline = require('readline');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

function ask(q, callback) {
process.send({ type: 'prompt' });
rl.question(q, callback);
}

ask('What\'s your name? ', answer => {
console.log(`hi, ${answer}`);
ask('How many coffee do you want? ', answer => {
console.log(`here is your ${answer} coffee`);
rl.close();
});
});
```

#### coffee.end(callback)

Callback will be called after completing the assertion, the first argument is Error if throw exception.
Expand Down
41 changes: 31 additions & 10 deletions lib/coffee.js
Expand Up @@ -148,12 +148,20 @@ class Coffee extends EventEmitter {
return this;
}

/*
Write data to stdin of the command
*/
write(value) {

/**
* Write data to stdin of the command
* @param {String} input - input text
* @return {Coffee} return self for chain
*/
write(input) {
assert(!this._isEndCalled, 'can\'t call write after end');
this.stdin.push(value);
this.stdin.push(input);
return this;
}

waitForPrompt(enable) {
this._isWaitForPrompt = enable !== false;
return this;
}

Expand Down Expand Up @@ -211,11 +219,23 @@ class Coffee extends EventEmitter {
cmd.once('close', this.emit.bind(this, 'close'));

if (this.stdin.length) {
this.stdin.forEach(function(buf) {
debug('input stdin `%s`', show(buf));
cmd.stdin.write(buf);
});
cmd.stdin.end();
if (this._isWaitForPrompt) {
// wait for message then write to stdin
cmd.on('message', msg => {
if (msg.type !== 'prompt' || this.stdin.length === 0) return;
const buf = this.stdin.shift();
debug('prompt stdin `%s`', show(buf));
cmd.stdin.write(buf);
if (this.stdin.length === 0) cmd.stdin.end();
});
} else {
// write immediately
this.stdin.forEach(function(buf) {
debug('input stdin `%s`', show(buf));
cmd.stdin.write(buf);
});
cmd.stdin.end();
}
}

return this;
Expand All @@ -240,6 +260,7 @@ class Coffee extends EventEmitter {
};
this.complete = false;
this._isEndCalled = false;
this._isWaitForPrompt = false;
this._debug_stdout = false;
this._debug_stderr = false;
this._isCoverage = true;
Expand Down
10 changes: 5 additions & 5 deletions package.json
Expand Up @@ -4,15 +4,15 @@
"description": "Test command line on nodejs",
"main": "index.js",
"dependencies": {
"cross-spawn": "^5.1.0",
"debug": "^2.6.8"
"cross-spawn": "^6.0.5",
"debug": "^3.1.0"
},
"devDependencies": {
"autod": "^2.8.0",
"egg-ci": "^1.6.0",
"autod": "^3.0.1",
"egg-ci": "^1.8.0",
"eslint": "^3.19.0",
"eslint-config-egg": "^4.1.0",
"mm": "^2.1.0",
"mm": "^2.2.2",
"mocha": "2",
"nyc": "^11.0.2",
"spy": "^1.0.0"
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/prompt.js
@@ -0,0 +1,24 @@
#!/usr/bin/env node

'use strict';

const readline = require('readline');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

ask('What\'s your name? ', answer => {
console.log(`hi, ${answer}`);
ask('How many coffee do you want? ', answer => {
console.log(`here is your ${answer} coffee`);
rl.close();
process.exit();
});
});

function ask(q, callback) {
process.send({ type: 'prompt' });
rl.question(q, callback);
}

0 comments on commit b0e16e0

Please sign in to comment.