Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 1822ba8

Browse files
committed
added CallbackStream
1 parent e268dd5 commit 1822ba8

File tree

2 files changed

+339
-0
lines changed

2 files changed

+339
-0
lines changed

src/CallbackStream.php

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
6+
* @copyright Copyright (c) 2015 Oscar Otero (http://oscarotero.com) / Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
8+
*/
9+
10+
namespace Zend\Diactoros;
11+
12+
use InvalidArgumentException;
13+
use RuntimeException;
14+
use Psr\Http\Message\StreamInterface;
15+
16+
/**
17+
* Implementation of PSR HTTP streams
18+
*/
19+
class CallbackStream implements StreamInterface
20+
{
21+
/**
22+
* @var callable|null
23+
*/
24+
protected $callback;
25+
26+
/**
27+
* @param callable $callback
28+
* @throws InvalidArgumentException
29+
*/
30+
public function __construct(callable $callback)
31+
{
32+
$this->attach($callback);
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function __toString()
39+
{
40+
return $this->getContents();
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function close()
47+
{
48+
$this->callback = null;
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
public function detach()
55+
{
56+
$callback = $this->callback;
57+
$this->callback = null;
58+
return $callback;
59+
}
60+
61+
/**
62+
* Attach a new callback to the instance.
63+
*
64+
* @param callable $callback
65+
* @throws InvalidArgumentException for callable callback
66+
*/
67+
public function attach(callable $callback)
68+
{
69+
$this->callback = $callback;
70+
}
71+
72+
/**
73+
* {@inheritdoc}
74+
*/
75+
public function getSize()
76+
{
77+
}
78+
79+
/**
80+
* {@inheritdoc}
81+
*/
82+
public function tell()
83+
{
84+
throw new RuntimeException('Callback streams cannot tell position');
85+
}
86+
87+
/**
88+
* {@inheritdoc}
89+
*/
90+
public function eof()
91+
{
92+
return empty($this->callback);
93+
}
94+
95+
/**
96+
* {@inheritdoc}
97+
*/
98+
public function isSeekable()
99+
{
100+
return false;
101+
}
102+
103+
/**
104+
* {@inheritdoc}
105+
*/
106+
public function seek($offset, $whence = SEEK_SET)
107+
{
108+
throw new RuntimeException('Callback streams cannot seek position');
109+
}
110+
111+
/**
112+
* {@inheritdoc}
113+
*/
114+
public function rewind()
115+
{
116+
throw new RuntimeException('Callback streams cannot rewind position');
117+
}
118+
119+
/**
120+
* {@inheritdoc}
121+
*/
122+
public function isWritable()
123+
{
124+
return false;
125+
}
126+
127+
/**
128+
* {@inheritdoc}
129+
*/
130+
public function write($string)
131+
{
132+
throw new RuntimeException('Callback streams cannot write');
133+
}
134+
135+
/**
136+
* {@inheritdoc}
137+
*/
138+
public function isReadable()
139+
{
140+
return false;
141+
}
142+
143+
/**
144+
* {@inheritdoc}
145+
*/
146+
public function read($length)
147+
{
148+
throw new RuntimeException('Callback streams cannot read');
149+
}
150+
151+
/**
152+
* {@inheritdoc}
153+
*/
154+
public function getContents()
155+
{
156+
$callback = $this->detach();
157+
158+
return $callback ? $callback() : '';
159+
}
160+
161+
/**
162+
* {@inheritdoc}
163+
*/
164+
public function getMetadata($key = null)
165+
{
166+
$metadata = [
167+
'eof' => $this->eof(),
168+
'stream_type' => 'callback',
169+
'seekable' => false
170+
];
171+
172+
if (null === $key) {
173+
return $metadata;
174+
}
175+
176+
if (! array_key_exists($key, $metadata)) {
177+
return null;
178+
}
179+
180+
return $metadata[$key];
181+
}
182+
}

test/CallbackStreamTest.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
6+
* @copyright Copyright (c) 2015 Oscar Otero (http://oscarotero.com) / 2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
8+
*/
9+
10+
namespace ZendTest\Diactoros;
11+
12+
use PHPUnit_Framework_TestCase as TestCase;
13+
use Zend\Diactoros\RelativeStream;
14+
use Zend\Diactoros\CallbackStream;
15+
16+
/**
17+
* @covers \Zend\Diactoros\CallbackStream
18+
*/
19+
class CallbackStreamTest extends TestCase
20+
{
21+
public function testToString()
22+
{
23+
$stream = new CallbackStream(function () {
24+
return 'foobarbaz';
25+
});
26+
27+
$ret = $stream->__toString();
28+
$this->assertEquals('foobarbaz', $ret);
29+
}
30+
31+
public function testClose()
32+
{
33+
$stream = new CallbackStream(function () {});
34+
35+
$stream->close();
36+
37+
$callback = $stream->detach();
38+
39+
$this->assertNull($callback);
40+
}
41+
42+
public function testDetach()
43+
{
44+
$callback = function () {};
45+
$stream = new CallbackStream($callback);
46+
$ret = $stream->detach();
47+
$this->assertSame($callback, $ret);
48+
}
49+
50+
public function testEof()
51+
{
52+
$stream = new CallbackStream(function () {});
53+
$ret = $stream->eof();
54+
$this->assertFalse($ret);
55+
56+
$stream->getContents();
57+
$ret = $stream->eof();
58+
$this->assertTrue($ret);
59+
}
60+
61+
public function testGetSize()
62+
{
63+
$stream = new CallbackStream(function () {});
64+
$ret = $stream->getSize();
65+
$this->assertNull($ret);
66+
}
67+
68+
/**
69+
* @expectedException RuntimeException
70+
*/
71+
public function testTell()
72+
{
73+
$stream = new CallbackStream(function () {});
74+
$stream->tell();
75+
}
76+
77+
public function testIsSeekable()
78+
{
79+
$stream = new CallbackStream(function () {});
80+
$ret = $stream->isSeekable();
81+
$this->assertFalse($ret);
82+
}
83+
84+
public function testIsWritable()
85+
{
86+
$stream = new CallbackStream(function () {});
87+
$ret = $stream->isWritable();
88+
$this->assertFalse($ret);
89+
}
90+
91+
public function testIsReadable()
92+
{
93+
$stream = new CallbackStream(function () {});
94+
$ret = $stream->isReadable();
95+
$this->assertFalse($ret);
96+
}
97+
98+
/**
99+
* @expectedException RuntimeException
100+
*/
101+
public function testSeek()
102+
{
103+
$stream = new CallbackStream(function () {});
104+
$stream->seek(0);
105+
}
106+
107+
/**
108+
* @expectedException RuntimeException
109+
*/
110+
public function testRewind()
111+
{
112+
$stream = new CallbackStream(function () {});
113+
$stream->rewind();
114+
}
115+
116+
/**
117+
* @expectedException RuntimeException
118+
*/
119+
public function testWrite()
120+
{
121+
$stream = new CallbackStream(function () {});
122+
$stream->write('foobarbaz');
123+
}
124+
125+
/**
126+
* @expectedException RuntimeException
127+
*/
128+
public function testRead()
129+
{
130+
$stream = new CallbackStream(function () {});
131+
$stream->read(3);
132+
}
133+
134+
public function testGetContents()
135+
{
136+
$stream = new CallbackStream(function () {
137+
return 'foobarbaz';
138+
});
139+
140+
$ret = $stream->getContents();
141+
$this->assertEquals('foobarbaz', $ret);
142+
}
143+
144+
public function testGetMetadata()
145+
{
146+
$stream = new CallbackStream(function () {});
147+
148+
$ret = $stream->getMetadata('stream_type');
149+
$this->assertEquals('callback', $ret);
150+
151+
$ret = $stream->getMetadata('seekable');
152+
$this->assertFalse($ret);
153+
154+
$ret = $stream->getMetadata('eof');
155+
$this->assertFalse($ret);
156+
}
157+
}

0 commit comments

Comments
 (0)