Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/route-collector' into develop
Browse files Browse the repository at this point in the history
Close #64
  • Loading branch information
weierophinney committed Mar 14, 2018
2 parents 8c5a60b + 9abad21 commit 7c63fa6
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 54 deletions.
11 changes: 6 additions & 5 deletions CHANGELOG.md
Expand Up @@ -17,11 +17,12 @@ All notable changes to this project will be documented in this file, in reverse
need to configure within your application in order to work properly. See each
factory for details.

- [#47](https://github.com/zendframework/zend-expressive-router/pull/47) and
[#50](https://github.com/zendframework/zend-expressive-router/pull/50) add
the middleware `Zend\Expressive\Router\Middleware\PathBasedRoutingMiddleware`,
which extends the `RouteMiddleware` to add methods for defining and creating
path+method based routes. It exposes the following methods:
- [#47](https://github.com/zendframework/zend-expressive-router/pull/47),
[#50](https://github.com/zendframework/zend-expressive-router/pull/50), and
[#64](https://github.com/zendframework/zend-expressive-router/pull/64) add
the `Zend\Expressive\Router\RouteCollector` class,
which composes a `RouterInterface`, and provides methods for defining and
creating path+method based routes. It exposes the following methods:

- `route(string $path, MiddlewareInterface $middleware, array $methods = null, string $name = null) : Route`
- `get(string $path, MiddlewareInterface $middleware, string $name = null) : Route`
Expand Down
2 changes: 1 addition & 1 deletion src/ConfigProvider.php
Expand Up @@ -27,8 +27,8 @@ public function getDependencies() : array
Middleware\ImplicitHeadMiddleware::class => Middleware\ImplicitHeadMiddlewareFactory::class,
Middleware\ImplicitOptionsMiddleware::class => Middleware\ImplicitOptionsMiddlewareFactory::class,
Middleware\MethodNotAllowedMiddleware::class => Middleware\MethodNotAllowedMiddlewareFactory::class,
Middleware\PathBasedRoutingMiddleware::class => Middleware\PathBasedRoutingMiddlewareFactory::class,
Middleware\RouteMiddleware::class => Middleware\RouteMiddlewareFactory::class,
RouteCollector::class => RouteCollectorFactory::class,
]
];
// @codingStandardsIgnoreEnd
Expand Down
Expand Up @@ -7,17 +7,15 @@

declare(strict_types=1);

namespace Zend\Expressive\Router\Middleware;
namespace Zend\Expressive\Router;

use Psr\Http\Server\MiddlewareInterface;
use Zend\Expressive\Router\Exception;
use Zend\Expressive\Router\Route;

/**
* Routing middleware for path-based routes.
* Aggregate routes for the router.
*
* This middleware extends the RouteMiddleware in order to provide additional
* methods for creating path+HTTP method-based routes:
* This class provides * methods for creating path+HTTP method-based routes and
* injecting them into the router:
*
* - get
* - post
Expand All @@ -29,19 +27,29 @@
* A general `route()` method allows specifying multiple request methods and/or
* arbitrary request methods when creating a path-based route.
*
* Internally, the middleware performs some checks for duplicate routes when
* Internally, the class performs some checks for duplicate routes when
* attaching via one of the exposed methods, and will raise an exception when a
* collision occurs.
*/
class PathBasedRoutingMiddleware extends RouteMiddleware
class RouteCollector
{
/**
* @var RouterInterface
*/
protected $router;

/**
* List of all routes registered directly with the application.
*
* @var Route[]
*/
private $routes = [];

public function __construct(RouterInterface $router)
{
$this->router = $router;
}

/**
* Add a route for the route middleware to match.
*
Expand Down
Expand Up @@ -7,35 +7,33 @@

declare(strict_types=1);

namespace Zend\Expressive\Router\Middleware;
namespace Zend\Expressive\Router;

use Psr\Container\ContainerInterface;
use Zend\Expressive\Router\Exception\MissingDependencyException;
use Zend\Expressive\Router\RouterInterface;

/**
* Create and return a PathBasedRoutingMiddleware instance.
* Create and return a RouteCollector instance.
*
* This factory depends on one other service:
*
* - Zend\Expressive\Router\RouterInterface, which should resolve to
* a class implementing that interface.
*/
class PathBasedRoutingMiddlewareFactory
class RouteCollectorFactory
{
/**
* @throws MissingDependencyException if the RouterInterface service is
* missing.
*/
public function __invoke(ContainerInterface $container) : PathBasedRoutingMiddleware
public function __invoke(ContainerInterface $container) : RouteCollector
{
if (! $container->has(RouterInterface::class)) {
throw MissingDependencyException::dependencyForService(
throw Exception\MissingDependencyException::dependencyForService(
RouterInterface::class,
PathBasedRoutingMiddleware::class
);
}

return new PathBasedRoutingMiddleware($container->get(RouterInterface::class));
return new RouteCollector($container->get(RouterInterface::class));
}
}
3 changes: 2 additions & 1 deletion test/ConfigProviderTest.php
Expand Up @@ -12,6 +12,7 @@
use PHPUnit\Framework\TestCase;
use Zend\Expressive\Router\ConfigProvider;
use Zend\Expressive\Router\Middleware;
use Zend\Expressive\Router\RouteCollector;

class ConfigProviderTest extends TestCase
{
Expand All @@ -26,7 +27,7 @@ public function testProviderProvidesFactoriesForAllMiddleware()
$this->assertArrayHasKey(Middleware\ImplicitHeadMiddleware::class, $factories);
$this->assertArrayHasKey(Middleware\ImplicitOptionsMiddleware::class, $factories);
$this->assertArrayHasKey(Middleware\MethodNotAllowedMiddleware::class, $factories);
$this->assertArrayHasKey(Middleware\PathBasedRoutingMiddleware::class, $factories);
$this->assertArrayHasKey(Middleware\RouteMiddleware::class, $factories);
$this->assertArrayHasKey(RouteCollector::class, $factories);
}
}
Expand Up @@ -7,28 +7,28 @@

declare(strict_types=1);

namespace ZendTest\Expressive\Router\Middleware;
namespace ZendTest\Expressive\Router;

use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Container\ContainerInterface;
use Zend\Expressive\Router\Exception\MissingDependencyException;
use Zend\Expressive\Router\Middleware\PathBasedRoutingMiddleware;
use Zend\Expressive\Router\Middleware\PathBasedRoutingMiddlewareFactory;
use Zend\Expressive\Router\RouteCollector;
use Zend\Expressive\Router\RouteCollectorFactory;
use Zend\Expressive\Router\RouterInterface;

class PathBasedRoutingMiddlewareFactoryTest extends TestCase
class RouteCollectorFactoryTest extends TestCase
{
/** @var ContainerInterface|ObjectProphecy */
private $container;

/** @var PathBasedRoutingMiddlewareFactory */
/** @var RouteCollectorFactory */
private $factory;

public function setUp()
{
$this->container = $this->prophesize(ContainerInterface::class);
$this->factory = new PathBasedRoutingMiddlewareFactory();
$this->factory = new RouteCollectorFactory();
}

public function testFactoryRaisesExceptionIfRouterServiceIsMissing()
Expand All @@ -39,14 +39,14 @@ public function testFactoryRaisesExceptionIfRouterServiceIsMissing()
($this->factory)($this->container->reveal());
}

public function testFactoryProducesPathBasedRoutingMiddlewareWhenAllDependenciesPresent()
public function testFactoryProducesRouteCollectorWhenAllDependenciesPresent()
{
$router = $this->prophesize(RouterInterface::class)->reveal();
$this->container->has(RouterInterface::class)->willReturn(true);
$this->container->get(RouterInterface::class)->willReturn($router);

$middleware = ($this->factory)($this->container->reveal());

$this->assertInstanceOf(PathBasedRoutingMiddleware::class, $middleware);
$this->assertInstanceOf(RouteCollector::class, $middleware);
}
}
Expand Up @@ -7,7 +7,7 @@

declare(strict_types=1);

namespace ZendTest\Expressive\Router\Middleware;
namespace ZendTest\Expressive\Router;

use Fig\Http\Message\RequestMethodInterface as RequestMethod;
use PHPUnit\Framework\TestCase;
Expand All @@ -19,19 +19,19 @@
use Psr\Http\Server\RequestHandlerInterface;
use TypeError;
use Zend\Expressive\Router\Exception;
use Zend\Expressive\Router\Middleware\PathBasedRoutingMiddleware;
use Zend\Expressive\Router\Route;
use Zend\Expressive\Router\RouteCollector;
use Zend\Expressive\Router\RouterInterface;

class PathBasedRoutingMiddlewareTest extends TestCase
class RouteCollectorTest extends TestCase
{
/** @var RouterInterface|ObjectProphecy */
private $router;

/** @var ResponseInterface|ObjectProphecy */
private $response;

/** @var PathBasedRoutingMiddleware */
/** @var RouteCollector */
private $middleware;

/** @var ServerRequestInterface|ObjectProphecy */
Expand All @@ -42,9 +42,9 @@ class PathBasedRoutingMiddlewareTest extends TestCase

public function setUp()
{
$this->router = $this->prophesize(RouterInterface::class);
$this->response = $this->prophesize(ResponseInterface::class);
$this->middleware = new PathBasedRoutingMiddleware($this->router->reveal());
$this->router = $this->prophesize(RouterInterface::class);
$this->response = $this->prophesize(ResponseInterface::class);
$this->collector = new RouteCollector($this->router->reveal());

$this->request = $this->prophesize(ServerRequestInterface::class);
$this->handler = $this->prophesize(RequestHandlerInterface::class);
Expand Down Expand Up @@ -84,7 +84,7 @@ public function commonHttpMethods()
public function testRouteMethodReturnsRouteInstance()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalled();
$route = $this->middleware->route('/foo', $this->noopMiddleware);
$route = $this->collector->route('/foo', $this->noopMiddleware);
$this->assertInstanceOf(Route::class, $route);
$this->assertEquals('/foo', $route->getPath());
$this->assertSame($this->noopMiddleware, $route->getMiddleware());
Expand All @@ -93,7 +93,7 @@ public function testRouteMethodReturnsRouteInstance()
public function testAnyRouteMethod()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalled();
$route = $this->middleware->any('/foo', $this->noopMiddleware);
$route = $this->collector->any('/foo', $this->noopMiddleware);
$this->assertInstanceOf(Route::class, $route);
$this->assertEquals('/foo', $route->getPath());
$this->assertSame($this->noopMiddleware, $route->getMiddleware());
Expand All @@ -108,7 +108,7 @@ public function testAnyRouteMethod()
public function testCanCallRouteWithHttpMethods($method)
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalled();
$route = $this->middleware->route('/foo', $this->noopMiddleware, [$method]);
$route = $this->collector->route('/foo', $this->noopMiddleware, [$method]);
$this->assertInstanceOf(Route::class, $route);
$this->assertEquals('/foo', $route->getPath());
$this->assertSame($this->noopMiddleware, $route->getMiddleware());
Expand All @@ -120,7 +120,7 @@ public function testCanCallRouteWithMultipleHttpMethods()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalled();
$methods = array_keys($this->commonHttpMethods());
$route = $this->middleware->route('/foo', $this->noopMiddleware, $methods);
$route = $this->collector->route('/foo', $this->noopMiddleware, $methods);
$this->assertInstanceOf(Route::class, $route);
$this->assertEquals('/foo', $route->getPath());
$this->assertSame($this->noopMiddleware, $route->getMiddleware());
Expand All @@ -130,10 +130,10 @@ public function testCanCallRouteWithMultipleHttpMethods()
public function testCallingRouteWithExistingPathAndOmittingMethodsArgumentRaisesException()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalledTimes(2);
$this->middleware->route('/foo', $this->noopMiddleware);
$this->middleware->route('/bar', $this->noopMiddleware);
$this->collector->route('/foo', $this->noopMiddleware);
$this->collector->route('/bar', $this->noopMiddleware);
$this->expectException(Exception\DuplicateRouteException::class);
$this->middleware->route('/foo', $this->createNoopMiddleware());
$this->collector->route('/foo', $this->createNoopMiddleware());
}

public function invalidPathTypes()
Expand All @@ -159,7 +159,7 @@ public function invalidPathTypes()
public function testCallingRouteWithAnInvalidPathTypeRaisesAnException($path)
{
$this->expectException(TypeError::class);
$this->middleware->route($path, $this->createNoopMiddleware());
$this->collector->route($path, $this->createNoopMiddleware());
}

/**
Expand All @@ -169,7 +169,7 @@ public function testCallingRouteWithAnInvalidPathTypeRaisesAnException($path)
*/
public function testCommonHttpMethodsAreExposedAsClassMethodsAndReturnRoutes($method)
{
$route = $this->middleware->{$method}('/foo', $this->noopMiddleware);
$route = $this->collector->{$method}('/foo', $this->noopMiddleware);
$this->assertInstanceOf(Route::class, $route);
$this->assertEquals('/foo', $route->getPath());
$this->assertSame($this->noopMiddleware, $route->getMiddleware());
Expand All @@ -179,10 +179,10 @@ public function testCommonHttpMethodsAreExposedAsClassMethodsAndReturnRoutes($me
public function testCreatingHttpRouteMethodWithExistingPathButDifferentMethodCreatesNewRouteInstance()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalledTimes(2);
$route = $this->middleware->route('/foo', $this->noopMiddleware, [RequestMethod::METHOD_POST]);
$route = $this->collector->route('/foo', $this->noopMiddleware, [RequestMethod::METHOD_POST]);

$middleware = $this->createNoopMiddleware();
$test = $this->middleware->get('/foo', $middleware);
$test = $this->collector->get('/foo', $middleware);
$this->assertNotSame($route, $test);
$this->assertSame($route->getPath(), $test->getPath());
$this->assertSame(['GET'], $test->getAllowedMethods());
Expand All @@ -192,20 +192,20 @@ public function testCreatingHttpRouteMethodWithExistingPathButDifferentMethodCre
public function testCreatingHttpRouteWithExistingPathAndMethodRaisesException()
{
$this->router->addRoute(Argument::type(Route::class))->shouldBeCalledTimes(1);
$this->middleware->get('/foo', $this->noopMiddleware);
$this->collector->get('/foo', $this->noopMiddleware);

$this->expectException(Exception\DuplicateRouteException::class);
$this->middleware->get('/foo', $this->createNoopMiddleware());
$this->collector->get('/foo', $this->createNoopMiddleware());
}

public function testGetRoutes()
{
$middleware1 = $this->prophesize(MiddlewareInterface::class)->reveal();
$this->middleware->any('/foo', $middleware1, 'abc');
$this->collector->any('/foo', $middleware1, 'abc');
$middleware2 = $this->prophesize(MiddlewareInterface::class)->reveal();
$this->middleware->get('/bar', $middleware2, 'def');
$this->collector->get('/bar', $middleware2, 'def');

$routes = $this->middleware->getRoutes();
$routes = $this->collector->getRoutes();

$this->assertInternalType('array', $routes);
$this->assertCount(2, $routes);
Expand Down

0 comments on commit 7c63fa6

Please sign in to comment.