1<?php 2namespace GuzzleHttp\Tests\Stream; 3 4use BadMethodCallException; 5use GuzzleHttp\Stream\Exception\CannotAttachException; 6use GuzzleHttp\Stream\StreamInterface; 7use GuzzleHttp\Stream\Stream; 8use GuzzleHttp\Stream\StreamDecoratorTrait; 9use PHPUnit\Framework\TestCase; 10use UnexpectedValueException; 11 12class Str implements StreamInterface 13{ 14 use StreamDecoratorTrait; 15} 16 17/** 18 * @covers GuzzleHttp\Stream\StreamDecoratorTrait 19 */ 20class StreamDecoratorTraitTest extends TestCase 21{ 22 private $a; 23 private $b; 24 private $c; 25 26 public function setUp(): void 27 { 28 $this->c = fopen('php://temp', 'r+'); 29 fwrite($this->c, 'foo'); 30 fseek($this->c, 0); 31 $this->a = Stream::factory($this->c); 32 $this->b = new Str($this->a); 33 } 34 35 public function testCatchesExceptionsWhenCastingToString() 36 { 37 $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') 38 ->getMockForAbstractClass(); 39 $s->expects($this->once()) 40 ->method('read') 41 ->will($this->throwException(new \Exception('foo'))); 42 $msg = ''; 43 set_error_handler(function ($errNo, $str) use (&$msg) { $msg = $str; }); 44 echo new Str($s); 45 restore_error_handler(); 46 $this->assertStringContainsString('foo', $msg); 47 } 48 49 public function testToString() 50 { 51 $this->assertEquals('foo', (string) $this->b); 52 } 53 54 public function testHasSize() 55 { 56 $this->assertEquals(3, $this->b->getSize()); 57 $this->assertSame($this->b, $this->b->setSize(2)); 58 $this->assertEquals(2, $this->b->getSize()); 59 } 60 61 public function testReads() 62 { 63 $this->assertEquals('foo', $this->b->read(10)); 64 } 65 66 public function testCheckMethods() 67 { 68 $this->assertEquals($this->a->isReadable(), $this->b->isReadable()); 69 $this->assertEquals($this->a->isWritable(), $this->b->isWritable()); 70 $this->assertEquals($this->a->isSeekable(), $this->b->isSeekable()); 71 } 72 73 public function testSeeksAndTells() 74 { 75 $this->assertTrue($this->b->seek(1)); 76 $this->assertEquals(1, $this->a->tell()); 77 $this->assertEquals(1, $this->b->tell()); 78 $this->assertTrue($this->b->seek(0)); 79 $this->assertEquals(0, $this->a->tell()); 80 $this->assertEquals(0, $this->b->tell()); 81 $this->assertTrue($this->b->seek(0, SEEK_END)); 82 $this->assertEquals(3, $this->a->tell()); 83 $this->assertEquals(3, $this->b->tell()); 84 } 85 86 public function testGetsContents() 87 { 88 $this->assertEquals('foo', $this->b->getContents()); 89 $this->assertEquals('', $this->b->getContents()); 90 $this->b->seek(1); 91 $this->assertEquals('oo', $this->b->getContents(1)); 92 } 93 94 public function testCloses() 95 { 96 $this->b->close(); 97 $this->assertFalse(is_resource($this->c)); 98 } 99 100 public function testDetaches() 101 { 102 $this->b->detach(); 103 $this->assertFalse($this->b->isReadable()); 104 } 105 106 public function testCannotAttachByDefault() 107 { 108 $this->expectException(CannotAttachException::class); 109 $this->b->attach('a'); 110 } 111 112 public function testWrapsMetadata() 113 { 114 $this->assertSame($this->b->getMetadata(), $this->a->getMetadata()); 115 $this->assertSame($this->b->getMetadata('uri'), $this->a->getMetadata('uri')); 116 } 117 118 public function testWrapsWrites() 119 { 120 $this->b->seek(0, SEEK_END); 121 $this->b->write('foo'); 122 $this->assertEquals('foofoo', (string) $this->a); 123 } 124 125 public function testThrowsWithInvalidGetter() 126 { 127 $this->expectException(UnexpectedValueException::class); 128 $this->b->foo; 129 } 130 131 public function testThrowsWhenGetterNotImplemented() 132 { 133 $this->expectException(BadMethodCallException::class); 134 $s = new BadStream(); 135 $s->stream; 136 } 137} 138 139class BadStream 140{ 141 use StreamDecoratorTrait; 142 143 public function __construct() {} 144} 145