AppendStreamTest.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. namespace GuzzleHttp\Tests\Psr7;
  3. use GuzzleHttp\Psr7\AppendStream;
  4. use GuzzleHttp\Psr7;
  5. class AppendStreamTest extends BaseTest
  6. {
  7. /**
  8. * @expectedException \InvalidArgumentException
  9. * @expectedExceptionMessage Each stream must be readable
  10. */
  11. public function testValidatesStreamsAreReadable()
  12. {
  13. $a = new AppendStream();
  14. $s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
  15. ->setMethods(['isReadable'])
  16. ->getMockForAbstractClass();
  17. $s->expects($this->once())
  18. ->method('isReadable')
  19. ->will($this->returnValue(false));
  20. $a->addStream($s);
  21. }
  22. /**
  23. * @expectedException \RuntimeException
  24. * @expectedExceptionMessage The AppendStream can only seek with SEEK_SET
  25. */
  26. public function testValidatesSeekType()
  27. {
  28. $a = new AppendStream();
  29. $a->seek(100, SEEK_CUR);
  30. }
  31. /**
  32. * @expectedException \RuntimeException
  33. * @expectedExceptionMessage Unable to seek stream 0 of the AppendStream
  34. */
  35. public function testTriesToRewindOnSeek()
  36. {
  37. $a = new AppendStream();
  38. $s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
  39. ->setMethods(['isReadable', 'rewind', 'isSeekable'])
  40. ->getMockForAbstractClass();
  41. $s->expects($this->once())
  42. ->method('isReadable')
  43. ->will($this->returnValue(true));
  44. $s->expects($this->once())
  45. ->method('isSeekable')
  46. ->will($this->returnValue(true));
  47. $s->expects($this->once())
  48. ->method('rewind')
  49. ->will($this->throwException(new \RuntimeException()));
  50. $a->addStream($s);
  51. $a->seek(10);
  52. }
  53. public function testSeeksToPositionByReading()
  54. {
  55. $a = new AppendStream([
  56. Psr7\stream_for('foo'),
  57. Psr7\stream_for('bar'),
  58. Psr7\stream_for('baz'),
  59. ]);
  60. $a->seek(3);
  61. $this->assertEquals(3, $a->tell());
  62. $this->assertEquals('bar', $a->read(3));
  63. $a->seek(6);
  64. $this->assertEquals(6, $a->tell());
  65. $this->assertEquals('baz', $a->read(3));
  66. }
  67. public function testDetachWithoutStreams()
  68. {
  69. $s = new AppendStream();
  70. $s->detach();
  71. $this->assertSame(0, $s->getSize());
  72. $this->assertTrue($s->eof());
  73. $this->assertTrue($s->isReadable());
  74. $this->assertSame('', (string) $s);
  75. $this->assertTrue($s->isSeekable());
  76. $this->assertFalse($s->isWritable());
  77. }
  78. public function testDetachesEachStream()
  79. {
  80. $handle = fopen('php://temp', 'r');
  81. $s1 = Psr7\stream_for($handle);
  82. $s2 = Psr7\stream_for('bar');
  83. $a = new AppendStream([$s1, $s2]);
  84. $a->detach();
  85. $this->assertSame(0, $a->getSize());
  86. $this->assertTrue($a->eof());
  87. $this->assertTrue($a->isReadable());
  88. $this->assertSame('', (string) $a);
  89. $this->assertTrue($a->isSeekable());
  90. $this->assertFalse($a->isWritable());
  91. $this->assertNull($s1->detach());
  92. $this->assertInternalType('resource', $handle, 'resource is not closed when detaching');
  93. fclose($handle);
  94. }
  95. public function testClosesEachStream()
  96. {
  97. $handle = fopen('php://temp', 'r');
  98. $s1 = Psr7\stream_for($handle);
  99. $s2 = Psr7\stream_for('bar');
  100. $a = new AppendStream([$s1, $s2]);
  101. $a->close();
  102. $this->assertSame(0, $a->getSize());
  103. $this->assertTrue($a->eof());
  104. $this->assertTrue($a->isReadable());
  105. $this->assertSame('', (string) $a);
  106. $this->assertTrue($a->isSeekable());
  107. $this->assertFalse($a->isWritable());
  108. $this->assertFalse(is_resource($handle));
  109. }
  110. /**
  111. * @expectedExceptionMessage Cannot write to an AppendStream
  112. * @expectedException \RuntimeException
  113. */
  114. public function testIsNotWritable()
  115. {
  116. $a = new AppendStream([Psr7\stream_for('foo')]);
  117. $this->assertFalse($a->isWritable());
  118. $this->assertTrue($a->isSeekable());
  119. $this->assertTrue($a->isReadable());
  120. $a->write('foo');
  121. }
  122. public function testDoesNotNeedStreams()
  123. {
  124. $a = new AppendStream();
  125. $this->assertEquals('', (string) $a);
  126. }
  127. public function testCanReadFromMultipleStreams()
  128. {
  129. $a = new AppendStream([
  130. Psr7\stream_for('foo'),
  131. Psr7\stream_for('bar'),
  132. Psr7\stream_for('baz'),
  133. ]);
  134. $this->assertFalse($a->eof());
  135. $this->assertSame(0, $a->tell());
  136. $this->assertEquals('foo', $a->read(3));
  137. $this->assertEquals('bar', $a->read(3));
  138. $this->assertEquals('baz', $a->read(3));
  139. $this->assertSame('', $a->read(1));
  140. $this->assertTrue($a->eof());
  141. $this->assertSame(9, $a->tell());
  142. $this->assertEquals('foobarbaz', (string) $a);
  143. }
  144. public function testCanDetermineSizeFromMultipleStreams()
  145. {
  146. $a = new AppendStream([
  147. Psr7\stream_for('foo'),
  148. Psr7\stream_for('bar')
  149. ]);
  150. $this->assertEquals(6, $a->getSize());
  151. $s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
  152. ->setMethods(['isSeekable', 'isReadable'])
  153. ->getMockForAbstractClass();
  154. $s->expects($this->once())
  155. ->method('isSeekable')
  156. ->will($this->returnValue(null));
  157. $s->expects($this->once())
  158. ->method('isReadable')
  159. ->will($this->returnValue(true));
  160. $a->addStream($s);
  161. $this->assertNull($a->getSize());
  162. }
  163. public function testCatchesExceptionsWhenCastingToString()
  164. {
  165. $s = $this->getMockBuilder('Psr\Http\Message\StreamInterface')
  166. ->setMethods(['isSeekable', 'read', 'isReadable', 'eof'])
  167. ->getMockForAbstractClass();
  168. $s->expects($this->once())
  169. ->method('isSeekable')
  170. ->will($this->returnValue(true));
  171. $s->expects($this->once())
  172. ->method('read')
  173. ->will($this->throwException(new \RuntimeException('foo')));
  174. $s->expects($this->once())
  175. ->method('isReadable')
  176. ->will($this->returnValue(true));
  177. $s->expects($this->any())
  178. ->method('eof')
  179. ->will($this->returnValue(false));
  180. $a = new AppendStream([$s]);
  181. $this->assertFalse($a->eof());
  182. $this->assertSame('', (string) $a);
  183. }
  184. public function testReturnsEmptyMetadata()
  185. {
  186. $s = new AppendStream();
  187. $this->assertEquals([], $s->getMetadata());
  188. $this->assertNull($s->getMetadata('foo'));
  189. }
  190. }