1010namespace ZendTest \Diactoros \Response ;
1111
1212use PHPUnit_Framework_TestCase as TestCase ;
13+ use Prophecy \Argument ;
1314use Psr \Http \Message \ResponseInterface ;
1415use Psr \Http \Message \StreamInterface ;
1516use Zend \Diactoros \CallbackStream ;
@@ -43,6 +44,7 @@ public function testDoesNotInjectContentLengthHeaderIfStreamSizeIsUnknown()
4344 $ stream = $ this ->prophesize ('Psr\Http\Message\StreamInterface ' );
4445 $ stream ->__toString ()->willReturn ('Content! ' );
4546 $ stream ->isSeekable ()->willReturn (false );
47+ $ stream ->isReadable ()->willReturn (false );
4648 $ stream ->eof ()->willReturn (true );
4749 $ stream ->rewind ()->willReturn (true );
4850 $ stream ->getSize ()->willReturn (null );
@@ -58,6 +60,101 @@ public function testDoesNotInjectContentLengthHeaderIfStreamSizeIsUnknown()
5860 }
5961 }
6062
63+ public function emitBodyProvider ()
64+ {
65+ return [
66+ [true , '01234567890123456789 ' , 10 , 2 ],
67+ [true , '012345678901234567890123 ' , 10 , 3 ],
68+ [false , '01234567890123456789 ' , 10 , 2 ],
69+ [false , '012345678901234567890123 ' , 10 , 3 ],
70+ ];
71+ }
72+
73+ /**
74+ * @dataProvider emitBodyProvider
75+ */
76+ public function testEmitBody ($ seekable , $ contents , $ maxBufferLength , $ expectedReads = 0 )
77+ {
78+ $ position = 0 ;
79+
80+ $ stream = $ this ->prophesize ('Psr\Http\Message\StreamInterface ' );
81+ $ stream ->getSize ()->willReturn (strlen ($ contents ));
82+ $ stream ->isSeekable ()->willReturn ($ seekable );
83+ $ stream ->isReadable ()->willReturn (true );
84+ $ stream ->rewind ()->willReturn (true );
85+
86+ $ stream ->eof ()->will (function () use (&$ contents , &$ position ){
87+ return !isset ($ contents [$ position ]);
88+ });
89+
90+ $ stream ->read (Argument::type ('integer ' ))->will (function ($ args ) use (&$ contents , &$ position ){
91+ $ data = substr ($ contents , $ position , $ args [0 ]);
92+ $ position += strlen ($ data );
93+ return $ data ;
94+ });
95+
96+ $ response = (new Response ())
97+ ->withStatus (200 )
98+ ->withBody ($ stream ->reveal ());
99+
100+ ob_start ();
101+ $ this ->emitter ->emit ($ response , $ maxBufferLength );
102+ $ stream ->rewind ()->shouldBeCalledTimes ($ seekable ? 1 : 0 );
103+ $ stream ->read (Argument::type ('integer ' ))->shouldBeCalledTimes ($ expectedReads );
104+ $ this ->assertEquals ($ contents , ob_get_clean ());
105+
106+ }
107+
108+ public function emitBodyRangeProvider ()
109+ {
110+ return [
111+ [true , '01234567890123456789 ' , ['bytes ' , 10 , 20 , '* ' ], 10 , 1 ],
112+ [true , '012345678901234567890123 ' , ['bytes ' , 10 , 40 , '* ' ], 10 , 2 ],
113+ [false , '01234567890123456789 ' , ['bytes ' , 11 , 20 , '* ' ], 10 , 1 ],
114+ [false , '012345678901234567890123 ' , ['bytes ' , 11 , 40 , '* ' ], 10 , 2 ],
115+ ];
116+ }
117+
118+ /**
119+ * @dataProvider emitBodyRangeProvider
120+ */
121+ public function testEmitBodyRange ($ seekable , $ contents , $ range , $ maxBufferLength , $ expectedReads = 0 )
122+ {
123+ list ($ unit , $ first , $ last , $ length ) = $ range ;
124+
125+ $ position = $ first ;
126+
127+ $ stream = $ this ->prophesize ('Psr\Http\Message\StreamInterface ' );
128+ $ stream ->getSize ()->willReturn (strlen ($ contents ));
129+ $ stream ->isSeekable ()->willReturn ($ seekable );
130+ $ stream ->isReadable ()->willReturn (true );
131+ $ stream ->seek (Argument::type ('integer ' ))->will (function ($ args ) use (&$ position ){
132+ $ position = $ args [0 ];
133+ return true ;
134+ });
135+
136+ $ stream ->eof ()->will (function () use (&$ contents , &$ position ){
137+ return !isset ($ contents [$ position ]);
138+ });
139+
140+ $ stream ->read (Argument::type ('integer ' ))->will (function ($ args ) use (&$ contents , &$ position ){
141+ $ data = substr ($ contents , $ position , $ args [0 ]);
142+ $ position += strlen ($ data );
143+ return $ data ;
144+ });
145+
146+ $ response = (new Response ())
147+ ->withStatus (200 )
148+ ->withHeader ('Content-Range ' , "$ unit $ first- $ last/ $ length " )
149+ ->withBody ($ stream ->reveal ());
150+
151+ ob_start ();
152+ $ this ->emitter ->emit ($ response , $ maxBufferLength );
153+ $ stream ->seek (Argument::type ('integer ' ))->shouldBeCalledTimes ($ seekable ? 1 : 0 );
154+ $ stream ->read (Argument::type ('integer ' ))->shouldBeCalledTimes ($ expectedReads );
155+ $ this ->assertEquals (substr ($ contents , $ first , $ last - $ first + 1 ), ob_get_clean ());
156+ }
157+
61158 public function contentRangeProvider ()
62159 {
63160 return [
0 commit comments