Unit tests
Socket interface update Server testing Connection setting
This commit is contained in:
parent
4129036356
commit
75afa73826
@ -33,6 +33,14 @@ class App implements ApplicationInterface {
|
||||
*/
|
||||
protected $_buffer_size = 4096;
|
||||
|
||||
/**
|
||||
* After run() is called, the server will loop as long as this is true
|
||||
* This is here for unit testing purposes
|
||||
* @var bool
|
||||
* @internal
|
||||
*/
|
||||
protected $_run = true;
|
||||
|
||||
public function __construct(ApplicationInterface $application = null) {
|
||||
if (null === $application) {
|
||||
throw new \UnexpectedValueException("Server requires an application to run off of");
|
||||
@ -79,7 +87,7 @@ class App implements ApplicationInterface {
|
||||
|
||||
do {
|
||||
$this->loop($host);
|
||||
} while (true);
|
||||
} while ($this->_run);
|
||||
}
|
||||
|
||||
protected function loop(SocketInterface $host) {
|
||||
|
@ -4,6 +4,8 @@ use Ratchet\SocketInterface;
|
||||
|
||||
/**
|
||||
* @todo Consider if this belongs under Application
|
||||
* @todo Construct should have StorageInterface, currently all is memory, should be different ones
|
||||
* That will allow a queue system, communication between threaded connections
|
||||
*/
|
||||
class Connection {
|
||||
protected $_data = array();
|
||||
|
@ -99,8 +99,17 @@ interface SocketInterface {
|
||||
*/
|
||||
function recv(&$buf, $len, $flags);
|
||||
|
||||
// @todo Figure out how to break this out to not do pass by reference
|
||||
// function select(array &$read, array &$write, array &$except, $tv_sec, $tv_usec = 0);
|
||||
/**
|
||||
* @param array|Iterator
|
||||
* @param array|Iterator
|
||||
* @param array|Iterator
|
||||
* @param int
|
||||
* @param int
|
||||
* @return int
|
||||
* @throws Exception
|
||||
* @todo Figure out how to break this out to not do pass by reference
|
||||
*/
|
||||
function select(&$read, &$write, &$except, $tv_sec, $tv_usec = 0);
|
||||
|
||||
/**
|
||||
* Sets the blocking mode on the socket resource
|
||||
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
namespace Ratchet\Tests;
|
||||
use Ratchet\Application\Server\App as Server;
|
||||
namespace Ratchet\Tests\Application\Server;
|
||||
use Ratchet\Application\Server\App as ServerApp;
|
||||
use Ratchet\Tests\Mock\FakeSocket as Socket;
|
||||
use Ratchet\Tests\Mock\Application as TestApp;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Server\App
|
||||
* @covers Ratchet\Application\Server\App
|
||||
*/
|
||||
class AppTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_catalyst;
|
||||
@ -15,7 +15,12 @@ class AppTest extends \PHPUnit_Framework_TestCase {
|
||||
public function setUp() {
|
||||
$this->_catalyst = new Socket;
|
||||
$this->_app = new TestApp;
|
||||
$this->_server = new Server($this->_app);
|
||||
$this->_server = new ServerApp($this->_app);
|
||||
|
||||
$ref = new \ReflectionClass('\Ratchet\Application\Server\App');
|
||||
$prop = $ref->getProperty('_run');
|
||||
$prop->setAccessible(true);
|
||||
$prop->setValue($this->_server, false);
|
||||
}
|
||||
|
||||
protected function getPrivateProperty($class, $name) {
|
||||
@ -26,14 +31,40 @@ class AppTest extends \PHPUnit_Framework_TestCase {
|
||||
return $property->getValue($class);
|
||||
}
|
||||
|
||||
public function testBindToInvalidAddress() {
|
||||
return $this->markTestIncomplete();
|
||||
protected function getMasterConnection() {
|
||||
$connections = $this->getPrivateProperty($this->_server, '_connections');
|
||||
return array_pop($connections);
|
||||
}
|
||||
|
||||
$app = new TestApp();
|
||||
public function testDoNotAllowStacklessServer() {
|
||||
$this->setExpectedException('UnexpectedValueException');
|
||||
new ServerApp;
|
||||
}
|
||||
|
||||
$this->_server->attatchReceiver($app);
|
||||
$this->setExpectedException('\\Ratchet\\Exception');
|
||||
public function testOnOpenPassesClonedSocket() {
|
||||
$this->_server->run($this->_catalyst);
|
||||
$master = $this->getMasterConnection();
|
||||
|
||||
$this->_server->run('la la la', 80);
|
||||
$this->_server->onOpen($master);
|
||||
$clone = $this->_app->_conn_open;
|
||||
|
||||
$this->assertEquals($master->getID() + 1, $clone->getID());
|
||||
}
|
||||
|
||||
public function testOnMessageSendsToApp() {
|
||||
$this->_server->run($this->_catalyst);
|
||||
$master = $this->getMasterConnection();
|
||||
|
||||
// todo, make FakeSocket better, set data in select, recv to pass data when called, then do this check
|
||||
// that way can mimic the TCP fragmentation/buffer situation
|
||||
|
||||
$this->_server->onOpen($master);
|
||||
$clone = $this->_app->_conn_open;
|
||||
|
||||
// $this->_server->run($this->_catalyst);
|
||||
$msg = 'Hello World!';
|
||||
$this->_server->onMessage($clone, $msg);
|
||||
|
||||
$this->assertEquals($msg, $this->_app->_msg_recv);
|
||||
}
|
||||
}
|
@ -1,33 +1,83 @@
|
||||
<?php
|
||||
namespace Ratchet\Tests\Mock;
|
||||
use Ratchet\SocketInterface;
|
||||
use Ratchet\Socket as RealSocket;
|
||||
|
||||
class FakeSocket extends RealSocket {
|
||||
protected $_arguments = array();
|
||||
protected $_options = array();
|
||||
class FakeSocket implements SocketInterface {
|
||||
public $_arguments = array();
|
||||
public $_options = array();
|
||||
|
||||
public function __construct($domain = null, $type = null, $protocol = null) {
|
||||
list($this->_arguments['domain'], $this->_arguments['type'], $this->_arguments['protocol']) = static::getConfig($domain, $type, $protocol);
|
||||
protected $_id = 1;
|
||||
|
||||
public $_last = array();
|
||||
|
||||
public function getResource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return '1';
|
||||
return (string)$this->_id;
|
||||
}
|
||||
|
||||
public function __construct($domain = null, $type = null, $protocol = null) {
|
||||
list($this->_arguments['domain'], $this->_arguments['type'], $this->_arguments['protocol']) = array(1, 1, 1);
|
||||
}
|
||||
|
||||
public function __clone() {
|
||||
$this->_id++;
|
||||
}
|
||||
|
||||
public function deliver($message) {
|
||||
$this->write($message, strlen($message));
|
||||
}
|
||||
|
||||
public function bind($address, $port = 0) {
|
||||
$this->_last['bind'] = array($address, $port);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function close() {
|
||||
}
|
||||
|
||||
public function connect($address, $port = 0) {
|
||||
$this->_last['connect'] = array($address, $port = 0);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRemoteAddress() {
|
||||
return '127.0.0.1';
|
||||
}
|
||||
|
||||
public function get_option($level, $optname) {
|
||||
return $this->_options[$level][$optname];
|
||||
}
|
||||
|
||||
public function listen($backlog = 0) {
|
||||
$this->_last['listen'] = array($backlog);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function read($length, $type = PHP_BINARY_READ) {
|
||||
$this->_last['read'] = array($length, $type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function recv(&$buf, $len, $flags) {
|
||||
$this->_last['recv'] = array($buf, $len, $flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function select(&$read, &$write, &$except, $tv_sec, $tv_usec = 0) {
|
||||
$this->_last['select'] = array($read, $write, $except, $tv_sec, $tv_usec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function set_block() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function set_nonblock() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function set_option($level, $optname, $optval) {
|
||||
@ -38,6 +88,13 @@ class FakeSocket extends RealSocket {
|
||||
$this->_options[$level][$optname] = $optval;
|
||||
}
|
||||
|
||||
public function shutdown($how = 2) {
|
||||
$this->_last['shutdown'] = array($how);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function write($buffer, $length = 0) {
|
||||
$this->_last['write'] = array($buffer, $length);
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -7,7 +7,14 @@ use Ratchet\Tests\Mock\FakeSocket;
|
||||
* @covers Ratchet\Resource\Connection
|
||||
*/
|
||||
class ConnectionTest extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @var Ratchet\Tests\Mock\FakeSocket
|
||||
*/
|
||||
protected $_fs;
|
||||
|
||||
/**
|
||||
* @var Ratchet\Resource\Connection
|
||||
*/
|
||||
protected $_c;
|
||||
|
||||
public function setUp() {
|
||||
@ -18,6 +25,9 @@ class ConnectionTest extends \PHPUnit_Framework_TestCase {
|
||||
public static function keyAndValProvider() {
|
||||
return array(
|
||||
array('hello', 'world')
|
||||
, array('herp', 'derp')
|
||||
, array('depth', array('hell', 'yes'))
|
||||
, array('moar', array('hellz' => 'yes'))
|
||||
);
|
||||
}
|
||||
|
||||
@ -38,6 +48,7 @@ class ConnectionTest extends \PHPUnit_Framework_TestCase {
|
||||
$ret = $this->_c->faked;
|
||||
}
|
||||
|
||||
// I think I'll be removing this feature from teh lib soon, so this UT will be removed when it fails
|
||||
public function testLambdaReturnValueOnGet() {
|
||||
$this->_c->lambda = function() { return 'Hello World!'; };
|
||||
$this->assertEquals('Hello World!', $this->_c->lambda);
|
||||
|
@ -22,12 +22,14 @@ class SocketTest extends \PHPUnit_Framework_TestCase {
|
||||
$this->_socket = new Socket();
|
||||
}
|
||||
|
||||
/* (1): I may or may not re-enable this test (need to add code back to FakeSocket), not sure if I'll keep this feature at all
|
||||
public function testGetDefaultConfigForConstruct() {
|
||||
$ref_conf = static::getMethod('getConfig');
|
||||
$config = $ref_conf->invokeArgs($this->_socket, array());
|
||||
|
||||
$this->assertEquals(array_values(Socket::$_defaults), $config);
|
||||
}
|
||||
/**/
|
||||
|
||||
public function testInvalidConstructorArguments() {
|
||||
$this->setExpectedException('\\Ratchet\\Exception');
|
||||
@ -48,6 +50,7 @@ class SocketTest extends \PHPUnit_Framework_TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* (1)
|
||||
* @dataProvider asArrayProvider
|
||||
* /
|
||||
public function testMethodMungforselectReturnsExpectedValues($output, $input) {
|
||||
@ -57,9 +60,10 @@ class SocketTest extends \PHPUnit_Framework_TestCase {
|
||||
$this->assertEquals($return, $output);
|
||||
}
|
||||
|
||||
public function testMethodMungforselectRejectsNonTraversable() {
|
||||
public function NOPEtestMethodMungforselectRejectsNonTraversable() {
|
||||
$this->setExpectedException('\\InvalidArgumentException');
|
||||
$method = static::getMethod('mungForSelect');
|
||||
$method->invokeArgs($this->_socket, array('I am upset with PHP ATM'));
|
||||
}
|
||||
*/
|
||||
}
|
Loading…
Reference in New Issue
Block a user