Remove RouteTable, revise RouteFactory,

This commit is contained in:
PJ Dietz 2015-05-08 01:03:07 -04:00
parent 09ea17d349
commit 1d30fcbbba
9 changed files with 87 additions and 427 deletions

View File

@ -2,7 +2,7 @@
namespace WellRESTed\Routing\Route; namespace WellRESTed\Routing\Route;
use WellRESTed\Routing\RouteTableInterface; use WellRESTed\Routing\MethodMap;
/** /**
* Class for creating routes * Class for creating routes
@ -10,20 +10,17 @@ use WellRESTed\Routing\RouteTableInterface;
class RouteFactory implements RouteFactoryInterface class RouteFactory implements RouteFactoryInterface
{ {
/** /**
* The method will determine the most appropriate route subclass to use * Creates a route for the given target.
* and will forward the arguments on to the subclass's constructor.
* *
* - Paths with no special characters will register StaticRoutes * - Target with no special characters will create StaticRoutes
* - Paths ending with * will register PrefixRoutes * - Target ending with * will create PrefixRoutes
* - Paths containing URI variables (e.g., {id}) will register TemplateRoutes * - Target containing URI variables (e.g., {id}) will create TemplateRoutes
* - Regular exressions will register RegexRoutes * - Regular exressions will create RegexRoutes
* *
* @param RouteTableInterface $routeTable Table to add the route to * @param string $target Route target or target pattern
* @param string $target Path, prefix, or pattern to match * @return RouteInterface
* @param mixed $middleware Middleware to dispatch
* @param mixed $extra Additional options to pass to a route constructor
*/ */
public function registerRoute(RouteTableInterface $routeTable, $target, $middleware, $extra = null) public function create($target)
{ {
if ($target[0] === "/") { if ($target[0] === "/") {
@ -31,25 +28,19 @@ class RouteFactory implements RouteFactoryInterface
// PrefixRoutes end with * // PrefixRoutes end with *
if (substr($target, -1) === "*") { if (substr($target, -1) === "*") {
// Remove the trailing *, since the PrefixRoute constructor doesn't expect it. return new PrefixRoute($target, new MethodMap());
$target = substr($target, 0, -1);
$route = new PrefixRoute($target, $middleware);
$routeTable->addPrefixRoute($route);
} }
// TempalateRoutes contain {variable} // TempalateRoutes contain {variable}
if (preg_match(TemplateRoute::URI_TEMPLATE_EXPRESSION_RE, $target)) { if (preg_match(TemplateRoute::URI_TEMPLATE_EXPRESSION_RE, $target)) {
$route = new TemplateRoute($target, $middleware, $extra); return new TemplateRoute($target, new MethodMap());
$routeTable->addRoute($route);
} }
// StaticRoute // StaticRoute
$route = new StaticRoute($target, $middleware); return new StaticRoute($target, new MethodMap());
$routeTable->addStaticRoute($route);
} }
// Regex // Regex
$route = new RegexRoute($target, $middleware); return new RegexRoute($target, new MethodMap());
$routeTable->addRoute($route);
} }
} }

View File

@ -6,6 +6,14 @@ interface RouteFactoryInterface
{ {
/** /**
* Creates a route for the given target. * Creates a route for the given target.
*
* - Target with no special characters will create StaticRoutes
* - Target ending with * will create PrefixRoutes
* - Target containing URI variables (e.g., {id}) will create TemplateRoutes
* - Regular exressions will create RegexRoutes
*
* @param string $target Route target or target pattern
* @return RouteInterface
*/ */
public function create($target); public function create($target);
} }

View File

@ -1,103 +0,0 @@
<?php
namespace WellRESTed\Routing;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use WellRESTed\Routing\Route\PrefixRouteInterface;
use WellRESTed\Routing\Route\RouteInterface;
use WellRESTed\Routing\Route\StaticRouteInterface;
class RouteTable implements MiddlewareInterface, RouteTableInterface
{
/** @var RouteInterface[] Array of Route objects */
private $routes;
/** @var array Hash array mapping exact paths to routes */
private $staticRoutes;
/** @var array Hash array mapping path prefixes to routes */
private $prefixRoutes;
public function __construct()
{
$this->routes = [];
$this->staticRoutes = [];
$this->prefixRoutes = [];
}
public function addRoute(RouteInterface $route)
{
$this->routes[] = $route;
}
public function addStaticRoute(StaticRouteInterface $staticRoute)
{
$this->staticRoutes[$staticRoute->getPath()] = $staticRoute;
}
public function addPrefixRoute(PrefixRouteInterface $prefxRoute)
{
$this->prefixRoutes[$prefxRoute->getPrefix()] = $prefxRoute;
}
public function dispatch(ServerRequestInterface $request, ResponseInterface &$response)
{
$requestTarget = $request->getRequestTarget();
$route = $this->getStaticRoute($requestTarget);
if ($route) {
$route->dispatch($request, $response);
return;
}
$route = $this->getPrefixRoute($requestTarget);
if ($route) {
$route->dispatch($request, $response);
return;
}
// Try each of the routes.
foreach ($this->routes as $route) {
if ($route->matchesRequestTarget($requestTarget, $captures)) {
if (is_array($captures)) {
foreach ($captures as $key => $value) {
$request = $request->withAttribute($key, $value);
}
}
$route->dispatch($request, $response);
}
}
}
private function getStaticRoute($requestTarget)
{
if (isset($this->staticRoutes[$requestTarget])) {
return $this->staticRoutes[$requestTarget];
}
return null;
}
private function getPrefixRoute($requestTarget)
{
// Find all prefixes that match the start of this path.
$prefixes = array_keys($this->prefixRoutes);
$matches = array_filter(
$prefixes,
function ($prefix) use ($requestTarget) {
return (strrpos($requestTarget, $prefix, -strlen($requestTarget)) !== false);
}
);
if ($matches) {
if (count($matches) > 0) {
// If there are multiple matches, sort them to find the one with the longest string length.
$compareByLength = function ($a, $b) {
return strlen($b) - strlen($a);
};
usort($matches, $compareByLength);
}
$route = $this->prefixRoutes[$matches[0]];
return $route;
}
return null;
}
}

View File

@ -1,16 +0,0 @@
<?php
namespace WellRESTed\Routing;
use WellRESTed\Routing\Route\PrefixRouteInterface;
use WellRESTed\Routing\Route\RouteInterface;
use WellRESTed\Routing\Route\StaticRouteInterface;
interface RouteTableInterface extends MiddlewareInterface
{
public function addRoute(RouteInterface $route);
public function addStaticRoute(StaticRouteInterface $staticRoute);
public function addPrefixRoute(PrefixRouteInterface $prefxRoute);
}

View File

@ -4,6 +4,7 @@ namespace WellRESTed\Test\Unit\Routing\Route;
use Prophecy\Argument; use Prophecy\Argument;
use WellRESTed\Routing\Route\RouteFactory; use WellRESTed\Routing\Route\RouteFactory;
use WellRESTed\Routing\Route\RouteInterface;
/** /**
* @covers WellRESTed\Routing\Route\RouteFactory * @covers WellRESTed\Routing\Route\RouteFactory
@ -12,46 +13,35 @@ use WellRESTed\Routing\Route\RouteFactory;
* @uses WellRESTed\Routing\Route\PrefixRoute * @uses WellRESTed\Routing\Route\PrefixRoute
* @uses WellRESTed\Routing\Route\StaticRoute * @uses WellRESTed\Routing\Route\StaticRoute
* @uses WellRESTed\Routing\Route\Route * @uses WellRESTed\Routing\Route\Route
* @uses WellRESTed\Routing\MethodMap
*/ */
class RouteFactoryTest extends \PHPUnit_Framework_TestCase class RouteFactoryTest extends \PHPUnit_Framework_TestCase
{ {
private $routeTable; public function testCreatesStaticRoute()
public function setUp()
{
parent::setUp();
$this->routeTable = $this->prophesize("\\WellRESTed\\Routing\\RouteTableInterface");
$this->routeTable->addStaticRoute(Argument::cetera())->willReturn();
$this->routeTable->addPrefixRoute(Argument::cetera())->willReturn();
$this->routeTable->addRoute(Argument::cetera())->willReturn();
}
public function testRegistersStaticRoute()
{ {
$factory = new RouteFactory(); $factory = new RouteFactory();
$factory->registerRoute($this->routeTable->reveal(), "/cats/", null); $route = $factory->create("/cats/");
$this->routeTable->addStaticRoute(Argument::any())->shouldHaveBeenCalled(); $this->assertSame(RouteInterface::TYPE_STATIC, $route->getType());
} }
public function testRegistersPrefixRoute() public function testCreatesPrefixRoute()
{ {
$factory = new RouteFactory(); $factory = new RouteFactory();
$factory->registerRoute($this->routeTable->reveal(), "/cats/*", null); $route = $factory->create("/cats/*");
$this->routeTable->addPrefixRoute(Argument::any())->shouldHaveBeenCalled(); $this->assertSame(RouteInterface::TYPE_PREFIX, $route->getType());
} }
public function testRegistersTemplateRoute() public function testCreatesRegexRoute()
{ {
$factory = new RouteFactory(); $factory = new RouteFactory();
$factory->registerRoute($this->routeTable->reveal(), "/cats/{catId}", null); $route = $factory->create("~/cat/[0-9]+~");
$this->routeTable->addRoute(Argument::type("\\WellRESTed\\Routing\\Route\\TemplateRoute"))->shouldHaveBeenCalled(); $this->assertSame(RouteInterface::TYPE_PATTERN, $route->getType());
} }
public function testRegistersRegexRoute() public function testCreatesTemplateRoute()
{ {
$factory = new RouteFactory(); $factory = new RouteFactory();
$factory->registerRoute($this->routeTable->reveal(), "~/cat/[0-9]+~", null); $route = $factory->create("/cat/{id}");
$this->routeTable->addRoute(Argument::type("\\WellRESTed\\Routing\\Route\\RegexRoute"))->shouldHaveBeenCalled(); $this->assertSame(RouteInterface::TYPE_PATTERN, $route->getType());
$this->routeTable->addRoute(Argument::type("\\WellRESTed\\Routing\\Route\\TemplateRoute"))->shouldNotHaveBeenCalled();
} }
} }

View File

@ -39,7 +39,7 @@ class TemplateRouteTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* @dataProvider matchingRouteProvider * @dataProvider matchingTemplateProvider
*/ */
public function testProvidesCapturesAsRequestAttributes($template, $path, $expectedCaptures) public function testProvidesCapturesAsRequestAttributes($template, $path, $expectedCaptures)
{ {
@ -52,7 +52,11 @@ class TemplateRouteTest extends \PHPUnit_Framework_TestCase
$route->matchesRequestTarget($path); $route->matchesRequestTarget($path);
$route->dispatch($request->reveal(), $responseReveal); $route->dispatch($request->reveal(), $responseReveal);
$request->withAttribute("path", $expectedCaptures)->shouldHaveBeenCalled(); $request->withAttribute("path", Argument::that(function ($path) use ($expectedCaptures) {
return array_intersect_assoc($path, $expectedCaptures) == $expectedCaptures;
}))->shouldHaveBeenCalled();
//$request->withAttribute("path", $expectedCaptures)->shouldHaveBeenCalled();
} }
public function matchingTemplateProvider() public function matchingTemplateProvider()

View File

@ -3,12 +3,12 @@
namespace WellRESTed\Test\Unit\Routing; namespace WellRESTed\Test\Unit\Routing;
use Prophecy\Argument; use Prophecy\Argument;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use WellRESTed\Routing\MethodMapInterface;
use WellRESTed\Routing\Route\RouteInterface; use WellRESTed\Routing\Route\RouteInterface;
use WellRESTed\Routing\RouteMap; use WellRESTed\Routing\RouteMap;
// Test dispatch orders (static before prefix, prefix before pattern)
// Test dispatches first matching pattern route
/** /**
* @coversDefaultClass WellRESTed\Routing\RouteMap * @coversDefaultClass WellRESTed\Routing\RouteMap
* @uses WellRESTed\Routing\RouteMap * @uses WellRESTed\Routing\RouteMap

View File

@ -1,179 +0,0 @@
<?php
namespace WellRESTed\Test\Unit\Routing;
use Prophecy\Argument;
use WellRESTed\Routing\Route\TemplateRoute;
use WellRESTed\Routing\RouteTable;
class RouteTableTest extends \PHPUnit_Framework_TestCase
{
private $request;
private $response;
public function setUp()
{
$this->request = $this->prophesize("\\Psr\\Http\\Message\\ServerRequestInterface");
$this->response = $this->prophesize("\\Psr\\Http\\Message\\ResponseInterface");
}
public function testMatchesStaticRoute()
{
$route = $this->prophesize("\\WellRESTed\\Routing\\Route\\StaticRouteInterface");
$route->getPath()->willReturn("/cats/");
$route->dispatch(Argument::cetera())->willReturn();
$this->request->getRequestTarget()->willReturn("/cats/");
$table = new RouteTable();
$table->addStaticRoute($route->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route->dispatch($request, $response)->shouldHaveBeenCalled();
}
public function testMatchesPrefixRoute()
{
$route = $this->prophesize("\\WellRESTed\\Routing\\Route\\PrefixRouteInterface");
$route->getPrefix()->willReturn("/cats/");
$route->dispatch(Argument::cetera())->willReturn();
$this->request->getRequestTarget()->willReturn("/cats/molly");
$table = new RouteTable();
$table->addPrefixRoute($route->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route->dispatch($request, $response)->shouldHaveBeenCalled();
}
public function testMatchesBestPrefixRoute()
{
$route1 = $this->prophesize("\\WellRESTed\\Routing\\Route\\PrefixRouteInterface");
$route1->getPrefix()->willReturn("/animals/");
$route1->dispatch(Argument::cetera())->willReturn();
$route2 = $this->prophesize("\\WellRESTed\\Routing\\Route\\PrefixRouteInterface");
$route2->getPrefix()->willReturn("/animals/cats/");
$route2->dispatch(Argument::cetera())->willReturn();
$this->request->getRequestTarget()->willReturn("/animals/cats/molly");
$table = new RouteTable();
$table->addPrefixRoute($route1->reveal());
$table->addPrefixRoute($route2->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route1->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
$route2->dispatch(Argument::cetera())->shouldHaveBeenCalled();
}
public function testMatchesStaticRouteBeforePrefixRoute()
{
$route1 = $this->prophesize("\\WellRESTed\\Routing\\Route\\PrefixRouteInterface");
$route1->getPrefix()->willReturn("/animals/cats/");
$route1->dispatch(Argument::cetera())->willReturn();
$route2 = $this->prophesize("\\WellRESTed\\Routing\\Route\\StaticRouteInterface");
$route2->getPath()->willReturn("/animals/cats/molly");
$route2->dispatch(Argument::cetera())->willReturn();
$this->request->getRequestTarget()->willReturn("/animals/cats/molly");
$table = new RouteTable();
$table->addPrefixRoute($route1->reveal());
$table->addStaticRoute($route2->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route1->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
$route2->dispatch(Argument::cetera())->shouldHaveBeenCalled();
}
public function testMatchesPrefixRouteBeforeRoute()
{
$route1 = $this->prophesize("\\WellRESTed\\Routing\\Route\\PrefixRouteInterface");
$route1->getPrefix()->willReturn("/animals/cats/");
$route1->dispatch(Argument::cetera())->willReturn();
$route2 = $this->prophesize("\\WellRESTed\\Routing\\Route\\RouteInterface");
$route2->matchesRequestTarget(Argument::cetera())->willReturn(true);
$this->request->getRequestTarget()->willReturn("/animals/cats/molly");
$table = new RouteTable();
$table->addPrefixRoute($route1->reveal());
$table->addRoute($route2->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route1->dispatch(Argument::cetera())->shouldHaveBeenCalled();
$route2->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
}
/**
* @uses WellRESTed\Routing\Route\TemplateRoute
* @uses WellRESTed\Routing\Route\RegexRoute
* @uses WellRESTed\Routing\Route\Route
*/
public function testAddsCapturesAsRequestAttributes()
{
// This test needs to read the result of the $captures parameter which
// is passed by reference. This is not so eary so mock, so the test
// will use an actual TemplateRoute.
$middleware = $this->prophesize("\\WellRESTed\\Routing\\MiddlewareInterface");
$route = new TemplateRoute("/cats/{id}", $middleware->reveal());
$this->request->withAttribute(Argument::cetera())->willReturn($this->request->reveal());
$this->request->getRequestTarget()->willReturn("/cats/molly");
$table = new RouteTable();
$table->addRoute($route);
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$this->request->withAttribute("id", "molly")->shouldHaveBeenCalled();
}
public function testDispatchedFirstMatchingRoute()
{
$route1 = $this->prophesize("\\WellRESTed\\Routing\\Route\\RouteInterface");
$route1->matchesRequestTarget(Argument::cetera())->willReturn(false);
$route2 = $this->prophesize("\\WellRESTed\\Routing\\Route\\RouteInterface");
$route2->matchesRequestTarget(Argument::cetera())->willReturn(true);
$route2->dispatch(Argument::cetera())->willReturn();
$route3 = $this->prophesize("\\WellRESTed\\Routing\\Route\\RouteInterface");
$route3->matchesRequestTarget(Argument::cetera())->willReturn(false);
$this->request->getRequestTarget()->willReturn("/");
$table = new RouteTable();
$table->addRoute($route1->reveal());
$table->addRoute($route2->reveal());
$table->addRoute($route3->reveal());
$request = $this->request->reveal();
$response = $this->response->reveal();
$table->dispatch($request, $response);
$route1->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
$route2->dispatch(Argument::cetera())->shouldHaveBeenCalled();
$route3->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
}
}

View File

@ -21,14 +21,31 @@ class RouterTest extends \PHPUnit_Framework_TestCase
{ {
private $request; private $request;
private $response; private $response;
private $routeMap;
private $router;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
$this->request = $this->prophesize('Psr\Http\Message\ServerRequestInterface'); $this->request = $this->prophesize('Psr\Http\Message\ServerRequestInterface');
$this->response = $this->prophesize('Psr\Http\Message\ResponseInterface'); $this->response = $this->prophesize('Psr\Http\Message\ResponseInterface');
$this->response->hasHeader("Content-length")->willReturn(true); $this->response->hasHeader("Content-length")->willReturn(true);
$this->response->getStatusCode()->willReturn(200); $this->response->getStatusCode()->willReturn(200);
$this->routeMap = $this->prophesize('WellRESTed\Routing\RouteMapInterface');
$this->routeMap->add(Argument::cetera())->willReturn();
$this->routeMap->dispatch(Argument::cetera())->willReturn();
$this->router = $this->getMockBuilder('WellRESTed\Routing\Router')
->setMethods(["getRouteMap"])
->disableOriginalConstructor()
->getMock();
$this->router->expects($this->any())
->method("getRouteMap")
->will($this->returnValue($this->routeMap->reveal()));
$this->router->__construct();
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -57,24 +74,12 @@ class RouterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testAddRegistersRouteWithRouteMap() public function testAddRegistersRouteWithRouteMap()
{ {
$routeMap = $this->prophesize('WellRESTed\Routing\RouteMapInterface');
$routeMap->add(Argument::cetera())->willReturn();
$router = $this->getMockBuilder('WellRESTed\Routing\Router')
->setMethods(["getRouteMap"])
->disableOriginalConstructor()
->getMock();
$router->expects($this->any())
->method("getRouteMap")
->will($this->returnValue($routeMap->reveal()));
$router->__construct();
$method = "GET"; $method = "GET";
$target = "/path/{id}"; $target = "/path/{id}";
$middleware = "Middleware"; $middleware = "Middleware";
$router->add($method, $target, $middleware); $this->router->add($method, $target, $middleware);
$routeMap->add($method, $target, $middleware)->shouldHaveBeenCalled(); $this->routeMap->add($method, $target, $middleware)->shouldHaveBeenCalled();
} }
/** /**
@ -82,23 +87,10 @@ class RouterTest extends \PHPUnit_Framework_TestCase
*/ */
public function testDispatchesRouteMap() public function testDispatchesRouteMap()
{ {
$routeMap = $this->prophesize('WellRESTed\Routing\RouteMapInterface');
$routeMap->dispatch(Argument::cetera())->willReturn();
$router = $this->getMockBuilder('WellRESTed\Routing\Router')
->setMethods(["getRouteMap"])
->disableOriginalConstructor()
->getMock();
$router->expects($this->any())
->method("getRouteMap")
->will($this->returnValue($routeMap->reveal()));
$router->__construct();
$request = $this->request->reveal(); $request = $this->request->reveal();
$resonse = $this->response->reveal(); $resonse = $this->response->reveal();
$router->dispatch($request, $resonse); $this->router->dispatch($request, $resonse);
$this->routeMap->dispatch($request, Argument::any())->shouldHaveBeenCalled();
$routeMap->dispatch($request, Argument::any())->shouldHaveBeenCalled();
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -113,12 +105,11 @@ class RouterTest extends \PHPUnit_Framework_TestCase
$hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface'); $hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
$hook->dispatch(Argument::cetera())->willReturn(); $hook->dispatch(Argument::cetera())->willReturn();
$router = new Router(); $this->router->addPreRouteHook($hook->reveal());
$router->addPreRouteHook($hook->reveal());
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$hook->dispatch(Argument::cetera())->shouldHaveBeenCalled(); $hook->dispatch(Argument::cetera())->shouldHaveBeenCalled();
} }
@ -135,12 +126,11 @@ class RouterTest extends \PHPUnit_Framework_TestCase
$statusMiddleware = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface'); $statusMiddleware = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
$statusMiddleware->dispatch(Argument::cetera())->willReturn(); $statusMiddleware->dispatch(Argument::cetera())->willReturn();
$router = new Router(); $this->router->setStatusHook(403, $statusMiddleware->reveal());
$router->setStatusHook(403, $statusMiddleware->reveal());
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$statusMiddleware->dispatch(Argument::cetera())->shouldHaveBeenCalled(); $statusMiddleware->dispatch(Argument::cetera())->shouldHaveBeenCalled();
} }
@ -150,13 +140,12 @@ class RouterTest extends \PHPUnit_Framework_TestCase
* @covers ::dispatchStatusHooks * @covers ::dispatchStatusHooks
* @covers ::setStatusHook * @covers ::setStatusHook
*/ */
public function testDispatchesStatusHookForHttpException() public function testConvertsHttpExceptionToResponse()
{ {
$statusMiddleware = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface'); $statusMiddleware = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
$statusMiddleware->dispatch(Argument::cetera())->willReturn(); $statusMiddleware->dispatch(Argument::cetera())->willReturn();
$routeMap = $this->prophesize('WellRESTed\Routing\RouteMapInterface'); $this->routeMap->dispatch(Argument::cetera())->willThrow(new NotFoundException());
$routeMap->dispatch(Argument::cetera())->willThrow(new NotFoundException());
$this->response->withStatus(Argument::any())->will( $this->response->withStatus(Argument::any())->will(
function ($args) { function ($args) {
@ -166,18 +155,9 @@ class RouterTest extends \PHPUnit_Framework_TestCase
); );
$this->response->withBody(Argument::any())->willReturn($this->response->reveal()); $this->response->withBody(Argument::any())->willReturn($this->response->reveal());
$router = $this->getMockBuilder('WellRESTed\Routing\Router')
->setMethods(["getRouteMap"])
->disableOriginalConstructor()
->getMock();
$router->expects($this->any())
->method("getRouteMap")
->will($this->returnValue($routeMap->reveal()));
$router->__construct();
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$this->response->withStatus(404)->shouldHaveBeenCalled(); $this->response->withStatus(404)->shouldHaveBeenCalled();
} }
@ -191,12 +171,11 @@ class RouterTest extends \PHPUnit_Framework_TestCase
$hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface'); $hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
$hook->dispatch(Argument::cetera())->willReturn(); $hook->dispatch(Argument::cetera())->willReturn();
$router = new Router(); $this->router->addPostRouteHook($hook->reveal());
$router->addPostRouteHook($hook->reveal());
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$hook->dispatch(Argument::cetera())->shouldHaveBeenCalled(); $hook->dispatch(Argument::cetera())->shouldHaveBeenCalled();
} }
@ -210,12 +189,11 @@ class RouterTest extends \PHPUnit_Framework_TestCase
$hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface'); $hook = $this->prophesize('\WellRESTed\Routing\MiddlewareInterface');
$hook->dispatch(Argument::cetera())->willReturn(); $hook->dispatch(Argument::cetera())->willReturn();
$router = new Router(); $this->router->addFinalizationHook($hook->reveal());
$router->addFinalizationHook($hook->reveal());
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$hook->dispatch(Argument::cetera())->shouldHaveBeenCalled(); $hook->dispatch(Argument::cetera())->shouldHaveBeenCalled();
} }
@ -228,34 +206,23 @@ class RouterTest extends \PHPUnit_Framework_TestCase
// Each middleware will push a value onto this array. // Each middleware will push a value onto this array.
$stack = []; $stack = [];
$routeMap = $this->prophesize('WellRESTed\Routing\RouteMapInterface');
$response = $this->response; $response = $this->response;
$routeMap->dispatch(Argument::cetera())->will(function () use ($response, &$stack) { $this->routeMap->dispatch(Argument::cetera())->will(function () use ($response, &$stack) {
$stack[] = "routeMap"; $stack[] = "routeMap";
$response->getStatusCode()->willReturn(404); $response->getStatusCode()->willReturn(404);
}); });
$router = $this->getMockBuilder('WellRESTed\Routing\Router') $this->router->addPreRouteHook($this->createStackHook("pre1", $stack));
->setMethods(["getRouteMap"]) $this->router->addPreRouteHook($this->createStackHook("pre2", $stack));
->disableOriginalConstructor() $this->router->addPostRouteHook($this->createStackHook("post1", $stack));
->getMock(); $this->router->addPostRouteHook($this->createStackHook("post2", $stack));
$router->expects($this->any()) $this->router->addFinalizationHook($this->createStackHook("final1", $stack));
->method("getRouteMap") $this->router->addFinalizationHook($this->createStackHook("final2", $stack));
->will($this->returnValue($routeMap->reveal())); $this->router->setStatusHook(404, $this->createStackHook("404", $stack));
$router->__construct();
$router->addPreRouteHook($this->createStackHook("pre1", $stack));
$router->addPreRouteHook($this->createStackHook("pre2", $stack));
$router->addPostRouteHook($this->createStackHook("post1", $stack));
$router->addPostRouteHook($this->createStackHook("post2", $stack));
$router->addFinalizationHook($this->createStackHook("final1", $stack));
$router->addFinalizationHook($this->createStackHook("final2", $stack));
$router->setStatusHook(404, $this->createStackHook("404", $stack));
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$this->assertEquals(["pre1","pre2","routeMap","404","post1","post2","final1","final2"], $stack); $this->assertEquals(["pre1","pre2","routeMap","404","post1","post2","final1","final2"], $stack);
} }
@ -287,11 +254,10 @@ class RouterTest extends \PHPUnit_Framework_TestCase
} }
); );
$this->response->withBody(Argument::any())->willReturn($this->response->reveal()); $this->response->withBody(Argument::any())->willReturn($this->response->reveal());
$router = new Router();
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$this->response->withHeader(Argument::cetera())->shouldHaveBeenCalled(); $this->response->withHeader(Argument::cetera())->shouldHaveBeenCalled();
} }
@ -314,11 +280,10 @@ class RouterTest extends \PHPUnit_Framework_TestCase
} }
); );
$this->response->withBody(Argument::any())->willReturn($this->response->reveal()); $this->response->withBody(Argument::any())->willReturn($this->response->reveal());
$router = new Router();
$request = $this->request->reveal(); $request = $this->request->reveal();
$response = $this->response->reveal(); $response = $this->response->reveal();
$router->dispatch($request, $response); $this->router->dispatch($request, $response);
$this->response->withBody(Argument::that(function ($body) { $this->response->withBody(Argument::that(function ($body) {
return $body->getSize() === 0; return $body->getSize() === 0;