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