diff --git a/src/Stream.php b/src/Stream.php index 4dfa90a..873ad36 100644 --- a/src/Stream.php +++ b/src/Stream.php @@ -130,7 +130,9 @@ public function handleData($stream) { $data = fread($stream, $this->bufferSize); - $this->emit('data', array($data, $this)); + if ($data !== '') { + $this->emit('data', array($data, $this)); + } if (!is_resource($stream) || feof($stream)) { $this->end(); diff --git a/tests/StreamIntegrationTest.php b/tests/StreamIntegrationTest.php index e891b28..239c337 100644 --- a/tests/StreamIntegrationTest.php +++ b/tests/StreamIntegrationTest.php @@ -55,4 +55,32 @@ public function testBufferReadsLargeChunks($condition, $loopFactory) $this->assertEquals($testString, $buffer); } + + /** + * @dataProvider loopProvider + */ + public function testDoesNotEmitDataIfNothingHasBeenWritten($condition, $loopFactory) + { + if (true !== $condition()) { + return $this->markTestSkipped('Loop implementation not available'); + } + + $loop = $loopFactory(); + + list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); + + $streamA = new Stream($sockA, $loop); + $streamB = new Stream($sockB, $loop); + + // end streamA without writing any data + $streamA->end(); + + // streamB should not emit any data + $streamB->on('data', $this->expectCallableNever()); + + $loop->run(); + + $streamA->close(); + $streamB->close(); + } } diff --git a/tests/StreamTest.php b/tests/StreamTest.php index 1a9b18f..33f36b6 100644 --- a/tests/StreamTest.php +++ b/tests/StreamTest.php @@ -50,6 +50,20 @@ public function testDataEvent() $this->assertSame("foobar\n", $capturedData); } + /** + * @covers React\Stream\Stream::handleData + */ + public function testEmptyStreamShouldNotEmitData() + { + $stream = fopen('php://temp', 'r+'); + $loop = $this->createLoopMock(); + + $conn = new Stream($stream, $loop); + $conn->on('data', $this->expectCallableNever()); + + $conn->handleData($stream); + } + /** * @covers React\Stream\Stream::write */