From 942282e532a21d1ba9b0fbd6768239092034defe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 15 Jun 2016 14:55:49 +0200 Subject: [PATCH] Remove event listeners once closed --- src/Sequencer.php | 16 ++++++++++------ tests/SequencerTest.php | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/Sequencer.php b/src/Sequencer.php index 3000477..e9bf433 100644 --- a/src/Sequencer.php +++ b/src/Sequencer.php @@ -12,13 +12,12 @@ */ class Sequencer extends EventEmitter implements ReadableStreamInterface { - private $buffer = ''; - private $expect = 0; - private $closed = false; - private $input; private $invalid; + private $buffer = ''; + private $closed = false; + public function __construct(ReadableStreamInterface $input, $replacementCharacter = '?') { $this->input = $input; @@ -123,7 +122,10 @@ public function handleEnd() $this->emit('data', array($data)); } - $this->emit('end', array()); + if (!$this->closed) { + $this->emit('end'); + $this->close(); + } } /** @internal */ @@ -145,10 +147,12 @@ public function close() } $this->closed = true; + $this->buffer = ''; $this->input->close(); - $this->emit('close', array()); + $this->emit('close'); + $this->removeAllListeners(); } public function pause() diff --git a/tests/SequencerTest.php b/tests/SequencerTest.php index 38489b0..011f86e 100644 --- a/tests/SequencerTest.php +++ b/tests/SequencerTest.php @@ -161,6 +161,14 @@ public function testClosingInputWillCloseSequencer() $this->assertFalse($this->sequencer->isReadable()); } + public function testClosingInputWillRemoveAllDataListeners() + { + $this->input->close(); + + $this->assertEquals(array(), $this->input->listeners('data')); + $this->assertEquals(array(), $this->sequencer->listeners('data')); + } + public function testClosingSequencerWillCloseInput() { $this->input->on('close', $this->expectCallableOnce()); @@ -173,6 +181,25 @@ public function testClosingSequencerWillCloseInput() $this->assertFalse($this->sequencer->isReadable()); } + public function testClosingSequencerWillRemoveAllDataListeners() + { + $this->sequencer->close(); + + $this->assertEquals(array(), $this->input->listeners('data')); + $this->assertEquals(array(), $this->sequencer->listeners('data')); + } + + public function testClosingSequencerDuringFinalDataEventFromEndWillNotEmitEnd() + { + $this->sequencer->on('data', $this->expectCallableOnceWith('?')); + $this->sequencer->on('data', array($this->sequencer, 'close')); + + $this->sequencer->on('end', $this->expectCallableNever()); + + $this->input->emit('data', array("\xc3")); + $this->input->emit('end'); + } + public function testCustomReplacementEmitDataWithInvalidStartUtf8SequencesWillForwardOnceReplaced() { $this->sequencer = new Sequencer($this->input, 'X'); @@ -205,6 +232,15 @@ public function testUnreadableInputWillResultInUnreadableSequencer() $this->assertFalse($this->sequencer->isReadable()); } + public function testUnreadableInputWillNotAddAnyEventListeners() + { + $this->input->close(); + $this->sequencer = new Sequencer($this->input); + + $this->assertEquals(array(), $this->input->listeners('data')); + $this->assertEquals(array(), $this->sequencer->listeners('data')); + } + public function testEmitErrorEventWillForwardAndClose() { $this->sequencer->on('error', $this->expectCallableOnce());