Browse Source

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`.
v0.11.12-release
Yazhong Liu 11 years ago
committed by Timothy J Fontaine
parent
commit
cfe0bab85b
  1. 8
      lib/readline.js
  2. 22
      test/simple/test-readline-interface.js
  3. 3
      test/simple/test-readline-set-raw-mode.js

8
lib/readline.js

@ -91,6 +91,9 @@ function Interface(input, output, completer, terminal) {
} }
function onend() { function onend() {
if (util.isString(self._line_buffer) && self._line_buffer.length > 0) {
self.emit('line', self._line_buffer);
}
self.close(); self.close();
} }
@ -118,6 +121,11 @@ function Interface(input, output, completer, terminal) {
// input usually refers to stdin // input usually refers to stdin
input.on('keypress', onkeypress); 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 // Current line
this.line = ''; this.line = '';

22
test/simple/test-readline-interface.js

@ -113,6 +113,27 @@ FakeInput.prototype.end = function() {};
assert.equal(callCount, expectedLines.length - 1); assert.equal(callCount, expectedLines.length - 1);
rli.close(); 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 // \r\n should emit one line event, not two
fi = new FakeInput(); fi = new FakeInput();
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); 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('\u001b[31m\u001b[39m'), 0);
assert.equal(readline.getStringWidth('> '), 2); assert.equal(readline.getStringWidth('> '), 2);
assert.deepEqual(fi.listeners('end'), []);
assert.deepEqual(fi.listeners(terminal ? 'keypress' : 'data'), []); assert.deepEqual(fi.listeners(terminal ? 'keypress' : 'data'), []);
}); });

3
test/simple/test-readline-set-raw-mode.js

@ -49,7 +49,7 @@ var rli = readline.createInterface({
output: stream, output: stream,
terminal: true terminal: true
}); });
assert(rli.terminal) assert(rli.terminal);
assert(rawModeCalled); assert(rawModeCalled);
assert(resumeCalled); assert(resumeCalled);
assert(!pauseCalled); assert(!pauseCalled);
@ -85,7 +85,6 @@ assert(rawModeCalled);
assert(!resumeCalled); assert(!resumeCalled);
assert(pauseCalled); assert(pauseCalled);
assert.deepEqual(stream.listeners('end'), []);
assert.deepEqual(stream.listeners('keypress'), []); assert.deepEqual(stream.listeners('keypress'), []);
// one data listener for the keypress events. // one data listener for the keypress events.
assert.equal(stream.listeners('data').length, 1); assert.equal(stream.listeners('data').length, 1);

Loading…
Cancel
Save