Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ php:
- 7.2

before_install:
- printf "\n" | pecl install swoole
- yes Y | pecl install swoole
- composer self-update

install:
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"phpstan": "vendor/bin/phpstan analyse src --level=0"
},
"require": {
"php": ">=7.1.0",
"igniphp/container": ">=1.1.0",
"igniphp/exception": "^1.0",
"nikic/fast-route": "1.0",
"php": ">=7.1.0",
"psr/container": ">=1.0",
"psr/http-message": ">=1.0",
"psr/log": ">=1.0",
Expand All @@ -34,12 +34,12 @@
"zendframework/zend-stratigility": ">=3.0.0"
},
"suggest": {
"ext-swoole": "for asynchronous support."
"ext-swoole": "for build in http server support."
},
"require-dev": {
"phpunit/phpunit": ">=5.7",
"mockery/mockery": ">=1.0.0",
"league/container": ">=1.0.0",
"phpunit/phpunit": ">=7.0.0",
"phpstan/phpstan": ">=0.9.2"
},
"autoload": {
Expand Down
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
>
<testsuites>
Expand All @@ -22,10 +21,11 @@
<directory suffix=".php">./tests</directory>
<directory suffix=".php">./examples</directory>
<directory suffix=".php">./src/Http/Exception</directory>
<directory suffix=".php">./src/Application/Exception</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="./coverage.clover" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-clover" target="./coverage.clover"/>
</logging>
</phpunit>
2 changes: 1 addition & 1 deletion src/Application/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function get(string $key, $default = null)
*/
public function merge(Config $config): Config
{
$this->config = array_merge_recursive($this->config, $config);
$this->config = array_merge_recursive($this->config, $config->config);

return $this;
}
Expand Down
11 changes: 7 additions & 4 deletions src/Http/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Server
/**
* @var Listener[]
*/
private $listeners;
private $listeners = [];

public function __construct(HttpConfiguration $settings = null)
{
Expand All @@ -48,7 +48,7 @@ public function __construct(HttpConfiguration $settings = null)
$settings = new HttpConfiguration();
}

$this->settings= $settings;
$this->settings = $settings;
}

/**
Expand Down Expand Up @@ -101,14 +101,17 @@ public function getServerStats(): ServerStats
*/
public function start(): void
{
// Create swoole's server instance.
if ($this->settings->isSslEnabled()) {
$flags = SWOOLE_SOCK_TCP | SWOOLE_SSL;
} else {
$flags = SWOOLE_SOCK_TCP;
}

$settings = $this->settings->getSettings();
$this->handler = new Swoole\Http\Server($settings['address'], $settings['port'], SWOOLE_PROCESS, $flags);

if (!defined('IS_TEST') || IS_TEST !== true) {
$this->handler = new Swoole\Http\Server($settings['address'], $settings['port'], SWOOLE_PROCESS, $flags);
}
$this->handler->set($settings);

// Attach listeners.
Expand Down
10 changes: 3 additions & 7 deletions tests/Fixtures/HttpController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,20 @@
use Igni\Http\Controller;
use Igni\Http\Response;
use Igni\Http\Route;
use Igni\Validation\Validator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class HttpController implements Controller
{
public const URI = '/testhttpcontroller';

public function __invoke(ServerRequestInterface $request): ResponseInterface
{
return Response::fromText('test controller');
}

public static function getRoute(): Route
{
Route::get('/testhttpcontroller');
}

public function getValidator(): Validator
{

return Route::get(self::URI);
}
}
74 changes: 74 additions & 0 deletions tests/Functional/Application/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,78 @@ public function testCanInstantiate(): void
$config = new Config();
self::assertInstanceOf(Config::class, $config);
}

public function testThatConfigUnderstandsGlobalConstants(): void
{
$value = '12345';
define('TEST_1', $value);

$config = new Config([
'test' => '${TEST_1}',
]);

self::assertSame($value, $config->get('test'));
}

public function testNestingValues(): void
{
$config = new Config();

$config->set('test.a', 1);
self::assertEquals(['a' => 1], $config->get('test'));
self::assertSame(1, $config->get('test.a'));
}

public function testConfigMerge(): void
{
$a = new Config([
'testA' => [
'a' => 1,
],
'testB' => 'b'
]);

$b = new Config([
'testA' => [
'b' => 2
],
'testB' => 'c',
'testC' => 2
]);

$a->merge($b);

self::assertSame(
[
'testA' => [
'a' => 1,
'b' => 2
],
'testB' => ['b', 'c'],
'testC' => 2,
],
$a->toArray()
);
}

public function testToArray(): void
{
$config = new Config();
$config->set('a.b.c' , 1);
$config->set('b.c', 2);
$config->set('c', 3);

self::assertSame([
'a' => [
'b' => [
'c' => 1,
],
],
'b' => [
'c' => 2,
],
'c' => 3,
], $config->toArray());
}

}
68 changes: 68 additions & 0 deletions tests/Functional/Http/Controller/ControllerAggregateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);

namespace IgniTest\Funcational\Http\Controller;

use Igni\Http\Controller\ControllerAggregate;
use Igni\Http\Route;
use Igni\Http\Router;
use IgniTest\Fixtures\HttpController;
use PHPUnit\Framework\TestCase;
use Mockery;

class ControllerAggregateTest extends TestCase
{
public function testCanInstantiate(): void
{
self::assertInstanceOf(
ControllerAggregate::class,
new ControllerAggregate(Mockery::mock(Router::class))
);
}

public function testAddCallableController(): void
{
$controller = function() {};
$route = Mockery::mock(Route::class);
$route->shouldReceive('delegate')
->withArgs([$controller]);

$router = Mockery::mock(Router::class);
$router->shouldReceive('addRoute')
->withArgs([$route]);
$aggregate = new ControllerAggregate($router);

self::assertNull($aggregate->add($controller, $route));
}

public function testAddControllerClass(): void
{
$controller = HttpController::class;

$router = Mockery::mock(Router::class);
$router->shouldReceive('addRoute')
->withArgs(function($route) {
self::assertInstanceOf(Route::class, $route);
self::assertSame(HttpController::URI, $route->getExpression());
return true;
});
$aggregate = new ControllerAggregate($router);

self::assertNull($aggregate->add($controller));
}

public function testAddControllerObject(): void
{
$controller = new HttpController();

$router = Mockery::mock(Router::class);
$router->shouldReceive('addRoute')
->withArgs(function($route) {
self::assertInstanceOf(Route::class, $route);
self::assertSame(HttpController::URI, $route->getExpression());
return true;
});
$aggregate = new ControllerAggregate($router);

self::assertNull($aggregate->add($controller));
}
}
92 changes: 80 additions & 12 deletions tests/Unit/Http/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,98 @@ public function testCanInstantiate(): void
self::assertInstanceOf(Server::class, new Server());
}

public function testAddListener(): void
public function testAddingListeners(): void
{
// Mock listeners.
$noopListener = Mockery::mock(Server\Listener::class);
$onRequestListener = Mockery::mock(Server\OnRequest::class);
$onConnectListener = Mockery::mock(Server\OnConnect::class);
$onShutDownListener = Mockery::mock(Server\OnShutdown::class);
$onStartListener = Mockery::mock(Server\OnStart::class);

// Mock swoole server.
$swoole = Mockery::mock(\Swoole\Server::class . '[on]', ['0.0.0.0']);

$server = new Server();
$swoole = $this->initializeSwoole($server);
$swoole->shouldReceive('on')
->with('Request', Mockery::any());
$swoole->shouldReceive('on')
->with('Connect', Mockery::any());
$swoole->shouldReceive('on')
->with('Shutdown', Mockery::any());
$swoole->shouldReceive('on')
->with('Start', Mockery::any());
$swoole->shouldReceive('set');
$swoole->shouldReceive('start');
$server->addListener($noopListener);
self::assertCount(1, self::readAttribute($server, 'listeners'));
self::assertTrue($server->hasListener($noopListener));

$server->addListener($onRequestListener);
self::assertCount(2, self::readAttribute($server, 'listeners'));
self::assertTrue($server->hasListener($onRequestListener));

$server->addListener($onConnectListener);
$server->addListener($onShutDownListener);
$server->addListener($onStartListener);
self::assertCount(5, self::readAttribute($server, 'listeners'));
$server->start();
}

public function testGetClientStats(): void
{
$server = new Server();
$server->addListener($noopListener);
$swoole = $this->initializeSwoole($server);
$swoole->shouldReceive('getClientInfo')
->withArgs([1])
->andReturn([]);

self::assertInstanceOf(Server\ClientStats::class, $server->getClientStats(1));
}

public function testGetServerStats(): void
{
$server = new Server();
$swoole = $this->initializeSwoole($server);
$swoole->shouldReceive('stats')
->andReturn([]);

self::assertInstanceOf(Server\ServerStats::class, $server->getServerStats());
}

public function testStartWithSsl(): void
{
$settings = new Server\HttpConfiguration();
$settings->enableSsl('a', 'b');
$server = new Server($settings);
$swoole = $this->initializeSwoole($server);
$swoole->shouldReceive('start');
$swoole->shouldReceive('set')
->withArgs(function (array $config) {
self::assertSame(
[
'address' => '0.0.0.0',
'port' => 8080,
'ssl_cert_file' => 'a',
'ssl_key_file' => 'b',
],
$config
);

return true;
});

self::assertNull($server->start());
}

private function initializeSwoole(Server $server): Mockery\MockInterface
{
// Replace swoole instance with generic mock object.
$swoole = Mockery::mock(\stdClass::class);

$reflectionApi = new \ReflectionClass(Server::class);
$listenersProperty = $reflectionApi->getProperty('listeners');
$listenersProperty->setAccessible(true);
$handlerProperty = $reflectionApi->getProperty('handler');
$handlerProperty->setAccessible(true);

self::assertCount(1, $listenersProperty->getValue($server));

$handlerProperty->setValue($server, $swoole);
$server->addListener($onRequestListener);
self::assertCount(2, $listenersProperty->getValue($server));

return $swoole;
}
}
Loading