Skip to content

Commit

Permalink
- Adding getRoutes() method to Router class.
Browse files Browse the repository at this point in the history
- Dropping MiddlewareManager::remove() method as nothing was using it.
- Adding test coverage for MiddlewareManager.
- Adding additional test coverage for Router.
- Adding test coverage for \class_method()
  • Loading branch information
Brent Scheffler committed Aug 29, 2019
1 parent afe1106 commit 87efec3
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 47 deletions.
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,10 @@
"symfony\/var-dumper": "^4.2",
"php-coveralls\/php-coveralls": "^2.1",
"nimbly\/capsule": "^0.6.0"
}
},
"autoload-dev": {
"psr-4": {
"Limber\\Tests\\": "tests\/"
}
}
}
26 changes: 11 additions & 15 deletions src/Middleware/MiddlewareManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,17 @@ public function __construct(array $layers = [])
public function add(MiddlewareLayerInterface $layer): void
{
$this->middlewareStack[] = $layer;
}
}

/**
* Remove a layer by its classname.
*
* @param string $middlewareClass
*/
public function remove(string $middlewareClass): void
{
foreach( $this->middlewareStack as $i => $middleware ){
if( $middleware instanceof $middlewareClass ){
unset($this->middlewareStack[$i]);
}
}
}
/**
* Get the middleware stack.
*
* @return array<MiddlewareLayerInterface>
*/
public function getMiddleware(): array
{
return $this->middlewareStack;
}

/**
* Run the middleware stack.
Expand All @@ -75,7 +71,7 @@ public function remove(string $middlewareClass): void
*/
public function run(ServerRequestInterface $request, callable $kernel): ResponseInterface
{
$next = \array_reduce(\array_reverse($this->middlewareStack), function(callable $next, MiddlewareLayerInterface $layer): \Closure {
$next = \array_reduce(\array_reverse($this->getMiddleware()), function(callable $next, MiddlewareLayerInterface $layer): \closure {

return function(ServerRequestInterface $request) use ($next, $layer): ResponseInterface {
return $layer->handle($request, $next);
Expand Down
61 changes: 32 additions & 29 deletions src/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ public function resolve(ServerRequestInterface $request): ?Route
return $this->engine->resolve($request);
}

/**
* Get all registered routes.
*
* @return array
*/
public function getRoutes(): array
{
return $this->engine->getRoutes();
}

/**
* Get the HTTP methods supported by a particular path.
*
Expand Down Expand Up @@ -135,7 +145,7 @@ public function add(array $methods, string $path, $action): Route
*/
public function get($path, $action): Route
{
return $this->engine->add(["GET"], $path, $action);
return $this->add(["GET"], $path, $action);
}

/**
Expand All @@ -147,7 +157,7 @@ public function get($path, $action): Route
*/
public function post($path, $action): Route
{
return $this->engine->add(["POST"], $path, $action);
return $this->add(["POST"], $path, $action);
}

/**
Expand All @@ -159,7 +169,7 @@ public function post($path, $action): Route
*/
public function put($path, $action): Route
{
return $this->engine->add(["PUT"], $path, $action);
return $this->add(["PUT"], $path, $action);
}

/**
Expand All @@ -171,7 +181,7 @@ public function put($path, $action): Route
*/
public function patch($path, $action): Route
{
return $this->engine->add(["PATCH"], $path, $action);
return $this->add(["PATCH"], $path, $action);
}

/**
Expand All @@ -183,7 +193,7 @@ public function patch($path, $action): Route
*/
public function delete(string $path, $action): Route
{
return $this->engine->add(["DELETE"], $path, $action);
return $this->add(["DELETE"], $path, $action);
}

/**
Expand All @@ -195,7 +205,7 @@ public function delete(string $path, $action): Route
*/
public function head(string $path, $action): Route
{
return $this->engine->add(["HEAD"], $path, $action);
return $this->add(["HEAD"], $path, $action);
}

/**
Expand All @@ -207,23 +217,23 @@ public function head(string $path, $action): Route
*/
public function options(string $path, $action): Route
{
return $this->engine->add(["OPTIONS"], $path, $action);
return $this->add(["OPTIONS"], $path, $action);
}

/**
* Group routes together with a set of shared configuration options.
*
* @param array $config
* @param \Closure $callback
* @param \closure $callback
* @return void
*/
public function group(array $config, \Closure $callback): void
public function group(array $groupConfig, \closure $callback): void
{
// Save current config
$previousConfig = $this->config;

// Merge config values
$this->config = $this->mergeGroupConfig($config);
// Merge group config values with current config
$this->config = $this->mergeGroupConfig($this->config, $groupConfig);

// Process routes in closure
\call_user_func($callback, $this);
Expand All @@ -235,28 +245,21 @@ public function group(array $config, \Closure $callback): void
/**
* Merge parent route Group configs in with child group.
*
* @param array<string, mixed> $config
* @param array<string, mixed> $groupConfig
* @return array<string, mixed>
*/
protected function mergeGroupConfig(array $groupConfig): array
protected function mergeGroupConfig(array $config, array $groupConfig): array
{
$config = $this->config;

$config['hostname'] = $groupConfig['hostname'] ?? null;
$config['prefix'] = $groupConfig['prefix'] ?? null;
$config['namespace'] = $groupConfig['namespace'] ?? null;

if( \array_key_exists('middleware', $groupConfig) ){

if( \array_key_exists('middleware', $config) ){
$config['middleware'] = \array_merge($config['middleware'], $groupConfig['middleware']);
}

else {
$config['middleware'] = $groupConfig['middleware'];
}
}
$mergedConfig['scheme'] = $groupConfig['scheme'] ?? $config['scheme'] ?? null;
$mergedConfig['hostname'] = $groupConfig['hostname'] ?? $config['hostname'] ?? null;
$mergedConfig['prefix'] = $groupConfig['prefix'] ?? $config['pregix'] ?? null;
$mergedConfig['namespace'] = $groupConfig['namespace'] ?? $config['namespace'] ?? null;
$mergedConfig['middleware'] = \array_merge(
$config['middleware'] ?? [],
$groupConfig['middleware'] ?? []
);

return $config;
return $mergedConfig;
}
}
26 changes: 26 additions & 0 deletions tests/FunctionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Limber\Tests;

use PHPUnit\Framework\TestCase;

/**
* @covers ::class_method
*/
class TestFunctions extends TestCase
{
public function test_class_method()
{
$this->assertTrue(
\is_callable(
\class_method(TestFunctions::class . "@test_class_method")
)
);
}

public function test_class_method_not_callable()
{
$this->expectException(\Exception::class);
\class_method("FooClass");
}
}
89 changes: 89 additions & 0 deletions tests/MiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace Limber\Tests;

use Capsule\Response;
use Capsule\ResponseStatus;
use Capsule\ServerRequest;
use Limber\Middleware\CallableMiddlewareLayer;
use Limber\Middleware\MiddlewareLayerInterface;
use Limber\Middleware\MiddlewareManager;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
* @covers Limber\Middleware\MiddlewareManager
* @covers Limber\Middleware\CallableMiddlewareLayer
*/
class MiddlewareTest extends TestCase
{
public function test_constructor_compiles_class_references()
{
$middlewareManager = new MiddlewareManager([
SampleMiddleware::class
]);

$middleware = $middlewareManager->getMiddleware();

$this->assertTrue($middleware[0] instanceof MiddlewareLayerInterface);
}

public function test_constructor_compiles_callables()
{
$middlewareManager = new MiddlewareManager([
function(ServerRequestInterface $request, callable $next): ResponseInterface {
$request = $request->withAddedHeader("X-Request-Header", "Limber");
return $next($request);
}
]);

$middleware = $middlewareManager->getMiddleware();

$this->assertTrue($middleware[0] instanceof CallableMiddlewareLayer);
}

public function test_constructor_adds_layer_instances()
{
$middlewareManager = new MiddlewareManager([
new SampleMiddleware
]);

$middleware = $middlewareManager->getMiddleware();

$this->assertTrue($middleware[0] instanceof MiddlewareLayerInterface);
}

public function test_add()
{
$middlewareManager = new MiddlewareManager([
new SampleMiddleware
]);

$middlewareManager->add(new SampleMiddleware);

$middleware = $middlewareManager->getMiddleware();

$this->assertEquals(2, \count($middleware));
$this->assertTrue($middleware[1] instanceof MiddlewareLayerInterface);
}

public function test_run()
{
$middlewareManager = new MiddlewareManager([
new SampleMiddleware
]);

$response = $middlewareManager->run(
ServerRequest::create("get", "/books", null, [], [], [], []),
function(ServerRequestInterface $request) {
return new Response(
ResponseStatus::OK
);
}
);

$this->assertEquals(ResponseStatus::OK, $response->getStatusCode());
$this->assertEquals("X-Sample-Middleware: Limber", $response->getHeaderLine("X-Sample-Middleware"));
}
}
Loading

0 comments on commit 87efec3

Please sign in to comment.