Fix documentation and add tests for TemplateRoute

This commit is contained in:
PJ Dietz 2014-07-13 17:08:15 -04:00
parent f11c13c1b3
commit e597926634
4 changed files with 126 additions and 24 deletions

View File

@ -1,9 +1,18 @@
<?php <?php
/**
* pjdietz\WellRESTed\TemplateRoute
*
* @author PJ Dietz <pj@pjdietz.com>
* @copyright Copyright 2014 by PJ Dietz
* @license MIT
*/
namespace pjdietz\WellRESTed\Routes; namespace pjdietz\WellRESTed\Routes;
use InvalidArgumentException; /**
* Maps a URI template to a Handler
*/
class TemplateRoute extends RegexRoute class TemplateRoute extends RegexRoute
{ {
/** /**
@ -21,6 +30,10 @@ class TemplateRoute extends RegexRoute
const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/'; const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/';
/** /**
* Create a new route that matches a URI template to a Handler.
*
* Optionally provide patterns for the variables in the template.
*
* @param string $template URI template the path must match * @param string $template URI template the path must match
* @param string $targetClassName Fully qualified name to an autoloadable handler class * @param string $targetClassName Fully qualified name to an autoloadable handler class
* @param string $defaultPattern Regular expression for variables * @param string $defaultPattern Regular expression for variables
@ -36,6 +49,14 @@ class TemplateRoute extends RegexRoute
parent::__construct($pattern, $targetClassName); parent::__construct($pattern, $targetClassName);
} }
/**
* Translate the URI template into a regular expression.
*
* @param string $template URI template the path must match
* @param string $defaultPattern Regular expression for variables
* @param array $variablePatterns Map of variable names and regular expression
* @return string
*/
private function buildPattern($template, $defaultPattern, $variablePatterns) private function buildPattern($template, $defaultPattern, $variablePatterns)
{ {
if (is_null($variablePatterns)) { if (is_null($variablePatterns)) {
@ -64,10 +85,6 @@ class TemplateRoute extends RegexRoute
// Is this part an expression or a literal? // Is this part an expression or a literal?
if (preg_match(self::URI_TEMPLATE_EXPRESSION_RE, $part, $matches)) { if (preg_match(self::URI_TEMPLATE_EXPRESSION_RE, $part, $matches)) {
// This part of the path is an expresion.
if (count($matches) === 2) {
// Locate the name for the variable from the template. // Locate the name for the variable from the template.
$variableName = $matches[1]; $variableName = $matches[1];
@ -86,10 +103,6 @@ class TemplateRoute extends RegexRoute
$variablePattern $variablePattern
); );
} else {
throw new InvalidArgumentException('Invalid URI Template.');
}
} else { } else {
// This part is a literal. // This part is a literal.
$pattern .= $part; $pattern .= $part;

View File

@ -1,5 +1,7 @@
<?php <?php
namespace pjdietz\WellRESTed\Test;
use pjdietz\WellRESTed\Routes\RegexRoute; use pjdietz\WellRESTed\Routes\RegexRoute;
class RegexRouteTest extends \PHPUnit_Framework_TestCase class RegexRouteTest extends \PHPUnit_Framework_TestCase

View File

@ -1,5 +1,7 @@
<?php <?php
namespace pjdietz\WellRESTed\Test;
use pjdietz\WellRESTed\Routes\StaticRoute; use pjdietz\WellRESTed\Routes\StaticRoute;
class StaticRouteTest extends \PHPUnit_Framework_TestCase class StaticRouteTest extends \PHPUnit_Framework_TestCase

View File

@ -0,0 +1,85 @@
<?php
namespace pjdietz\WellRESTed\Test;
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
use pjdietz\WellRESTed\Interfaces\RequestInterface;
use pjdietz\WellRESTed\Response;
use pjdietz\WellRESTed\Routes\TemplateRoute;
class TemplateRouteTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider matchingTemplateProvider
*/
public function testMatchingTemplate($template, $default, $vars, $path, $testName, $expected)
{
$mockRequest = $this->getMock('\pjdietz\WellRESTed\Interfaces\RequestInterface');
$mockRequest->expects($this->any())
->method('getPath')
->will($this->returnValue($path));
$route = new TemplateRoute($template, __NAMESPACE__ . '\TemplateRouteTestMockHandler', $default, $vars);
$resp = $route->getResponse($mockRequest);
$args = json_decode($resp->getBody(), true);
$this->assertEquals($expected, $args[$testName]);
}
public function matchingTemplateProvider()
{
return array(
array("/cat/{id}", TemplateRoute::RE_NUM, null, "/cat/12", "id", "12"),
array("/cat/{catId}/{dogId}", TemplateRoute::RE_SLUG, null, "/cat/molly/bear", "dogId", "bear"),
array("/cat/{catId}/{dogId}", TemplateRoute::RE_NUM, array(
"catId" => TemplateRoute::RE_SLUG,
"dogId" => TemplateRoute::RE_SLUG),
"/cat/molly/bear", "dogId", "bear"),
array("cat/{catId}/{dogId}", TemplateRoute::RE_NUM, (object) array(
"catId" => TemplateRoute::RE_SLUG,
"dogId" => TemplateRoute::RE_SLUG),
"/cat/molly/bear", "dogId", "bear")
);
}
/**
* @dataProvider nonmatchingTemplateProvider
*/
public function testNonmatchingTemplate($template, $default, $vars, $path)
{
$mockRequest = $this->getMock('\pjdietz\WellRESTed\Interfaces\RequestInterface');
$mockRequest->expects($this->any())
->method('getPath')
->will($this->returnValue($path));
$route = new TemplateRoute($template, __NAMESPACE__ . '\TemplateRouteTestMockHandler', $default, $vars);
$resp = $route->getResponse($mockRequest);
$this->assertNull($resp);
}
public function nonmatchingTemplateProvider()
{
return array(
array("/cat/{id}", TemplateRoute::RE_NUM, null, "/cat/molly"),
array("/cat/{catId}/{dogId}", TemplateRoute::RE_ALPHA, null, "/cat/12/13"),
array("/cat/{catId}/{dogId}", TemplateRoute::RE_NUM, array(
"catId" => TemplateRoute::RE_ALPHA,
"dogId" => TemplateRoute::RE_ALPHA),
"/cat/12/13")
);
}
}
/**
* Mini Handler class that allways returns a 200 status code Response.
*/
class TemplateRouteTestMockHandler implements HandlerInterface
{
public function getResponse(RequestInterface $request, array $args = null)
{
$resp = new Response();
$resp->setStatusCode(200);
$resp->setBody(json_encode($args));
return $resp;
}
}