1<?php 2namespace GuzzleHttp\Tests\Stream; 3 4use GuzzleHttp\Stream\Stream; 5use InvalidArgumentException; 6use PHPUnit\Framework\TestCase; 7 8/** 9 * @covers GuzzleHttp\Stream\Stream 10 */ 11class StreamTest extends TestCase 12{ 13 public function testConstructorThrowsExceptionOnInvalidArgument() 14 { 15 $this->expectException(InvalidArgumentException::class); 16 new Stream(true); 17 } 18 19 public function testConstructorInitializesProperties() 20 { 21 $handle = fopen('php://temp', 'r+'); 22 fwrite($handle, 'data'); 23 $stream = new Stream($handle); 24 $this->assertTrue($stream->isReadable()); 25 $this->assertTrue($stream->isWritable()); 26 $this->assertTrue($stream->isSeekable()); 27 $this->assertEquals('php://temp', $stream->getMetadata('uri')); 28 $this->assertIsArray($stream->getMetadata()); 29 $this->assertEquals(4, $stream->getSize()); 30 $this->assertFalse($stream->eof()); 31 $stream->close(); 32 } 33 34 public function testStreamClosesHandleOnDestruct() 35 { 36 $handle = fopen('php://temp', 'r'); 37 $stream = new Stream($handle); 38 unset($stream); 39 $this->assertFalse(is_resource($handle)); 40 } 41 42 public function testConvertsToString() 43 { 44 $handle = fopen('php://temp', 'w+'); 45 fwrite($handle, 'data'); 46 $stream = new Stream($handle); 47 $this->assertEquals('data', (string) $stream); 48 $this->assertEquals('data', (string) $stream); 49 $stream->close(); 50 } 51 52 public function testGetsContents() 53 { 54 $handle = fopen('php://temp', 'w+'); 55 fwrite($handle, 'data'); 56 $stream = new Stream($handle); 57 $this->assertEquals('', $stream->getContents()); 58 $stream->seek(0); 59 $this->assertEquals('data', $stream->getContents()); 60 $this->assertEquals('', $stream->getContents()); 61 } 62 63 public function testChecksEof() 64 { 65 $handle = fopen('php://temp', 'w+'); 66 fwrite($handle, 'data'); 67 $stream = new Stream($handle); 68 $this->assertFalse($stream->eof()); 69 $stream->read(4); 70 $this->assertTrue($stream->eof()); 71 $stream->close(); 72 } 73 74 public function testAllowsSettingManualSize() 75 { 76 $handle = fopen('php://temp', 'w+'); 77 fwrite($handle, 'data'); 78 $stream = new Stream($handle); 79 $stream->setSize(10); 80 $this->assertEquals(10, $stream->getSize()); 81 $stream->close(); 82 } 83 84 public function testGetSize() 85 { 86 $size = filesize(__FILE__); 87 $handle = fopen(__FILE__, 'r'); 88 $stream = new Stream($handle); 89 $this->assertEquals($size, $stream->getSize()); 90 // Load from cache 91 $this->assertEquals($size, $stream->getSize()); 92 $stream->close(); 93 } 94 95 public function testEnsuresSizeIsConsistent() 96 { 97 $h = fopen('php://temp', 'w+'); 98 $this->assertEquals(3, fwrite($h, 'foo')); 99 $stream = new Stream($h); 100 $this->assertEquals(3, $stream->getSize()); 101 $this->assertEquals(4, $stream->write('test')); 102 $this->assertEquals(7, $stream->getSize()); 103 $this->assertEquals(7, $stream->getSize()); 104 $stream->close(); 105 } 106 107 public function testProvidesStreamPosition() 108 { 109 $handle = fopen('php://temp', 'w+'); 110 $stream = new Stream($handle); 111 $this->assertEquals(0, $stream->tell()); 112 $stream->write('foo'); 113 $this->assertEquals(3, $stream->tell()); 114 $stream->seek(1); 115 $this->assertEquals(1, $stream->tell()); 116 $this->assertSame(ftell($handle), $stream->tell()); 117 $stream->close(); 118 } 119 120 public function testKeepsPositionOfResource() 121 { 122 $h = fopen(__FILE__, 'r'); 123 fseek($h, 10); 124 $stream = Stream::factory($h); 125 $this->assertEquals(10, $stream->tell()); 126 $stream->close(); 127 } 128 129 public function testCanDetachAndAttachStream() 130 { 131 $r = fopen('php://temp', 'w+'); 132 $stream = new Stream($r); 133 $stream->write('foo'); 134 $this->assertTrue($stream->isReadable()); 135 $this->assertSame($r, $stream->detach()); 136 $this->assertNull($stream->detach()); 137 138 $this->assertFalse($stream->isReadable()); 139 $this->assertFalse($stream->read(10)); 140 $this->assertFalse($stream->isWritable()); 141 $this->assertFalse($stream->write('bar')); 142 $this->assertFalse($stream->isSeekable()); 143 $this->assertFalse($stream->seek(10)); 144 $this->assertFalse($stream->tell()); 145 $this->assertTrue($stream->eof()); 146 $this->assertNull($stream->getSize()); 147 $this->assertSame('', (string) $stream); 148 $this->assertSame('', $stream->getContents()); 149 150 $stream->attach($r); 151 $stream->seek(0); 152 $this->assertEquals('foo', $stream->getContents()); 153 $this->assertTrue($stream->isReadable()); 154 $this->assertTrue($stream->isWritable()); 155 $this->assertTrue($stream->isSeekable()); 156 157 $stream->close(); 158 } 159 160 public function testCloseClearProperties() 161 { 162 $handle = fopen('php://temp', 'r+'); 163 $stream = new Stream($handle); 164 $stream->close(); 165 166 $this->assertEmpty($stream->getMetadata()); 167 $this->assertFalse($stream->isSeekable()); 168 $this->assertFalse($stream->isReadable()); 169 $this->assertFalse($stream->isWritable()); 170 $this->assertNull($stream->getSize()); 171 } 172 173 public function testCreatesWithFactory() 174 { 175 $stream = Stream::factory('foo'); 176 $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $stream); 177 $this->assertEquals('foo', $stream->getContents()); 178 $stream->close(); 179 } 180 181 public function testFactoryCreatesFromEmptyString() 182 { 183 $s = Stream::factory(); 184 $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); 185 } 186 187 public function testFactoryCreatesFromResource() 188 { 189 $r = fopen(__FILE__, 'r'); 190 $s = Stream::factory($r); 191 $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); 192 $this->assertSame(file_get_contents(__FILE__), (string) $s); 193 } 194 195 public function testFactoryCreatesFromObjectWithToString() 196 { 197 $r = new HasToString(); 198 $s = Stream::factory($r); 199 $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); 200 $this->assertEquals('foo', (string) $s); 201 } 202 203 public function testCreatePassesThrough() 204 { 205 $s = Stream::factory('foo'); 206 $this->assertSame($s, Stream::factory($s)); 207 } 208 209 public function testThrowsExceptionForUnknown() 210 { 211 $this->expectException(InvalidArgumentException::class); 212 Stream::factory(new \stdClass()); 213 } 214 215 public function testReturnsCustomMetadata() 216 { 217 $s = Stream::factory('foo', ['metadata' => ['hwm' => 3]]); 218 $this->assertEquals(3, $s->getMetadata('hwm')); 219 $this->assertArrayHasKey('hwm', $s->getMetadata()); 220 } 221 222 public function testCanSetSize() 223 { 224 $s = Stream::factory('', ['size' => 10]); 225 $this->assertEquals(10, $s->getSize()); 226 } 227 228 public function testCanCreateIteratorBasedStream() 229 { 230 $a = new \ArrayIterator(['foo', 'bar', '123']); 231 $p = Stream::factory($a); 232 $this->assertInstanceOf('GuzzleHttp\Stream\PumpStream', $p); 233 $this->assertEquals('foo', $p->read(3)); 234 $this->assertFalse($p->eof()); 235 $this->assertEquals('b', $p->read(1)); 236 $this->assertEquals('a', $p->read(1)); 237 $this->assertEquals('r12', $p->read(3)); 238 $this->assertFalse($p->eof()); 239 $this->assertEquals('3', $p->getContents()); 240 $this->assertTrue($p->eof()); 241 $this->assertEquals(9, $p->tell()); 242 } 243} 244 245class HasToString 246{ 247 public function __toString() { 248 return 'foo'; 249 } 250} 251