Skip to content

Commit 53d01ea

Browse files
authored
Merge pull request #8 from clue-labs/close
Remove event listeners once closed
2 parents 813df56 + 942282e commit 53d01ea

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

src/Sequencer.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
*/
1313
class Sequencer extends EventEmitter implements ReadableStreamInterface
1414
{
15-
private $buffer = '';
16-
private $expect = 0;
17-
private $closed = false;
18-
1915
private $input;
2016
private $invalid;
2117

18+
private $buffer = '';
19+
private $closed = false;
20+
2221
public function __construct(ReadableStreamInterface $input, $replacementCharacter = '?')
2322
{
2423
$this->input = $input;
@@ -123,7 +122,10 @@ public function handleEnd()
123122
$this->emit('data', array($data));
124123
}
125124

126-
$this->emit('end', array());
125+
if (!$this->closed) {
126+
$this->emit('end');
127+
$this->close();
128+
}
127129
}
128130

129131
/** @internal */
@@ -145,10 +147,12 @@ public function close()
145147
}
146148

147149
$this->closed = true;
150+
$this->buffer = '';
148151

149152
$this->input->close();
150153

151-
$this->emit('close', array());
154+
$this->emit('close');
155+
$this->removeAllListeners();
152156
}
153157

154158
public function pause()

tests/SequencerTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ public function testClosingInputWillCloseSequencer()
161161
$this->assertFalse($this->sequencer->isReadable());
162162
}
163163

164+
public function testClosingInputWillRemoveAllDataListeners()
165+
{
166+
$this->input->close();
167+
168+
$this->assertEquals(array(), $this->input->listeners('data'));
169+
$this->assertEquals(array(), $this->sequencer->listeners('data'));
170+
}
171+
164172
public function testClosingSequencerWillCloseInput()
165173
{
166174
$this->input->on('close', $this->expectCallableOnce());
@@ -173,6 +181,25 @@ public function testClosingSequencerWillCloseInput()
173181
$this->assertFalse($this->sequencer->isReadable());
174182
}
175183

184+
public function testClosingSequencerWillRemoveAllDataListeners()
185+
{
186+
$this->sequencer->close();
187+
188+
$this->assertEquals(array(), $this->input->listeners('data'));
189+
$this->assertEquals(array(), $this->sequencer->listeners('data'));
190+
}
191+
192+
public function testClosingSequencerDuringFinalDataEventFromEndWillNotEmitEnd()
193+
{
194+
$this->sequencer->on('data', $this->expectCallableOnceWith('?'));
195+
$this->sequencer->on('data', array($this->sequencer, 'close'));
196+
197+
$this->sequencer->on('end', $this->expectCallableNever());
198+
199+
$this->input->emit('data', array("\xc3"));
200+
$this->input->emit('end');
201+
}
202+
176203
public function testCustomReplacementEmitDataWithInvalidStartUtf8SequencesWillForwardOnceReplaced()
177204
{
178205
$this->sequencer = new Sequencer($this->input, 'X');
@@ -205,6 +232,15 @@ public function testUnreadableInputWillResultInUnreadableSequencer()
205232
$this->assertFalse($this->sequencer->isReadable());
206233
}
207234

235+
public function testUnreadableInputWillNotAddAnyEventListeners()
236+
{
237+
$this->input->close();
238+
$this->sequencer = new Sequencer($this->input);
239+
240+
$this->assertEquals(array(), $this->input->listeners('data'));
241+
$this->assertEquals(array(), $this->sequencer->listeners('data'));
242+
}
243+
208244
public function testEmitErrorEventWillForwardAndClose()
209245
{
210246
$this->sequencer->on('error', $this->expectCallableOnce());

0 commit comments

Comments
 (0)