From cfe0bab85b8b0974c3683c434fa33663e0b02906 Mon Sep 17 00:00:00 2001 From: Yazhong Liu Date: Wed, 22 Jan 2014 09:53:23 +0800 Subject: [PATCH] readline: fix `line` event, if input emit 'end' If an input stream would emit `end` event, like `fs.createReadStream`, then readline need to get the last line correctly even though that line isnt ended with `\n`. --- lib/readline.js | 8 ++++++++ test/simple/test-readline-interface.js | 22 +++++++++++++++++++++- test/simple/test-readline-set-raw-mode.js | 3 +-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/readline.js b/lib/readline.js index 1872e852bd..c5d04b977a 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -91,6 +91,9 @@ function Interface(input, output, completer, terminal) { } function onend() { + if (util.isString(self._line_buffer) && self._line_buffer.length > 0) { + self.emit('line', self._line_buffer); + } self.close(); } @@ -118,6 +121,11 @@ function Interface(input, output, completer, terminal) { // input usually refers to stdin input.on('keypress', onkeypress); + input.on('end', function inputEnd() { + if (util.isString(self.line) && self.line.length > 0) + self.emit('line', self.line); + self.close(); + }); // Current line this.line = ''; diff --git a/test/simple/test-readline-interface.js b/test/simple/test-readline-interface.js index ec4ce9d351..d88f64a4e2 100644 --- a/test/simple/test-readline-interface.js +++ b/test/simple/test-readline-interface.js @@ -113,6 +113,27 @@ FakeInput.prototype.end = function() {}; assert.equal(callCount, expectedLines.length - 1); rli.close(); + // sending multiple newlines at once that does not end with a new(empty) + // line and a `end` event + fi = new FakeInput(); + rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); + expectedLines = ['foo', 'bar', 'baz', '']; + callCount = 0; + rli.on('line', function(line) { + assert.equal(line, expectedLines[callCount]); + callCount++; + }); + rli.on('close', function() { + callCount++; + }) + fi.emit('data', expectedLines.join('\n')); + fi.emit('end'); + assert.equal(callCount, expectedLines.length); + rli.close(); + + // sending multiple newlines at once that does not end with a new line + // and a `end` event(last line is) + // \r\n should emit one line event, not two fi = new FakeInput(); rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); @@ -214,6 +235,5 @@ FakeInput.prototype.end = function() {}; assert.equal(readline.getStringWidth('\u001b[31m\u001b[39m'), 0); assert.equal(readline.getStringWidth('> '), 2); - assert.deepEqual(fi.listeners('end'), []); assert.deepEqual(fi.listeners(terminal ? 'keypress' : 'data'), []); }); diff --git a/test/simple/test-readline-set-raw-mode.js b/test/simple/test-readline-set-raw-mode.js index 5bca5272cc..f43443857b 100644 --- a/test/simple/test-readline-set-raw-mode.js +++ b/test/simple/test-readline-set-raw-mode.js @@ -49,7 +49,7 @@ var rli = readline.createInterface({ output: stream, terminal: true }); -assert(rli.terminal) +assert(rli.terminal); assert(rawModeCalled); assert(resumeCalled); assert(!pauseCalled); @@ -85,7 +85,6 @@ assert(rawModeCalled); assert(!resumeCalled); assert(pauseCalled); -assert.deepEqual(stream.listeners('end'), []); assert.deepEqual(stream.listeners('keypress'), []); // one data listener for the keypress events. assert.equal(stream.listeners('data').length, 1);