From 24303d7000d2b2b0b135db6c2fb689ad3b670fdc Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 17:48:05 +0000 Subject: [PATCH 01/16] document test deps --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index db96034..e2bab4b 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,13 @@ A simple way to run Python scripts from Node.js with basic but efficient inter-p npm install python-shell ``` +## Testing + +`Mocha` testrunner is required: +```bash +npm install -g mocha +``` + To run the tests: ```bash npm test From d220019c5ad32ff9f385bd3289d9381f94d9b047 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 17:48:43 +0000 Subject: [PATCH 02/16] Revert "document test deps" This reverts commit 24303d7000d2b2b0b135db6c2fb689ad3b670fdc. --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index e2bab4b..db96034 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,6 @@ A simple way to run Python scripts from Node.js with basic but efficient inter-p npm install python-shell ``` -## Testing - -`Mocha` testrunner is required: -```bash -npm install -g mocha -``` - To run the tests: ```bash npm test From cf409911c42335074017431315680fefcbc59701 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:01:20 +0000 Subject: [PATCH 03/16] Make conceptual humorous conversation --- test/python/conversation.py | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/python/conversation.py diff --git a/test/python/conversation.py b/test/python/conversation.py new file mode 100644 index 0000000..59a0cdd --- /dev/null +++ b/test/python/conversation.py @@ -0,0 +1,40 @@ +import sys, json + +def makeError(reason): + return { + action: 'error', + reason: reason + } + +def handleKnockKnock(obj): + response = { + action: 'knockknockjoke' + }; + + phase = obj.phase; + if (phase == 'Knock, knock.'): + response.message = "Who's there?" + return response; + + if (phase == 'Orange.'): + response.message = "Orange who?" + return response; + + if (phase == "Orange you glad I didn't say, 'banana'?"): + response.message = "Ha ha." + return response; + + return makeError('Unrecognised knock-knock phase.') + +def handleAction(obj): + action = obj.action + if action == 'knockknockjoke': + return handleKnockKnock(obj) + + return makeError("Unrecognised action: {0}".format(action)) + +# simple JSON echo script +for line in sys.stdin: + parsed = json.loads(line) + response = handleAction(parsed) + print json.dumps(response) From 32e445aa3f51d667e01dae95a6bfaf31b9f94462 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:07:14 +0000 Subject: [PATCH 04/16] Group unit tests into contexts --- test/test-python-shell.js | 82 +++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 4898617..6718a5e 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -63,32 +63,52 @@ describe('PythonShell', function () { }); describe('.send(message)', function () { - it('should send string messages when mode is "text"', function (done) { - var pyshell = new PythonShell('echo_text.py', { - mode: 'text' - }); - var output = ''; - pyshell.stdout.on('data', function (data) { - output += ''+data; - }); - pyshell.send('hello').send('world').end(function (err) { - if (err) return done(err); - output.should.be.exactly('hello\nworld\n'); - done(); + context('text mode', function() { + it('should send string messages', function (done) { + var pyshell = new PythonShell('echo_text.py', { + mode: 'text' + }); + var output = ''; + pyshell.stdout.on('data', function (data) { + output += ''+data; + }); + pyshell.send('hello').send('world').end(function (err) { + if (err) return done(err); + output.should.be.exactly('hello\nworld\n'); + done(); + }); + }); + }) + context('JSON mode', function() { + it('should send JSON messages', function (done) { + var pyshell = new PythonShell('echo_json.py', { + mode: 'json' + }); + var output = ''; + pyshell.stdout.on('data', function (data) { + output += ''+data; + }); + pyshell.send({ a: 'b' }).send(null).send([1, 2, 3]).end(function (err) { + if (err) return done(err); + output.should.be.exactly('{"a": "b"}\nnull\n[1, 2, 3]\n'); + done(); + }); }); }); - it('should send JSON messages when mode is "json"', function (done) { - var pyshell = new PythonShell('echo_json.py', { - mode: 'json' - }); - var output = ''; - pyshell.stdout.on('data', function (data) { - output += ''+data; - }); - pyshell.send({ a: 'b' }).send(null).send([1, 2, 3]).end(function (err) { - if (err) return done(err); - output.should.be.exactly('{"a": "b"}\nnull\n[1, 2, 3]\n'); - done(); + context('binary mode', function() { + it('should write as-is', function (done) { + var pyshell = new PythonShell('echo_binary.py', { + mode: 'binary' + }); + var output = ''; + pyshell.stdout.on('data', function (data) { + output += ''+data; + }); + pyshell.send(new Buffer('i am not a string')).end(function (err) { + if (err) return done(err); + output.should.be.exactly('i am not a string'); + done(); + }); }); }); it('should use a custom formatter', function (done) { @@ -107,20 +127,6 @@ describe('PythonShell', function () { done(); }); }); - it('should write as-is when mode is "binary"', function (done) { - var pyshell = new PythonShell('echo_binary.py', { - mode: 'binary' - }); - var output = ''; - pyshell.stdout.on('data', function (data) { - output += ''+data; - }); - pyshell.send(new Buffer('i am not a string')).end(function (err) { - if (err) return done(err); - output.should.be.exactly('i am not a string'); - done(); - }); - }); }); describe('.receive(data)', function () { From d0937debcedd436431f3bba3761f996ee7ba5642 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:28:57 +0000 Subject: [PATCH 05/16] fix JSON syntax in conversation.py, modularize further, handle more types of unexpected input --- test/python/conversation.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/test/python/conversation.py b/test/python/conversation.py index 59a0cdd..ee18828 100644 --- a/test/python/conversation.py +++ b/test/python/conversation.py @@ -1,17 +1,24 @@ import sys, json +def is_json(myjson): + try: + json_object = json.loads(myjson) + except ValueError, e: + return False + return True + def makeError(reason): return { - action: 'error', - reason: reason + 'action': 'error', + 'reason': reason } def handleKnockKnock(obj): response = { - action: 'knockknockjoke' + 'action': 'knockknockjoke' }; - phase = obj.phase; + phase = obj['phase']; if (phase == 'Knock, knock.'): response.message = "Who's there?" return response; @@ -27,14 +34,28 @@ def handleKnockKnock(obj): return makeError('Unrecognised knock-knock phase.') def handleAction(obj): - action = obj.action + if 'action' not in obj: + return makeError("Unsupported input; expected 'action' key.") + + action = obj['action'] if action == 'knockknockjoke': return handleKnockKnock(obj) return makeError("Unrecognised action: {0}".format(action)) +def handleLine(line): + if not is_json(line): + return makeError('Malformed input could not be parsed as JSON: {0}'.format(line)) + + parsed = json.loads(line) + + if type (parsed) != type({}): + return makeError('Malformed input: expected JSON object; received JSON primitive instead: {0}'.format(parsed)) + + return handleAction(parsed) + # simple JSON echo script for line in sys.stdin: - parsed = json.loads(line) - response = handleAction(parsed) + response = handleLine(line) + print json.dumps(response) From 1aab1afea3cfc6c168033746bbe301e40ccaf23e Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:29:05 +0000 Subject: [PATCH 06/16] start writing conversation test --- test/test-python-shell.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 6718a5e..df10502 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -94,6 +94,28 @@ describe('PythonShell', function () { done(); }); }); + it.only('holds a conversation', function (done) { + var pyshell = new PythonShell('conversation.py', { + mode: 'json' + }); + var output = ''; + pyshell.stdout.on('data', function (data) { + output += ''+data; + }); + pyshell + .send({ a: 'b' }) + .send(null) + .send([1, 2, 3]) + .end(function (err) { + if (err) { + return done(err); + } + outputs = output.split('\n'); + output[0].should.be.exactly(); + output.should.be.exactly('{"a": "b"}\nnull\n[1, 2, 3]\n'); + done(); + }); + }); }); context('binary mode', function() { it('should write as-is', function (done) { From 90334f84f2c014393d57b67e10c702dc3e73f911 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:29:55 +0000 Subject: [PATCH 07/16] add lodash to help with unit test assertions --- package.json | 3 ++- test/test-python-shell.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d0108f7..71f3a7c 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "dependencies": {}, "devDependencies": { "should": "^6.0.0", - "mocha": "^2.2.5" + "mocha": "^2.2.5", + "lodash": "^3.10.1" }, "repository": { "type": "git", diff --git a/test/test-python-shell.js b/test/test-python-shell.js index df10502..e039840 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -1,4 +1,5 @@ var should = require('should'); +var _ = require('lodash'); var PythonShell = require('..'); describe('PythonShell', function () { From 36f85983c6d730d551fadb82b25b713d690b592a Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 18:33:40 +0000 Subject: [PATCH 08/16] Revert "add lodash to help with unit test assertions" This reverts commit 90334f84f2c014393d57b67e10c702dc3e73f911. --- package.json | 3 +-- test/test-python-shell.js | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 71f3a7c..d0108f7 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,7 @@ "dependencies": {}, "devDependencies": { "should": "^6.0.0", - "mocha": "^2.2.5", - "lodash": "^3.10.1" + "mocha": "^2.2.5" }, "repository": { "type": "git", diff --git a/test/test-python-shell.js b/test/test-python-shell.js index e039840..df10502 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -1,5 +1,4 @@ var should = require('should'); -var _ = require('lodash'); var PythonShell = require('..'); describe('PythonShell', function () { From 1d4f266cc83a8aa784d5cd108a65a3c32fbb4394 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 21:13:38 +0000 Subject: [PATCH 09/16] Not sure why can't multi-message --- test/python/conversation.py | 14 +++--- test/test-python-shell.js | 90 ++++++++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/test/python/conversation.py b/test/python/conversation.py index ee18828..878e7ac 100644 --- a/test/python/conversation.py +++ b/test/python/conversation.py @@ -18,17 +18,17 @@ def handleKnockKnock(obj): 'action': 'knockknockjoke' }; - phase = obj['phase']; - if (phase == 'Knock, knock.'): - response.message = "Who's there?" + message = obj['message']; + if (message == 'Knock, knock.'): + response['message'] = "Who's there?" return response; - if (phase == 'Orange.'): - response.message = "Orange who?" + if (message == 'Orange.'): + response['message'] = "Orange who?" return response; - if (phase == "Orange you glad I didn't say, 'banana'?"): - response.message = "Ha ha." + if (message == "Orange you glad I didn't say, 'banana'?"): + response['message'] = "Ha ha." return response; return makeError('Unrecognised knock-knock phase.') diff --git a/test/test-python-shell.js b/test/test-python-shell.js index df10502..7b68573 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -1,5 +1,6 @@ var should = require('should'); var PythonShell = require('..'); +var util = require('util'); describe('PythonShell', function () { @@ -99,22 +100,89 @@ describe('PythonShell', function () { mode: 'json' }); var output = ''; - pyshell.stdout.on('data', function (data) { - output += ''+data; + + function makeKnockKnockMessage(message) { + return { + action: 'knockknockjoke', + message: message + }; + } + + var makeKnockKnockReply = makeKnockKnockMessage; + + function handleReply(reply) { + switch(reply.message) { + case "Who's there?": + pyshell.send(makeKnockKnockMessage('Orange.')); + break; + case "Orange who?": + pyshell.send(makeKnockKnockMessage("Orange you glad I didn't say, 'banana'?")); + break; + case "Ha ha.": + endAndAssert(); + break; + } + + endAndAssert(); + } + + pyshell.on('message', function (message) { + output += ''+message; + + console.log("Data to stdout: ", message); + + switch(message.action) { + case 'knockknockjoke': + handleReply(message); + break; + default: + done(util.format("Unexpected action: '%s'", data.action)) + } }); - pyshell - .send({ a: 'b' }) - .send(null) - .send([1, 2, 3]) - .end(function (err) { + + pyshell.on('close', function(err) { if (err) { return done(err); } - outputs = output.split('\n'); - output[0].should.be.exactly(); - output.should.be.exactly('{"a": "b"}\nnull\n[1, 2, 3]\n'); - done(); + return done('Unexpectedly closed.'); }); + pyshell.send(makeKnockKnockMessage('Knock, knock.')); + // endAndAssert(); + + function endAndAssert() { + pyshell.end(function (err) { + if (err) { + return done(err); + } + var outputs = output.split("\n"); + + var parsedOutputs = []; + outputs + .slice(0, 3) + .forEach(function(outputRaw) { + try { + var parsed = JSON.parse(outputRaw); + parsedOutputs.push(parsed); + } catch(err) { + done(err); + } + }); + + should(parsedOutputs[0]) + .eql(makeKnockKnockReply("Who's there?"), + "Correct knock-knock reply received."); + + should(parsedOutputs[1]) + .eql(makeKnockKnockReply("Orange who?"), + "Correct knock-knock reply received."); + + should(parsedOutputs[2]) + .eql(makeKnockKnockReply("Ha ha."), + "Correct knock-knock reply received."); + + done(); + }); + } }); }); context('binary mode', function() { From 78a031c91ca26b79085d99d5c4a21bac9a83a3e2 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:04:28 +0000 Subject: [PATCH 10/16] Add various flushing, yielding. didn't help. --- index.js | 9 +++++++ test/python/conversation.py | 10 ++++++- test/test-python-shell.js | 54 ++++++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index a632b6a..2033aed 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ var EventEmitter = require('events').EventEmitter; var path = require('path'); var util = require('util'); +var os = require('os'); var spawn = require('child_process').spawn; function toArray(source) { @@ -185,10 +186,16 @@ PythonShell.prototype.parseError = function (data) { PythonShell.prototype.send = function (message) { var data = this.formatter ? this.formatter(message) : message; if (this.mode !== 'binary') data += '\n'; + console.log('writing to stdin: ', data); this.stdin.write(data); return this; }; +PythonShell.prototype.flushInput = function (message) { + this.stdin.write(os.EOL); + return this; +}; + /** * Parses data received from the Python shell stdout stream and emits "message" events * This method is not used in binary mode @@ -196,6 +203,8 @@ PythonShell.prototype.send = function (message) { * @param {string|Buffer} data The data to parse into messages */ PythonShell.prototype.receive = function (data) { + console.log('received: ',data) + var self = this; var parts = (''+data).split(/\n/g); diff --git a/test/python/conversation.py b/test/python/conversation.py index 878e7ac..da88f5c 100644 --- a/test/python/conversation.py +++ b/test/python/conversation.py @@ -1,4 +1,6 @@ -import sys, json +import sys, json, time + +ended = False def is_json(myjson): try: @@ -8,6 +10,7 @@ def is_json(myjson): return True def makeError(reason): + ended = True return { 'action': 'error', 'reason': reason @@ -29,6 +32,7 @@ def handleKnockKnock(obj): if (message == "Orange you glad I didn't say, 'banana'?"): response['message'] = "Ha ha." + ended = True return response; return makeError('Unrecognised knock-knock phase.') @@ -55,7 +59,11 @@ def handleLine(line): return handleAction(parsed) # simple JSON echo script +# while not ended: +# line = sys.stdin.read() for line in sys.stdin: response = handleLine(line) print json.dumps(response) + sys.stdout.flush() + time.sleep(1) \ No newline at end of file diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 7b68573..91f5a3f 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -1,6 +1,7 @@ var should = require('should'); var PythonShell = require('..'); var util = require('util'); +var os = require("os"); describe('PythonShell', function () { @@ -113,10 +114,14 @@ describe('PythonShell', function () { function handleReply(reply) { switch(reply.message) { case "Who's there?": + // awaitReply(); pyshell.send(makeKnockKnockMessage('Orange.')); + flushStdIn(); break; case "Orange who?": + // awaitReply(); pyshell.send(makeKnockKnockMessage("Orange you glad I didn't say, 'banana'?")); + flushStdIn(); break; case "Ha ha.": endAndAssert(); @@ -126,19 +131,37 @@ describe('PythonShell', function () { endAndAssert(); } - pyshell.on('message', function (message) { - output += ''+message; + // function awaitReply() { + pyshell.stdout.on('data', function (data) { + output += ''+data; - console.log("Data to stdout: ", message); + console.log("Data to stdout: ", data); - switch(message.action) { - case 'knockknockjoke': - handleReply(message); - break; - default: - done(util.format("Unexpected action: '%s'", data.action)) - } - }); + switch(data.action) { + case 'knockknockjoke': + handleReply(data); + break; + default: + done(util.format("Unexpected action: '%s'", data.action)) + } + }); + // } + + // function awaitReply() { + // pyshell.stdout.once('data', function (data) { + // output += ''+data; + + // console.log("Data to stdout: ", data); + + // switch(data.action) { + // case 'knockknockjoke': + // handleReply(data); + // break; + // default: + // done(util.format("Unexpected action: '%s'", data.action)) + // } + // }); + // } pyshell.on('close', function(err) { if (err) { @@ -146,8 +169,15 @@ describe('PythonShell', function () { } return done('Unexpectedly closed.'); }); + // awaitReply(); pyshell.send(makeKnockKnockMessage('Knock, knock.')); - // endAndAssert(); + flushStdIn(); + + function flushStdIn() { + // pyshell.stdin.write(os.EOF); + // pyshell.pauseInput(); + pyshell.flushInput(); + } function endAndAssert() { pyshell.end(function (err) { From feaf8a9f3f36cdae5857358ab0b3c4d74b6f305e Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:32:15 +0000 Subject: [PATCH 11/16] things continued to not help --- index.js | 7 ++++++- test/python/conversation.py | 6 +++++- test/test-python-shell.js | 10 ++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 2033aed..91e95c5 100644 --- a/index.js +++ b/index.js @@ -191,8 +191,13 @@ PythonShell.prototype.send = function (message) { return this; }; +PythonShell.prototype.pauseInput = function (message) { + this.stdin.pause(); + return this; +}; + PythonShell.prototype.flushInput = function (message) { - this.stdin.write(os.EOL); + // this.stdin.write(os.EOL); return this; }; diff --git a/test/python/conversation.py b/test/python/conversation.py index da88f5c..8742639 100644 --- a/test/python/conversation.py +++ b/test/python/conversation.py @@ -65,5 +65,9 @@ def handleLine(line): response = handleLine(line) print json.dumps(response) + # print json.dumps({ + # 'action':'knockknockjoke', + # 'message': "Who's there?" + # }) sys.stdout.flush() - time.sleep(1) \ No newline at end of file + # time.sleep(1) \ No newline at end of file diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 91f5a3f..7070828 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -145,6 +145,8 @@ describe('PythonShell', function () { done(util.format("Unexpected action: '%s'", data.action)) } }); + + pyshell.stdout.resume(); // } // function awaitReply() { @@ -163,6 +165,10 @@ describe('PythonShell', function () { // }); // } + pyshell.stderr.on('data', function(err) { + console.error(err); + }); + pyshell.on('close', function(err) { if (err) { return done(err); @@ -175,8 +181,8 @@ describe('PythonShell', function () { function flushStdIn() { // pyshell.stdin.write(os.EOF); - // pyshell.pauseInput(); - pyshell.flushInput(); + pyshell.pauseInput(); + // pyshell.flushInput(); } function endAndAssert() { From 0464d7c5a30bb3b2cf3cc1875b5e7c275ddf7779 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:49:18 +0000 Subject: [PATCH 12/16] finally flushing --- index.js | 10 ----- test/python/conversation.py | 16 ++++---- test/test-python-shell.js | 75 ++++++++++++++++--------------------- 3 files changed, 40 insertions(+), 61 deletions(-) diff --git a/index.js b/index.js index 91e95c5..a7faade 100644 --- a/index.js +++ b/index.js @@ -191,16 +191,6 @@ PythonShell.prototype.send = function (message) { return this; }; -PythonShell.prototype.pauseInput = function (message) { - this.stdin.pause(); - return this; -}; - -PythonShell.prototype.flushInput = function (message) { - // this.stdin.write(os.EOL); - return this; -}; - /** * Parses data received from the Python shell stdout stream and emits "message" events * This method is not used in binary mode diff --git a/test/python/conversation.py b/test/python/conversation.py index 8742639..9b03a05 100644 --- a/test/python/conversation.py +++ b/test/python/conversation.py @@ -59,15 +59,13 @@ def handleLine(line): return handleAction(parsed) # simple JSON echo script -# while not ended: -# line = sys.stdin.read() -for line in sys.stdin: +while not ended: + line = sys.stdin.readline() + if not line: + break +# for line in sys.stdin: + response = handleLine(line) print json.dumps(response) - # print json.dumps({ - # 'action':'knockknockjoke', - # 'message': "Who's there?" - # }) - sys.stdout.flush() - # time.sleep(1) \ No newline at end of file + sys.stdout.flush() \ No newline at end of file diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 7070828..101c9c3 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -100,7 +100,7 @@ describe('PythonShell', function () { var pyshell = new PythonShell('conversation.py', { mode: 'json' }); - var output = ''; + var outputs = []; function makeKnockKnockMessage(message) { return { @@ -109,21 +109,31 @@ describe('PythonShell', function () { }; } + var outgoingMessages = [ + "Knock, knock.", + "Orange.", + "Orange you glad I didn't say, 'banana'?" + ]; + + var incomingMessages = [ + "Who's there?", + "Orange who?", + "Ha ha." + ]; + var makeKnockKnockReply = makeKnockKnockMessage; function handleReply(reply) { switch(reply.message) { - case "Who's there?": + case incomingMessages[0]: // awaitReply(); - pyshell.send(makeKnockKnockMessage('Orange.')); - flushStdIn(); + pyshell.send(makeKnockKnockMessage(outgoingMessages[1])); break; - case "Orange who?": + case incomingMessages[1]: // awaitReply(); - pyshell.send(makeKnockKnockMessage("Orange you glad I didn't say, 'banana'?")); - flushStdIn(); + pyshell.send(makeKnockKnockMessage(outgoingMessages[2])); break; - case "Ha ha.": + case incomingMessages[2]: endAndAssert(); break; } @@ -132,11 +142,11 @@ describe('PythonShell', function () { } // function awaitReply() { - pyshell.stdout.on('data', function (data) { - output += ''+data; - + pyshell.on('message', function (data) { console.log("Data to stdout: ", data); + outputs.push(data); + switch(data.action) { case 'knockknockjoke': handleReply(data); @@ -146,7 +156,7 @@ describe('PythonShell', function () { } }); - pyshell.stdout.resume(); + // pyshell.stdout.resume(); // } // function awaitReply() { @@ -165,9 +175,9 @@ describe('PythonShell', function () { // }); // } - pyshell.stderr.on('data', function(err) { - console.error(err); - }); + // pyshell.stderr.on('data', function(err) { + // console.error(err); + // }); pyshell.on('close', function(err) { if (err) { @@ -176,44 +186,25 @@ describe('PythonShell', function () { return done('Unexpectedly closed.'); }); // awaitReply(); - pyshell.send(makeKnockKnockMessage('Knock, knock.')); - flushStdIn(); - - function flushStdIn() { - // pyshell.stdin.write(os.EOF); - pyshell.pauseInput(); - // pyshell.flushInput(); - } + pyshell.send(makeKnockKnockMessage(outgoingMessages[0])); function endAndAssert() { pyshell.end(function (err) { if (err) { return done(err); } - var outputs = output.split("\n"); - - var parsedOutputs = []; - outputs - .slice(0, 3) - .forEach(function(outputRaw) { - try { - var parsed = JSON.parse(outputRaw); - parsedOutputs.push(parsed); - } catch(err) { - done(err); - } - }); + console.log(outputs); - should(parsedOutputs[0]) - .eql(makeKnockKnockReply("Who's there?"), + should(outputs[0]) + .eql(makeKnockKnockReply(incomingMessages[0]), "Correct knock-knock reply received."); - should(parsedOutputs[1]) - .eql(makeKnockKnockReply("Orange who?"), + should(outputs[1]) + .eql(makeKnockKnockReply(incomingMessages[1]), "Correct knock-knock reply received."); - should(parsedOutputs[2]) - .eql(makeKnockKnockReply("Ha ha."), + should(outputs[2]) + .eql(makeKnockKnockReply(incomingMessages[1]), "Correct knock-knock reply received."); done(); From 9f65b404cd3328f1a07a6025c4949598980a17a1 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:52:54 +0000 Subject: [PATCH 13/16] put back to normal --- index.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/index.js b/index.js index a7faade..18ade3c 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ var EventEmitter = require('events').EventEmitter; var path = require('path'); var util = require('util'); -var os = require('os'); var spawn = require('child_process').spawn; function toArray(source) { @@ -186,7 +185,6 @@ PythonShell.prototype.parseError = function (data) { PythonShell.prototype.send = function (message) { var data = this.formatter ? this.formatter(message) : message; if (this.mode !== 'binary') data += '\n'; - console.log('writing to stdin: ', data); this.stdin.write(data); return this; }; @@ -198,8 +196,6 @@ PythonShell.prototype.send = function (message) { * @param {string|Buffer} data The data to parse into messages */ PythonShell.prototype.receive = function (data) { - console.log('received: ',data) - var self = this; var parts = (''+data).split(/\n/g); @@ -239,4 +235,4 @@ PythonShell.prototype.end = function (callback) { return this; }; -module.exports = PythonShell; +module.exports = PythonShell; \ No newline at end of file From b22ac2b13def7708d8c0ae78bd1676082afe6c33 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:53:05 +0000 Subject: [PATCH 14/16] remove unused, fix double-end of test --- test/test-python-shell.js | 67 +++++++++------------------------------ 1 file changed, 15 insertions(+), 52 deletions(-) diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 101c9c3..3c433e7 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -100,7 +100,7 @@ describe('PythonShell', function () { var pyshell = new PythonShell('conversation.py', { mode: 'json' }); - var outputs = []; + var receivedMessages = []; function makeKnockKnockMessage(message) { return { @@ -126,66 +126,29 @@ describe('PythonShell', function () { function handleReply(reply) { switch(reply.message) { case incomingMessages[0]: - // awaitReply(); pyshell.send(makeKnockKnockMessage(outgoingMessages[1])); break; case incomingMessages[1]: - // awaitReply(); pyshell.send(makeKnockKnockMessage(outgoingMessages[2])); break; case incomingMessages[2]: endAndAssert(); break; } - - endAndAssert(); } - // function awaitReply() { - pyshell.on('message', function (data) { - console.log("Data to stdout: ", data); + pyshell.on('message', function (message) { + receivedMessages.push(message); - outputs.push(data); - - switch(data.action) { - case 'knockknockjoke': - handleReply(data); - break; - default: - done(util.format("Unexpected action: '%s'", data.action)) - } - }); - - // pyshell.stdout.resume(); - // } - - // function awaitReply() { - // pyshell.stdout.once('data', function (data) { - // output += ''+data; - - // console.log("Data to stdout: ", data); - - // switch(data.action) { - // case 'knockknockjoke': - // handleReply(data); - // break; - // default: - // done(util.format("Unexpected action: '%s'", data.action)) - // } - // }); - // } - - // pyshell.stderr.on('data', function(err) { - // console.error(err); - // }); - - pyshell.on('close', function(err) { - if (err) { - return done(err); + switch(message.action) { + case 'knockknockjoke': + handleReply(message); + break; + default: + done(util.format("Unexpected action: '%s'", data.action)) } - return done('Unexpectedly closed.'); }); - // awaitReply(); + pyshell.send(makeKnockKnockMessage(outgoingMessages[0])); function endAndAssert() { @@ -193,18 +156,18 @@ describe('PythonShell', function () { if (err) { return done(err); } - console.log(outputs); + console.log(receivedMessages); - should(outputs[0]) + should(receivedMessages[0]) .eql(makeKnockKnockReply(incomingMessages[0]), "Correct knock-knock reply received."); - should(outputs[1]) + should(receivedMessages[1]) .eql(makeKnockKnockReply(incomingMessages[1]), "Correct knock-knock reply received."); - should(outputs[2]) - .eql(makeKnockKnockReply(incomingMessages[1]), + should(receivedMessages[2]) + .eql(makeKnockKnockReply(incomingMessages[2]), "Correct knock-knock reply received."); done(); From a49473f4867fc10d7c6392cbbc58d2829c51e49d Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:54:12 +0000 Subject: [PATCH 15/16] enable other tests again --- test/test-python-shell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 3c433e7..0d20d74 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -96,7 +96,7 @@ describe('PythonShell', function () { done(); }); }); - it.only('holds a conversation', function (done) { + it('holds a conversation', function (done) { var pyshell = new PythonShell('conversation.py', { mode: 'json' }); From 9d8641dc1e55e808ba82d029f9920413ab63206f Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Sun, 15 Nov 2015 22:54:35 +0000 Subject: [PATCH 16/16] remove tracing --- test/test-python-shell.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test-python-shell.js b/test/test-python-shell.js index 0d20d74..19479f6 100644 --- a/test/test-python-shell.js +++ b/test/test-python-shell.js @@ -156,7 +156,6 @@ describe('PythonShell', function () { if (err) { return done(err); } - console.log(receivedMessages); should(receivedMessages[0]) .eql(makeKnockKnockReply(incomingMessages[0]),