ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
StreamTest.php
Go to the documentation of this file.
1 <?php
2 
4 
5 require_once('./libs/composer/vendor/autoload.php');
6 
8 use Mockery;
10 
21 class 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()
39  {
40  parent::setUp();
41 
42  self::$functions = Mockery::mock();
43  }
44 
49  public function testDetachWhichShouldSucceed()
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 
142  public function testCloseWhichShouldSucceed()
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 
176  public function testTellWhichShouldSucceed()
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 
242  public function testEofWhichShouldSucceed()
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 
281  public function testSeekWhichShouldSucceed()
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 
373  public function testReadWhichShouldSucceed()
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 
603  public function testWriteWhichShouldSucceed()
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
$text
Definition: errorreport.php:18
static fwrite($handle, $string, $length=null)
fwrite wrapper
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20