ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
StreamTest.php
Go to the documentation of this file.
1<?php
2
4
5require_once('./libs/composer/vendor/autoload.php');
6
8use Mockery;
9use PHPUnit\Framework\TestCase;
10
21class StreamTest extends TestCase
22{
23
27 public static $functions;
28
29 private function createResource($content, $mode)
30 {
31 //call the root fopen function \ required!
32 return \fopen("data://text/plain,$content", $mode);
33 }
34
38 protected function setUp() : void
39 {
40 parent::setUp();
41
42 self::$functions = Mockery::mock();
43 }
44
50 {
51 $content = 'awesome content stream';
52 $mode = 'r';
53 $resource = $this->createResource($content, $mode);
54
55 $subject = new Stream($resource);
56 $detachedResource = $subject->detach();
57
58 //check that the resource is valid.
59 $this->assertTrue(is_resource($detachedResource));
60 $this->assertSame($resource, $detachedResource);
61
62 //Can't test the subject because psr-7 defines that the stream is in an unusable after the detach operation.
63 }
64
70 {
71 $content = 'awesome content stream';
72 $mode = 'r';
73 $resource = $this->createResource($content, $mode);
74
75 $subject = new Stream($resource);
76
77 //check that the detached resource is valid.
78 $detachedResource = $subject->detach();
79 $this->assertTrue(is_resource($detachedResource));
80
81 //must be null because the stream was already detached.
82 $detachedResource = $subject->detach();
83 $this->assertNull($detachedResource);
84 }
85
91 {
92 $content = 'awesome content stream';
93 $correctSize = strlen($content);
94 $mode = 'r';
95 $resource = $this->createResource($content, $mode);
96
97 $subject = new Stream($resource);
98
99 $size = $subject->getSize();
100 $this->assertSame($correctSize, $size);
101 }
102
108 {
109 $content = 'awesome content stream';
110 $correctSize = 900;
111 $mode = 'r';
112 $resource = $this->createResource($content, $mode);
113 $options = new StreamOptions([], $correctSize);
114
115 $subject = new Stream($resource, $options);
116
117 $size = $subject->getSize();
118 $this->assertSame($correctSize, $size);
119 }
120
126 {
127 $content = 'awesome content stream';
128 $mode = 'r';
129 $resource = $this->createResource($content, $mode);
130
131 $subject = new Stream($resource);
132 $subject->detach();
133
134 $size = $subject->getSize();
135 $this->assertNull($size);
136 }
137
143 {
144 $content = 'awesome content stream';
145 $mode = 'r';
146 $resource = $this->createResource($content, $mode);
147
148 $subject = new Stream($resource);
149
150 $subject->close();
151 $this->assertFalse(is_resource($resource));
152 }
153
159 {
160 $content = 'awesome content stream';
161 $mode = 'r';
162 $resource = $this->createResource($content, $mode);
163
164 $subject = new Stream($resource);
165
166 $actualResource = $subject->detach();
167 $subject->close();
168
169 $this->assertTrue(is_resource($actualResource));
170 }
171
177 {
178 $content = 'awesome content stream';
179 $mode = 'r';
180 $offset = 5;
181 $resource = $this->createResource($content, $mode);
182 fseek($resource, $offset);
183
184 $subject = new Stream($resource);
185
186 $actualPosition = $subject->tell();
187 $this->assertSame($offset, $actualPosition);
188 }
189
195 {
196 $content = 'awesome content stream';
197 $mode = 'r';
198 $resource = $this->createResource($content, $mode);
199
200 $subject = new Stream($resource);
201 $subject->detach();
202
203 $this->expectException(\RuntimeException::class);
204 $this->expectExceptionMessage('Stream is detached');
205
206 $subject->tell();
207 }
208
214 {
215 $content = 'awesome content stream';
216 $mode = 'r';
217 $resource = $this->createResource($content, $mode);
218
219 //load mock class
220 $functionMock = Mockery::mock('alias:' . PHPStreamFunctions::class);
221 $functionMock->shouldReceive('ftell')
222 ->once()
223 ->with($resource)
224 ->andReturn(false);
225
226 $functionMock->shouldReceive('fclose')
227 ->once()
228 ->with($resource);
229
230 $subject = new Stream($resource);
231
232 $this->expectException(\RuntimeException::class);
233 $this->expectExceptionMessage('Unable to determine stream position');
234
235 $subject->tell();
236 }
237
243 {
244 $content = 'awesome content stream';
245 $mode = 'r';
246 $offset = strlen($content); // end of stream
247 $resource = $this->createResource($content, $mode);
248 fseek($resource, $offset); // seek to end of stream
249 fgets($resource, 2); // we need to hit the end of the stream or eof returns false. (https://bugs.php.net/bug.php?id=35136)
250
251 $subject = new Stream($resource);
252
253 $endOfFileReached = $subject->eof();
254 $this->assertTrue($endOfFileReached);
255 }
256
262 {
263 $content = 'awesome content stream';
264 $mode = 'r';
265 $resource = $this->createResource($content, $mode);
266
267 $subject = new Stream($resource);
268 $subject->detach();
269
270 $this->expectException(\RuntimeException::class);
271 $this->expectExceptionMessage('Stream is detached');
272
273 $subject->eof();
274 }
275
276
282 {
283 $content = 'awesome content stream';
284 $mode = 'r';
285 $offset = 5;
286 $resource = $this->createResource($content, $mode);
287
288 $subject = new Stream($resource);
289
290 $subject->seek($offset);
291 $this->assertSame($offset, ftell($resource));
292 }
293
299 {
300 $content = 'awesome content stream';
301 $mode = 'r';
302 $offset = 5;
303 $resource = $this->createResource($content, $mode);
304
305 $subject = new Stream($resource);
306 $subject->detach();
307
308 $this->expectException(\RuntimeException::class);
309 $this->expectExceptionMessage('Stream is detached');
310
311 $subject->seek($offset);
312 }
313
319 {
320 $content = 'awesome content stream';
321 $mode = 'r';
322 $offset = 5;
323 $resource = $this->createResource($content, $mode);
324
325 $subjectMock = Mockery::mock(Stream::class . '[isSeekable]', [$resource]);
326
327 $subjectMock
328 ->shouldReceive('isSeekable')
329 ->once()
330 ->andReturn(false);
331
332 $this->expectException(\RuntimeException::class);
333 $this->expectExceptionMessage('Stream is not seekable');
334
335 $subjectMock->seek($offset);
336 }
337
343 {
344 $content = 'awesome content stream';
345 $mode = 'r';
346 $offset = 5;
347 $whence = SEEK_SET;
348 $resource = $this->createResource($content, $mode);
349
350 $subject = new Stream($resource);
351
352 //load mock class
353 $functionMock = Mockery::mock('alias:' . PHPStreamFunctions::class);
354 $functionMock->shouldReceive('fseek')
355 ->once()
356 ->withArgs([$resource, $offset, $whence])
357 ->andReturn(-1);
358
359 $functionMock->shouldReceive('fclose')
360 ->once()
361 ->with($resource);
362
363 $this->expectException(\RuntimeException::class);
364 $this->expectExceptionMessage("Unable to seek to stream position \"$offset\" with whence \"$whence\"");
365
366 $subject->seek($offset);
367 }
368
374 {
375 $content = 'awesome content stream';
376 $expectedResult = "awesome";
377 $mode = 'r';
378 $length = 7;
379 $resource = $this->createResource($content, $mode);
380
381 $subject = new Stream($resource);
382
383 $text = $subject->read($length);
384 $this->assertSame($expectedResult, $text);
385 }
386
392 {
393 $content = 'awesome content stream';
394 $expectedResult = "";
395 $mode = 'r';
396 $length = 0;
397 $resource = $this->createResource($content, $mode);
398
399 $subject = new Stream($resource);
400
401 $text = $subject->read($length);
402 $this->assertSame($expectedResult, $text);
403 }
404
410 {
411 $content = 'awesome content stream';
412 $mode = 'r';
413 $length = 7;
414 $resource = $this->createResource($content, $mode);
415
416 $subject = new Stream($resource);
417 $subject->detach();
418
419 $this->expectException(\RuntimeException::class);
420 $this->expectExceptionMessage('Stream is detached');
421
422 $subject->read($length);
423 }
424
430 {
431 $content = 'awesome content stream';
432 $mode = 'r';
433 $length = -2;
434 $resource = $this->createResource($content, $mode);
435
436 $subject = new Stream($resource);
437
438 $this->expectException(\RuntimeException::class);
439 $this->expectExceptionMessage('Length parameter must not be negative');
440
441 $subject->read($length);
442 }
443
449 {
450 $content = 'awesome content stream';
451 $mode = 'w';
452 $length = 3;
453 $resource = $this->createResource($content, $mode);
454
455 $subject = new Stream($resource);
456
457 $this->expectException(\RuntimeException::class);
458 $this->expectExceptionMessage('Can not read from non-readable stream');
459
460 $subject->read($length);
461 }
462
468 {
469 $content = 'awesome content stream';
470 $mode = 'r';
471 $length = 3;
472 $resource = $this->createResource($content, $mode);
473
474 $subject = new Stream($resource);
475
476 //load mock class
477 $functionMock = Mockery::mock('alias:' . PHPStreamFunctions::class);
478
479 $functionMock->shouldReceive('fread')
480 ->once()
481 ->withArgs([$resource, $length])
482 ->andReturn(false);
483
484 $functionMock->shouldReceive('fclose')
485 ->once()
486 ->with($resource);
487
488 $this->expectException(\RuntimeException::class);
489 $this->expectExceptionMessage('Unable to read from stream');
490
491 $subject->read($length);
492 }
493
499 {
500 $content = 'awesome content stream';
501 $mode = 'r';
502 $resource = $this->createResource($content, $mode);
503
504 $subject = new Stream($resource);
505
506 $text = $subject->getContents();
507 $this->assertSame($content, $text);
508 }
509
515 {
516 $content = 'awesome content stream';
517 $mode = 'r';
518 $resource = $this->createResource($content, $mode);
519
520 $subject = new Stream($resource);
521 $subject->detach();
522
523 $this->expectException(\RuntimeException::class);
524 $this->expectExceptionMessage('Stream is detached');
525
526 $subject->getContents();
527 }
528
534 {
535 $content = 'awesome content stream';
536 $mode = 'r';
537 $resource = $this->createResource($content, $mode);
538
539 $subject = new Stream($resource);
540
541 //load mock class
542 $functionMock = Mockery::mock('alias:' . PHPStreamFunctions::class);
543
544 $functionMock->shouldReceive('stream_get_contents')
545 ->once()
546 ->with($resource)
547 ->andReturn(false);
548
549 $functionMock->shouldReceive('fclose')
550 ->once()
551 ->with($resource);
552
553 $this->expectException(\RuntimeException::class);
554 $this->expectExceptionMessage('Unable to read stream contents');
555
556 $subject->getContents();
557 }
558
564 {
565 $content = 'awesome content stream';
566 $mode = 'r';
567 $resource = $this->createResource($content, $mode);
568
569 $subject = new Stream($resource);
570
571 $text = $subject->__toString();
572 $this->assertSame($content, $text);
573 }
574
582 {
583 $content = 'awesome content stream';
584 $expectedResult = '';
585 $mode = 'r';
586 $resource = $this->createResource($content, $mode);
587
588 $subject = Mockery::mock(Stream::class . '[rewind]', [$resource]);
589
590 $subject->shouldDeferMissing();
591 $subject->shouldReceive('rewind')
592 ->once()
593 ->andThrow(\RuntimeException::class);
594
595 $text = $subject->__toString();
596 $this->assertSame($expectedResult, $text);
597 }
598
604 {
605 $content = 'awesome content stream';
606 $newContent = '!';
607 $byteCount = strlen($newContent);
608 $mode = 'r+';
609 $resource = fopen('php://memory', $mode);
610 PHPStreamFunctions::fwrite($resource, $content);
611
612 $subject = new Stream($resource);
613 $currentSize = $subject->getSize();
614
615 $numberOfBytesWritten = $subject->write($newContent);
616 $newSize = $subject->getSize();
617
618 $this->assertSame($byteCount, $numberOfBytesWritten, 'The count of bytes passed to write must match the written bytes after the operation.');
619 $this->assertGreaterThan($currentSize, $newSize, 'The new size must be grater than the old size because we wrote to the stream.');
620 }
621
627 {
628 $content = 'awesome content stream';
629 $newContent = '!';
630 $mode = 'w';
631 $resource = $this->createResource($content, $mode);
632
633 $subject = new Stream($resource);
634 $subject->detach();
635
636 $this->expectException(\RuntimeException::class);
637 $this->expectExceptionMessage('Stream is detached');
638
639 $subject->write($newContent);
640 }
641
647 {
648 $content = 'awesome content stream';
649 $newContent = '!';
650 $mode = 'r';
651 $resource = $this->createResource($content, $mode);
652
653 $subject = new Stream($resource);
654
655 $this->expectException(\RuntimeException::class);
656 $this->expectExceptionMessage('Can not write to a non-writable stream');
657
658 $subject->write($newContent);
659 }
660
666 {
667 $content = 'awesome content stream';
668 $newContent = '!';
669 $mode = 'a+';
670 $resource = $this->createResource($content, $mode);
671
672 $subject = new Stream($resource);
673
674 //load mock class
675 $functionMock = Mockery::mock('alias:' . PHPStreamFunctions::class);
676
677 $functionMock->shouldReceive('fwrite')
678 ->once()
679 ->withArgs([$resource, $newContent])
680 ->andReturn(false);
681
682 $functionMock->shouldReceive('fclose')
683 ->once()
684 ->with($resource);
685
686 $this->expectException(\RuntimeException::class);
687 $this->expectExceptionMessage('Unable to write to stream');
688
689 $subject->write($newContent);
690 }
691}
$size
Definition: RandomTest.php:84
An exception for terminatinating execution or to throw for unit testing.
testDetachDoubleInvocationWhichShouldFail()
@Test @small
Definition: StreamTest.php:69
testGetSizeWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:125
testDetachWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:49
testGetContentsWithFailingStreamGetContentsCallWhichShouldFail()
@Test @small
Definition: StreamTest.php:533
testGetSizeWithOptionsWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:107
testSeekWithNotSeekableStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:318
testWriteWithFailingFwriteCallWhichShouldFail()
@Test @small
Definition: StreamTest.php:665
testSeekWithFseekFailureWhichShouldFail()
@Test @small
Definition: StreamTest.php:342
testTellWithFtellFailureWhichShouldFail()
@Test @small
Definition: StreamTest.php:213
testEofWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:261
testToStringWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:563
testReadWithFailingFreadCallWhichShouldFail()
@Test @small
Definition: StreamTest.php:467
testReadWithZeroLengthWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:391
testToStringWithErrorWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:581
testWriteWithReadOnlyStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:646
testGetContentsWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:514
testCloseWithDetachedStreamWhichShouldDoNothing()
@Test @small
Definition: StreamTest.php:158
testTellWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:194
testWriteWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:626
testReadWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:409
testGetSizeWithStatsWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:90
testSeekWithDetachedStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:298
testGetContentsWhichShouldSucceed()
@Test @small
Definition: StreamTest.php:498
testReadWithUnreadableStreamWhichShouldFail()
@Test @small
Definition: StreamTest.php:448
testReadWithNegativeLengthWhichShouldFail()
@Test @small
Definition: StreamTest.php:429
static fwrite($handle, $string, $length=null)
fwrite wrapper