From 50b74bdfadd18f0b155aed6c388940fff9c19250 Mon Sep 17 00:00:00 2001 From: Greg Cochard Date: Tue, 17 Jun 2014 09:24:14 -0700 Subject: [PATCH] Updating nexpect to emit events. Fixes #14 This allows nexpect to work with conditional branching. It will emit 'wait' right now, and the data will be the line of output which matches the expected output. From there, you can re-test the data and call sendline, expect, or wait again. Note that the user MUST call wait BEFORE the end of the stackframe on which the child was spawned. --- README.md | 19 +++++++++++++++++++ lib/nexpect.js | 16 +++++++++++++++- test/nexpect-test.js | 17 +++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5758ef0..2d32907 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,25 @@ Lets take a look at some sample usage: console.log(err) } }); + + emitter = nexpect.spawn("node --interactive") + .run(function (err) { + if (!err) { + console.log("node process started, console logged, process exited"); + } + else { + console.log(err) + } + }); + emitter.expect(">"); + emitter.on('wait',function(data){ + if(data === '>'){ + emitter.sendline("console.log('testing')") + .expect("testing") + } else if(data === 'testing') { + emitter.sendline("process.exit()") + } + }); ``` If you are looking for more examples take a look at the [examples][2], and [tests][3]. diff --git a/lib/nexpect.js b/lib/nexpect.js index 4d5db11..8ee29cf 100644 --- a/lib/nexpect.js +++ b/lib/nexpect.js @@ -8,6 +8,7 @@ var spawn = require('child_process').spawn; var util = require('util'); var AssertionError = require('assert').AssertionError; +var EventEmitter = require('events').EventEmitter; function chain (context) { return { @@ -36,6 +37,9 @@ function chain (context) { context.queue.push(_wait); return chain(context); }, + on: function() { + context.on.apply(this, arguments); + }, sendline: function (line) { var _sendline = function _sendline () { context.process.stdin.write(line + '\n'); @@ -146,6 +150,7 @@ function chain (context) { // If this is an `_expect` function, then evaluate it and attempt // to evaluate the next function (in case it is a `_sendline` function). // + context.emit('expect'); return currentFn(data) === true ? evalContext(data, '_expect') : onError(createExpectationError(currentFn.expectation, data), true); @@ -156,6 +161,7 @@ function chain (context) { // then evaluate the function (in case it is a `_sendline` function). // if (currentFn(data) === true) { + context.emit('wait',data); context.queue.shift(); evalContext(data, '_expect'); } @@ -295,7 +301,7 @@ function chain (context) { callback(null, stdout, signal || code); }); - return context.process; + return context; } }; } @@ -366,6 +372,14 @@ function nspawn (command, params, options) { stripColors: options.stripColors, verbose: options.verbose }; + _emitter = new EventEmitter(); + context._emitter = _emitter; + context.on = function(){ + _emitter.on.apply(_emitter,arguments); + }; + context.emit = function(){ + _emitter.emit.apply(_emitter,arguments); + }; return chain(context); } diff --git a/test/nexpect-test.js b/test/nexpect-test.js index 156bda6..f29e849 100644 --- a/test/nexpect-test.js +++ b/test/nexpect-test.js @@ -61,6 +61,23 @@ vows.describe('nexpect').addBatch({ .expect("testing") .sendline("process.exit()") ), + "and using the event driven method": { + "should respond with no error": function () { + child = nexpect.spawn('node', ['--interactive']); + child.run(function(err,stdout,exitcode){ + assert.isTrue(!err); + assert.isArray(stdout); + }); + child.on('wait',function(data){ + if(data === '>'){ + child.sendline('console.log("testing")').wait('testing'); + } else if (data === 'testing'){ + child.sendline('process.exit()'); + } + }); + child.wait('>'); + } + }, "and using the expect() method": { "when RegExp expectation is met": assertSpawn( nexpect.spawn("echo", ["hello"])