|
2 | 2 |
|
3 | 3 | namespace React\Tests\Stream; |
4 | 4 |
|
| 5 | +use Clue\StreamFilter as Filter; |
5 | 6 | use React\Stream\DuplexResourceStream; |
6 | 7 | use React\Stream\ReadableResourceStream; |
7 | 8 | use React\EventLoop\ExtEventLoop; |
@@ -342,6 +343,43 @@ public function testReadsNothingFromProcessPipeWithNoOutput($condition, $loopFac |
342 | 343 | $loop->run(); |
343 | 344 | } |
344 | 345 |
|
| 346 | + /** |
| 347 | + * @covers React\Stream\ReadableResourceStream::handleData |
| 348 | + * @dataProvider loopProvider |
| 349 | + */ |
| 350 | + public function testEmptyReadShouldntFcloseStream($condition, $loopFactory) |
| 351 | + { |
| 352 | + if (true !== $condition()) { |
| 353 | + return $this->markTestSkipped('Loop implementation not available'); |
| 354 | + } |
| 355 | + |
| 356 | + $server = stream_socket_server('tcp://127.0.0.1:0'); |
| 357 | + |
| 358 | + $client = stream_socket_client(stream_socket_get_name($server, false)); |
| 359 | + $stream = stream_socket_accept($server); |
| 360 | + |
| 361 | + |
| 362 | + // add a filter which returns an error when encountering an 'a' when reading |
| 363 | + Filter\append($stream, function ($chunk) { |
| 364 | + return ''; |
| 365 | + }, STREAM_FILTER_READ); |
| 366 | + |
| 367 | + $loop = $loopFactory(); |
| 368 | + |
| 369 | + $conn = new DuplexResourceStream($stream, $loop); |
| 370 | + $conn->on('error', $this->expectCallableNever()); |
| 371 | + $conn->on('data', $this->expectCallableNever()); |
| 372 | + $conn->on('end', $this->expectCallableNever()); |
| 373 | + |
| 374 | + fwrite($client, "foobar\n"); |
| 375 | + |
| 376 | + $conn->handleData($stream); |
| 377 | + |
| 378 | + fclose($stream); |
| 379 | + fclose($client); |
| 380 | + fclose($server); |
| 381 | + } |
| 382 | + |
345 | 383 | private function loopTick(LoopInterface $loop) |
346 | 384 | { |
347 | 385 | $loop->addTimer(0, function () use ($loop) { |
|
0 commit comments