Skip to content

Commit 8cac929

Browse files
committed
Merge branch 'refs/heads/clue-tests'
2 parents 32f988c + 7bab695 commit 8cac929

File tree

8 files changed

+438
-0
lines changed

8 files changed

+438
-0
lines changed

phpunit.xml.dist

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit backupGlobals="false"
4+
backupStaticAttributes="false"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
syntaxCheck="false"
12+
bootstrap="tests/bootstrap.php"
13+
>
14+
<testsuites>
15+
<testsuite name="React Test Suite">
16+
<directory>./tests/</directory>
17+
</testsuite>
18+
</testsuites>
19+
20+
<filter>
21+
<whitelist>
22+
<directory>./src/</directory>
23+
</whitelist>
24+
</filter>
25+
</phpunit>

tests/ConnectionTest.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace React\Tests\Socket;
4+
5+
use React\Socket\Connection;
6+
use React\Socket\Server;
7+
use React\EventLoop\StreamSelectLoop;
8+
9+
class ConnectionTest extends TestCase
10+
{
11+
/**
12+
* @covers React\Socket\Connection::getRemoteAddress
13+
*/
14+
public function testGetRemoteAddress()
15+
{
16+
$loop = new StreamSelectLoop();
17+
$server = new Server($loop);
18+
$server->listen(0);
19+
20+
$class = new \ReflectionClass('React\\Socket\\Server');
21+
$master = $class->getProperty('master');
22+
$master->setAccessible(true);
23+
24+
$client = stream_socket_client('tcp://localhost:' . $server->getPort());
25+
26+
$class = new \ReflectionClass('React\\Socket\\Connection');
27+
$method = $class->getMethod('parseAddress');
28+
$method->setAccessible(true);
29+
30+
$servConn = new Connection($server->master, $loop);
31+
32+
$mock = $this->createCallableMock();
33+
$mock
34+
->expects($this->once())
35+
->method('__invoke')
36+
->with($method->invokeArgs($servConn, array(stream_socket_get_name($master->getValue($server), false))))
37+
;
38+
39+
$server->on('connection', function ($conn) use ($mock) {
40+
$mock($conn->getRemoteAddress());
41+
});
42+
$loop->tick();
43+
}
44+
45+
public function remoteAddressProvider()
46+
{
47+
return array(
48+
array('192.168.1.120', '192.168.1.120:12345')
49+
, array('9999:0000:aaaa:bbbb:cccc:dddd:eeee:ffff', '[9999:0000:aaaa:bbbb:cccc:dddd:eeee:ffff]:12345')
50+
, array('10.0.0.1', '10.0.0.1:80')
51+
);
52+
}
53+
54+
/**
55+
* @dataProvider remoteAddressProvider
56+
* @covers React\Socket\Connection::parseAddress
57+
*/
58+
public function testParseAddress($expected, $given)
59+
{
60+
$class = new \ReflectionClass('React\\Socket\\Connection');
61+
$method = $class->getMethod('parseAddress');
62+
$method->setAccessible(true);
63+
64+
$socket = fopen('php://temp', 'r');
65+
$loop = $this->createLoopMock();
66+
67+
$conn = new Connection($socket, $loop);
68+
$result = $method->invokeArgs($conn, array($given));
69+
70+
$this->assertEquals($expected, $result);
71+
}
72+
73+
private function createLoopMock()
74+
{
75+
return $this->getMock('React\EventLoop\LoopInterface');
76+
}
77+
}

tests/ServerTest.php

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<?php
2+
3+
namespace React\Tests\Socket;
4+
5+
use React\Socket\Server;
6+
use React\EventLoop\StreamSelectLoop;
7+
8+
class ServerTest extends TestCase
9+
{
10+
private $loop;
11+
private $server;
12+
private $port;
13+
14+
private function createLoop()
15+
{
16+
return new StreamSelectLoop();
17+
}
18+
19+
/**
20+
* @covers React\Socket\Server::__construct
21+
* @covers React\Socket\Server::listen
22+
* @covers React\Socket\Server::getPort
23+
*/
24+
public function setUp()
25+
{
26+
$this->loop = $this->createLoop();
27+
$this->server = new Server($this->loop);
28+
$this->server->listen(0);
29+
30+
$this->port = $this->server->getPort();
31+
}
32+
33+
/**
34+
* @covers React\EventLoop\StreamSelectLoop::tick
35+
* @covers React\Socket\Server::handleConnection
36+
* @covers React\Socket\Server::createConnection
37+
*/
38+
public function testConnection()
39+
{
40+
$client = stream_socket_client('tcp://localhost:'.$this->port);
41+
42+
$this->server->on('connection', $this->expectCallableOnce());
43+
$this->loop->tick();
44+
}
45+
46+
/**
47+
* @covers React\EventLoop\StreamSelectLoop::tick
48+
* @covers React\Socket\Server::handleConnection
49+
* @covers React\Socket\Server::createConnection
50+
*/
51+
public function testConnectionWithManyClients()
52+
{
53+
$client1 = stream_socket_client('tcp://localhost:'.$this->port);
54+
$client2 = stream_socket_client('tcp://localhost:'.$this->port);
55+
$client3 = stream_socket_client('tcp://localhost:'.$this->port);
56+
57+
$this->server->on('connection', $this->expectCallableExactly(3));
58+
$this->loop->tick();
59+
$this->loop->tick();
60+
$this->loop->tick();
61+
}
62+
63+
/**
64+
* @covers React\EventLoop\StreamSelectLoop::tick
65+
* @covers React\Socket\Connection::handleData
66+
*/
67+
public function testDataWithNoData()
68+
{
69+
$client = stream_socket_client('tcp://localhost:'.$this->port);
70+
71+
$mock = $this->expectCallableNever();
72+
73+
$this->server->on('connection', function ($conn) use ($mock) {
74+
$conn->on('data', $mock);
75+
});
76+
$this->loop->tick();
77+
$this->loop->tick();
78+
}
79+
80+
/**
81+
* @covers React\EventLoop\StreamSelectLoop::tick
82+
* @covers React\Socket\Connection::handleData
83+
*/
84+
public function testData()
85+
{
86+
$client = stream_socket_client('tcp://localhost:'.$this->port);
87+
88+
fwrite($client, "foo\n");
89+
90+
$mock = $this->createCallableMock();
91+
$mock
92+
->expects($this->once())
93+
->method('__invoke')
94+
->with("foo\n");
95+
96+
$this->server->on('connection', function ($conn) use ($mock) {
97+
$conn->on('data', $mock);
98+
});
99+
$this->loop->tick();
100+
$this->loop->tick();
101+
}
102+
103+
/**
104+
* Test data sent from python language
105+
*
106+
* @covers React\EventLoop\StreamSelectLoop::tick
107+
* @covers React\Socket\Connection::handleData
108+
*/
109+
public function testDataSentFromPy()
110+
{
111+
$client = stream_socket_client('tcp://localhost:' . $this->port);
112+
fwrite($client, "foo\n");
113+
stream_socket_shutdown($client, STREAM_SHUT_WR);
114+
115+
$mock = $this->createCallableMock();
116+
$mock
117+
->expects($this->once())
118+
->method('__invoke')
119+
->with("foo\n");
120+
121+
122+
$this->server->on('connection', function ($conn) use ($mock) {
123+
$conn->on('data', $mock);
124+
});
125+
$this->loop->tick();
126+
$this->loop->tick();
127+
}
128+
129+
public function testFragmentedMessage()
130+
{
131+
$client = stream_socket_client('tcp://localhost:' . $this->port);
132+
133+
fwrite($client, "Hello World!\n");
134+
135+
$mock = $this->createCallableMock();
136+
$mock
137+
->expects($this->once())
138+
->method('__invoke')
139+
->with("He");
140+
141+
$this->server->on('connection', function ($conn) use ($mock) {
142+
$conn->bufferSize = 2;
143+
$conn->on('data', $mock);
144+
});
145+
$this->loop->tick();
146+
$this->loop->tick();
147+
}
148+
149+
/**
150+
* @covers React\EventLoop\StreamSelectLoop::tick
151+
*/
152+
public function testDisconnectWithoutDisconnect()
153+
{
154+
$client = stream_socket_client('tcp://localhost:'.$this->port);
155+
156+
$mock = $this->expectCallableNever();
157+
158+
$this->server->on('connection', function ($conn) use ($mock) {
159+
$conn->on('end', $mock);
160+
});
161+
$this->loop->tick();
162+
$this->loop->tick();
163+
}
164+
165+
/**
166+
* @covers React\EventLoop\StreamSelectLoop::tick
167+
* @covers React\Socket\Connection::end
168+
*/
169+
public function testDisconnect()
170+
{
171+
$client = stream_socket_client('tcp://localhost:'.$this->port);
172+
173+
fclose($client);
174+
175+
$mock = $this->expectCallableOnce();
176+
177+
$this->server->on('connection', function ($conn) use ($mock) {
178+
$conn->on('end', $mock);
179+
});
180+
$this->loop->tick();
181+
$this->loop->tick();
182+
}
183+
184+
/**
185+
* @covers React\Socket\Server::shutdown
186+
*/
187+
public function tearDown()
188+
{
189+
if ($this->server) {
190+
$this->server->shutdown();
191+
}
192+
}
193+
}

tests/Stub/CallableStub.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace React\Tests\Socket\Stub;
4+
5+
class CallableStub
6+
{
7+
public function __invoke()
8+
{
9+
}
10+
}

tests/Stub/ConnectionStub.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace React\Tests\Socket\Stub;
4+
5+
use Evenement\EventEmitter;
6+
use React\Socket\ConnectionInterface;
7+
use React\Stream\WritableStreamInterface;
8+
use React\Stream\Util;
9+
10+
class ConnectionStub extends EventEmitter implements ConnectionInterface
11+
{
12+
private $data = '';
13+
14+
public function isReadable()
15+
{
16+
return true;
17+
}
18+
19+
public function isWritable()
20+
{
21+
return true;
22+
}
23+
24+
public function pause()
25+
{
26+
}
27+
28+
public function resume()
29+
{
30+
}
31+
32+
public function pipe(WritableStreamInterface $dest, array $options = array())
33+
{
34+
Util::pipe($this, $dest, $options);
35+
36+
return $dest;
37+
}
38+
39+
public function write($data)
40+
{
41+
$this->data .= $data;
42+
43+
return true;
44+
}
45+
46+
public function end($data = null)
47+
{
48+
}
49+
50+
public function close()
51+
{
52+
}
53+
54+
public function getData()
55+
{
56+
return $this->data;
57+
}
58+
59+
public function getRemoteAddress()
60+
{
61+
return '127.0.0.1';
62+
}
63+
}

tests/Stub/ServerStub.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace React\Tests\Socket\Stub;
4+
5+
use Evenement\EventEmitter;
6+
use React\Socket\ServerInterface;
7+
8+
class ServerStub extends EventEmitter implements ServerInterface
9+
{
10+
public function listen($port, $host = '127.0.0.1')
11+
{
12+
}
13+
14+
public function getPort()
15+
{
16+
return 80;
17+
}
18+
19+
public function shutdown()
20+
{
21+
}
22+
}

0 commit comments

Comments
 (0)