Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
namespace React\Tests\Stream;
4
 
5
use React\Stream\Buffer;
6
 
7
class BufferTest extends TestCase
8
{
9
    /**
10
     * @covers React\Stream\Buffer::__construct
11
     */
12
    public function testConstructor()
13
    {
14
        $stream = fopen('php://temp', 'r+');
15
        $loop = $this->createLoopMock();
16
 
17
        $buffer = new Buffer($stream, $loop);
18
        $buffer->on('error', $this->expectCallableNever());
19
    }
20
 
21
    /**
22
     * @covers React\Stream\Buffer::write
23
     * @covers React\Stream\Buffer::handleWrite
24
     */
25
    public function testWrite()
26
    {
27
        $stream = fopen('php://temp', 'r+');
28
        $loop = $this->createWriteableLoopMock();
29
 
30
        $buffer = new Buffer($stream, $loop);
31
        $buffer->on('error', $this->expectCallableNever());
32
 
33
        $buffer->write("foobar\n");
34
        rewind($stream);
35
        $this->assertSame("foobar\n", fread($stream, 1024));
36
    }
37
 
38
    /**
39
     * @covers React\Stream\Buffer::write
40
     * @covers React\Stream\Buffer::handleWrite
41
     */
42
    public function testWriteReturnsFalseWhenBufferIsFull()
43
    {
44
        $stream = fopen('php://temp', 'r+');
45
        $loop = $this->createWriteableLoopMock();
46
        $loop->preventWrites = true;
47
 
48
        $buffer = new Buffer($stream, $loop);
49
        $buffer->softLimit = 4;
50
        $buffer->on('error', $this->expectCallableNever());
51
 
52
        $this->assertTrue($buffer->write("foo"));
53
        $loop->preventWrites = false;
54
        $this->assertFalse($buffer->write("bar\n"));
55
    }
56
 
57
    /**
58
     * @covers React\Stream\Buffer::write
59
     * @covers React\Stream\Buffer::handleWrite
60
     */
61
    public function testWriteDetectsWhenOtherSideIsClosed()
62
    {
63
        list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
64
 
65
        $loop = $this->createWriteableLoopMock();
66
 
67
        $buffer = new Buffer($a, $loop);
68
        $buffer->softLimit = 4;
69
        $buffer->on('error', $this->expectCallableOnce());
70
 
71
        fclose($b);
72
 
73
        $buffer->write("foo");
74
    }
75
 
76
    /**
77
     * @covers React\Stream\Buffer::write
78
     * @covers React\Stream\Buffer::handleWrite
79
     */
80
    public function testDrain()
81
    {
82
        $stream = fopen('php://temp', 'r+');
83
        $loop = $this->createWriteableLoopMock();
84
        $loop->preventWrites = true;
85
 
86
        $buffer = new Buffer($stream, $loop);
87
        $buffer->softLimit = 4;
88
        $buffer->on('error', $this->expectCallableNever());
89
        $buffer->on('drain', $this->expectCallableOnce());
90
 
91
        $buffer->write("foo");
92
        $loop->preventWrites = false;
93
        $buffer->listening = false;
94
        $buffer->write("bar\n");
95
    }
96
 
97
    /**
98
     * @covers React\Stream\Buffer::write
99
     * @covers React\Stream\Buffer::handleWrite
100
     */
101
    public function testWriteInDrain()
102
    {
103
        $writeStreams = array();
104
 
105
        $stream = fopen('php://temp', 'r+');
106
        $loop = $this->createWriteableLoopMock();
107
        $loop->preventWrites = true;
108
 
109
        $buffer = new Buffer($stream, $loop);
110
        $buffer->softLimit = 2;
111
        $buffer->on('error', $this->expectCallableNever());
112
 
113
        $buffer->once('drain', function ($buffer) {
114
            $buffer->listening = false;
115
            $buffer->write("bar\n");
116
        });
117
 
118
        $this->assertFalse($buffer->write("foo"));
119
        $loop->preventWrites = false;
120
        $buffer->listening = false;
121
        $buffer->write("\n");
122
 
123
        fseek($stream, 0);
124
        $this->assertSame("foo\nbar\n", stream_get_contents($stream));
125
    }
126
 
127
    /**
128
     * @covers React\Stream\Buffer::end
129
     */
130
    public function testEnd()
131
    {
132
        $stream = fopen('php://temp', 'r+');
133
        $loop = $this->createLoopMock();
134
 
135
        $buffer = new Buffer($stream, $loop);
136
        $buffer->on('error', $this->expectCallableNever());
137
        $buffer->on('close', $this->expectCallableOnce());
138
 
139
        $this->assertTrue($buffer->isWritable());
140
        $buffer->end();
141
        $this->assertFalse($buffer->isWritable());
142
    }
143
 
144
    /**
145
     * @covers React\Stream\Buffer::end
146
     */
147
    public function testEndWithData()
148
    {
149
        $stream = fopen('php://temp', 'r+');
150
        $loop = $this->createWriteableLoopMock();
151
 
152
        $buffer = new Buffer($stream, $loop);
153
        $buffer->on('error', $this->expectCallableNever());
154
        $buffer->on('close', $this->expectCallableOnce());
155
 
156
        $buffer->end('final words');
157
 
158
        rewind($stream);
159
        $this->assertSame('final words', stream_get_contents($stream));
160
    }
161
 
162
    /**
163
     * @covers React\Stream\Buffer::isWritable
164
     * @covers React\Stream\Buffer::close
165
     */
166
    public function testClose()
167
    {
168
        $stream = fopen('php://temp', 'r+');
169
        $loop = $this->createLoopMock();
170
 
171
        $buffer = new Buffer($stream, $loop);
172
        $buffer->on('error', $this->expectCallableNever());
173
        $buffer->on('close', $this->expectCallableOnce());
174
 
175
        $this->assertTrue($buffer->isWritable());
176
        $buffer->close();
177
        $this->assertFalse($buffer->isWritable());
178
    }
179
 
180
    /**
181
     * @covers React\Stream\Buffer::write
182
     * @covers React\Stream\Buffer::close
183
     */
184
    public function testWritingToClosedBufferShouldNotWriteToStream()
185
    {
186
        $stream = fopen('php://temp', 'r+');
187
        $loop = $this->createWriteableLoopMock();
188
 
189
        $buffer = new Buffer($stream, $loop);
190
        $buffer->close();
191
 
192
        $buffer->write('foo');
193
 
194
        rewind($stream);
195
        $this->assertSame('', stream_get_contents($stream));
196
    }
197
 
198
    /**
199
     * @covers React\Stream\Buffer::handleWrite
200
     * @covers React\Stream\Buffer::errorHandler
201
     */
202
    public function testError()
203
    {
204
        $stream = null;
205
        $loop = $this->createWriteableLoopMock();
206
 
207
        $error = null;
208
 
209
        $buffer = new Buffer($stream, $loop);
210
        $buffer->on('error', function ($message) use (&$error) {
211
            $error = $message;
212
        });
213
 
214
        $buffer->write('Attempting to write to bad stream');
215
        $this->assertInstanceOf('Exception', $error);
216
        $this->assertSame('Tried to write to invalid stream.', $error->getMessage());
217
    }
218
 
219
    public function testWritingToClosedStream()
220
    {
221
        if ('Darwin' === PHP_OS) {
222
            $this->markTestSkipped('OS X issue with shutting down pair for writing');
223
        }
224
 
225
        list($a, $b) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
226
        $loop = $this->createWriteableLoopMock();
227
 
228
        $error = null;
229
 
230
        $buffer = new Buffer($a, $loop);
231
        $buffer->on('error', function($message) use (&$error) {
232
            $error = $message;
233
        });
234
 
235
        $buffer->write('foo');
236
        stream_socket_shutdown($b, STREAM_SHUT_RD);
237
        stream_socket_shutdown($a, STREAM_SHUT_RD);
238
        $buffer->write('bar');
239
 
240
        $this->assertInstanceOf('Exception', $error);
241
        $this->assertSame('Tried to write to closed stream.', $error->getMessage());
242
    }
243
 
244
    private function createWriteableLoopMock()
245
    {
246
        $loop = $this->createLoopMock();
247
        $loop->preventWrites = false;
248
        $loop
249
            ->expects($this->any())
250
            ->method('addWriteStream')
251
            ->will($this->returnCallback(function ($stream, $listener) use ($loop) {
252
                if (!$loop->preventWrites) {
253
                    call_user_func($listener, $stream);
254
                }
255
            }));
256
 
257
        return $loop;
258
    }
259
 
260
    private function createLoopMock()
261
    {
262
        return $this->getMock('React\EventLoop\LoopInterface');
263
    }
264
}