Skip to content
Browse files

readline: Remove event listeners on close

Fix #3756
  • Loading branch information...
1 parent febffc1 commit 2a7b226faf5c8252c6695da75b7cf3684b3cfb2b @isaacs committed Jul 23, 2012
Showing with 39 additions and 10 deletions.
  1. +26 −10 lib/readline.js
  2. +9 −0 test/simple/test-readline-interface.js
  3. +4 −0 test/simple/test-readline-set-raw-mode.js
View
36 lib/readline.js
@@ -86,12 +86,28 @@ function Interface(input, output, completer, terminal) {
this.terminal = !!terminal;
+ function ondata(data) {
+ self._normalWrite(data);
+ }
+
+ function onend() {
+ self.close();
+ }
+
+ function onkeypress(s, key) {
+ self._ttyWrite(s, key);
+ }
+
+ function onresize() {
+ self._refreshLine();
+ }
+
if (!this.terminal) {
- input.on('data', function(data) {
- self._normalWrite(data);
- });
- input.on('end', function() {
- self.close();
+ input.on('data', ondata);
+ input.on('end', onend);
+ self.once('close', function() {
+ input.removeListener('data', ondata);
+ input.removeListener('end', onend);
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');
@@ -101,9 +117,7 @@ function Interface(input, output, completer, terminal) {
exports.emitKeypressEvents(input);
// input usually refers to stdin
- input.on('keypress', function(s, key) {
- self._ttyWrite(s, key);
- });
+ input.on('keypress', onkeypress);
// Current line
this.line = '';
@@ -117,8 +131,10 @@ function Interface(input, output, completer, terminal) {
this.history = [];
this.historyIndex = -1;
- output.on('resize', function() {
- self._refreshLine();
+ output.on('resize', onresize);
+ self.once('close', function() {
+ input.removeListener('keypress', onkeypress);
+ output.removeListener('resize', onresize);
});
}
}
View
9 test/simple/test-readline-interface.js
@@ -31,6 +31,7 @@ function FakeInput() {
}
inherits(FakeInput, EventEmitter);
FakeInput.prototype.resume = function() {};
+FakeInput.prototype.pause = function() {};
var fi;
var rli;
@@ -67,6 +68,7 @@ rli.on('line', function(line) {
});
fi.emit('data', 'a');
assert.ok(!called);
+rli.close();
// sending a single character with no newline and then a newline
fi = new FakeInput();
@@ -80,6 +82,7 @@ fi.emit('data', 'a');
assert.ok(!called);
fi.emit('data', '\n');
assert.ok(called);
+rli.close();
// sending multiple newlines at once
fi = new FakeInput();
@@ -92,6 +95,7 @@ rli.on('line', function(line) {
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length);
+rli.close();
// sending multiple newlines at once that does not end with a new line
fi = new FakeInput();
@@ -104,6 +108,7 @@ rli.on('line', function(line) {
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length - 1);
+rli.close();
// sending a multi-byte utf8 char over multiple writes
var buf = Buffer('', 'utf8');
@@ -120,3 +125,7 @@ rli.on('line', function(line) {
assert.equal(callCount, 0);
fi.emit('data', '\n');
assert.equal(callCount, 1);
+rli.close();
+
+assert.deepEqual(fi.listeners('end'), []);
+assert.deepEqual(fi.listeners('data'), []);
View
4 test/simple/test-readline-set-raw-mode.js
@@ -85,3 +85,7 @@ 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);

0 comments on commit 2a7b226

Please sign in to comment.
Something went wrong with that request. Please try again.