2015-08-17 17:00:26 -07:00
< ? php
2015-08-27 12:03:05 -07:00
namespace GuzzleHttp\Tests\Psr7 ;
2015-08-17 17:00:26 -07:00
2015-08-27 12:03:05 -07:00
use GuzzleHttp\Psr7 ;
use GuzzleHttp\Psr7\CachingStream ;
2015-08-17 17:00:26 -07:00
/**
2015-08-27 12:03:05 -07:00
* @ covers GuzzleHttp\Psr7\CachingStream
2015-08-17 17:00:26 -07:00
*/
class CachingStreamTest extends \PHPUnit_Framework_TestCase
{
/** @var CachingStream */
protected $body ;
protected $decorated ;
public function setUp ()
{
2015-08-27 12:03:05 -07:00
$this -> decorated = Psr7\stream_for ( 'testing' );
2015-08-17 17:00:26 -07:00
$this -> body = new CachingStream ( $this -> decorated );
}
public function tearDown ()
{
$this -> decorated -> close ();
$this -> body -> close ();
}
public function testUsesRemoteSizeIfPossible ()
{
2015-08-27 12:03:05 -07:00
$body = Psr7\stream_for ( 'test' );
2015-08-17 17:00:26 -07:00
$caching = new CachingStream ( $body );
$this -> assertEquals ( 4 , $caching -> getSize ());
}
2015-09-04 13:20:09 -07:00
public function testReadsUntilCachedToByte ()
2015-08-17 17:00:26 -07:00
{
2015-09-04 13:20:09 -07:00
$this -> body -> seek ( 5 );
$this -> assertEquals ( 'n' , $this -> body -> read ( 1 ));
$this -> body -> seek ( 0 );
$this -> assertEquals ( 't' , $this -> body -> read ( 1 ));
2015-08-17 17:00:26 -07:00
}
2015-09-04 13:20:09 -07:00
public function testCanSeekNearEndWithSeekEnd ()
{
$baseStream = Psr7\stream_for ( implode ( '' , range ( 'a' , 'z' )));
$cached = new CachingStream ( $baseStream );
$cached -> seek ( 1 , SEEK_END );
$this -> assertEquals ( 24 , $baseStream -> tell ());
$this -> assertEquals ( 'y' , $cached -> read ( 1 ));
$this -> assertEquals ( 26 , $cached -> getSize ());
}
public function testCanSeekToEndWithSeekEnd ()
2015-08-17 17:00:26 -07:00
{
2015-09-04 13:20:09 -07:00
$baseStream = Psr7\stream_for ( implode ( '' , range ( 'a' , 'z' )));
$cached = new CachingStream ( $baseStream );
$cached -> seek ( 0 , SEEK_END );
$this -> assertEquals ( 25 , $baseStream -> tell ());
$this -> assertEquals ( 'z' , $cached -> read ( 1 ));
$this -> assertEquals ( 26 , $cached -> getSize ());
}
public function testCanUseSeekEndWithUnknownSize ()
{
$baseStream = Psr7\stream_for ( 'testing' );
$decorated = Psr7\FnStream :: decorate ( $baseStream , [
'getSize' => function () { return null ; }
]);
$cached = new CachingStream ( $decorated );
$cached -> seek ( 1 , SEEK_END );
$this -> assertEquals ( 'ng' , $cached -> read ( 2 ));
2015-08-17 17:00:26 -07:00
}
public function testRewindUsesSeek ()
{
2015-08-27 12:03:05 -07:00
$a = Psr7\stream_for ( 'foo' );
$d = $this -> getMockBuilder ( 'GuzzleHttp\Psr7\CachingStream' )
2015-08-17 17:00:26 -07:00
-> setMethods ( array ( 'seek' ))
-> setConstructorArgs ( array ( $a ))
-> getMock ();
$d -> expects ( $this -> once ())
-> method ( 'seek' )
-> with ( 0 )
-> will ( $this -> returnValue ( true ));
$d -> seek ( 0 );
}
public function testCanSeekToReadBytes ()
{
$this -> assertEquals ( 'te' , $this -> body -> read ( 2 ));
$this -> body -> seek ( 0 );
$this -> assertEquals ( 'test' , $this -> body -> read ( 4 ));
$this -> assertEquals ( 4 , $this -> body -> tell ());
$this -> body -> seek ( 2 );
$this -> assertEquals ( 2 , $this -> body -> tell ());
$this -> body -> seek ( 2 , SEEK_CUR );
$this -> assertEquals ( 4 , $this -> body -> tell ());
$this -> assertEquals ( 'ing' , $this -> body -> read ( 3 ));
}
public function testWritesToBufferStream ()
{
$this -> body -> read ( 2 );
$this -> body -> write ( 'hi' );
$this -> body -> seek ( 0 );
$this -> assertEquals ( 'tehiing' , ( string ) $this -> body );
}
public function testSkipsOverwrittenBytes ()
{
2015-08-27 12:03:05 -07:00
$decorated = Psr7\stream_for (
2015-08-17 17:00:26 -07:00
implode ( " \n " , array_map ( function ( $n ) {
return str_pad ( $n , 4 , '0' , STR_PAD_LEFT );
}, range ( 0 , 25 )))
);
$body = new CachingStream ( $decorated );
2015-08-27 12:03:05 -07:00
$this -> assertEquals ( " 0000 \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0001 \n " , Psr7\readline ( $body ));
2015-08-17 17:00:26 -07:00
// Write over part of the body yet to be read, so skip some bytes
$this -> assertEquals ( 5 , $body -> write ( " TEST \n " ));
$this -> assertEquals ( 5 , $this -> readAttribute ( $body , 'skipReadBytes' ));
// Read, which skips bytes, then reads
2015-08-27 12:03:05 -07:00
$this -> assertEquals ( " 0003 \n " , Psr7\readline ( $body ));
2015-08-17 17:00:26 -07:00
$this -> assertEquals ( 0 , $this -> readAttribute ( $body , 'skipReadBytes' ));
2015-08-27 12:03:05 -07:00
$this -> assertEquals ( " 0004 \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0005 \n " , Psr7\readline ( $body ));
2015-08-17 17:00:26 -07:00
// Overwrite part of the cached body (so don't skip any bytes)
$body -> seek ( 5 );
$this -> assertEquals ( 5 , $body -> write ( " ABCD \n " ));
$this -> assertEquals ( 0 , $this -> readAttribute ( $body , 'skipReadBytes' ));
2015-08-27 12:03:05 -07:00
$this -> assertEquals ( " TEST \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0003 \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0004 \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0005 \n " , Psr7\readline ( $body ));
$this -> assertEquals ( " 0006 \n " , Psr7\readline ( $body ));
2015-08-17 17:00:26 -07:00
$this -> assertEquals ( 5 , $body -> write ( " 1234 \n " ));
$this -> assertEquals ( 5 , $this -> readAttribute ( $body , 'skipReadBytes' ));
// Seek to 0 and ensure the overwritten bit is replaced
$body -> seek ( 0 );
$this -> assertEquals ( " 0000 \n ABCD \n TEST \n 0003 \n 0004 \n 0005 \n 0006 \n 1234 \n 0008 \n 0009 \n " , $body -> read ( 50 ));
// Ensure that casting it to a string does not include the bit that was overwritten
$this -> assertContains ( " 0000 \n ABCD \n TEST \n 0003 \n 0004 \n 0005 \n 0006 \n 1234 \n 0008 \n 0009 \n " , ( string ) $body );
}
public function testClosesBothStreams ()
{
$s = fopen ( 'php://temp' , 'r' );
2015-08-27 12:03:05 -07:00
$a = Psr7\stream_for ( $s );
2015-08-17 17:00:26 -07:00
$d = new CachingStream ( $a );
$d -> close ();
$this -> assertFalse ( is_resource ( $s ));
}
2015-09-04 13:20:09 -07:00
/**
* @ expectedException \InvalidArgumentException
*/
public function testEnsuresValidWhence ()
{
$this -> body -> seek ( 10 , - 123456 );
}
2015-08-17 17:00:26 -07:00
}