diff --git a/README.md b/README.md
index 2e828d9..a44341f 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ $json = <<<'JSON'
JSON;
$builder = new RouteBuilder();
-$routes = $builder->buildRoutesFromJson($json);
+$routes = $builder->buildRoutes($json);
$router = new Router();
$router->addRoutes($routes);
diff --git a/composer.json b/composer.json
index fd426f1..c4f42ad 100644
--- a/composer.json
+++ b/composer.json
@@ -14,6 +14,9 @@
"require": {
"php": ">=5.3.0"
},
+ "require-dev": {
+ "phpunit/phpunit": "4.1.*"
+ },
"autoload": {
"psr-0": { "pjdietz\\WellRESTed": "src/" },
"classmap": ["src/pjdietz/WellRESTed/Exceptions/HttpExceptions.php"]
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..8827332
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,714 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "ff7bc5c6c0cd51153b947901dc3d51af",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "2.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "ed8ac99ce38c3fd134128c898f7ca74665abef7f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ed8ac99ce38c3fd134128c898f7ca74665abef7f",
+ "reference": "ed8ac99ce38c3fd134128c898f7ca74665abef7f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-file-iterator": "~1.3.1",
+ "phpunit/php-text-template": "~1.2.0",
+ "phpunit/php-token-stream": "~1.2.2",
+ "sebastian/environment": "~1.0.0",
+ "sebastian/version": "~1.0.3"
+ },
+ "require-dev": {
+ "ext-xdebug": ">=2.1.4",
+ "phpunit/phpunit": "~4.0.14"
+ },
+ "suggest": {
+ "ext-dom": "*",
+ "ext-xdebug": ">=2.2.1",
+ "ext-xmlwriter": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2014-06-29 08:14:40"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "File/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2013-10-10 15:34:57"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
+ "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "Text/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2014-01-30 17:20:04"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+ "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "PHP/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2013-08-02 07:42:54"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
+ "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHP/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2014-03-03 05:10:30"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "4.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "939cb801b3b2aa253aedd0b279f40bb8f35cec91"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/939cb801b3b2aa253aedd0b279f40bb8f35cec91",
+ "reference": "939cb801b3b2aa253aedd0b279f40bb8f35cec91",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "php": ">=5.3.3",
+ "phpunit/php-code-coverage": "~2.0",
+ "phpunit/php-file-iterator": "~1.3.1",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "~1.0.2",
+ "phpunit/phpunit-mock-objects": "~2.1",
+ "sebastian/comparator": "~1.0",
+ "sebastian/diff": "~1.1",
+ "sebastian/environment": "~1.0",
+ "sebastian/exporter": "~1.0",
+ "sebastian/version": "~1.0",
+ "symfony/yaml": "~2.0"
+ },
+ "suggest": {
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ "",
+ "../../symfony/yaml/"
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "http://www.phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2014-06-11 14:15:47"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "2.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "7878b9c41edb3afab92b85edf5f0981014a2713a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/7878b9c41edb3afab92b85edf5f0981014a2713a",
+ "reference": "7878b9c41edb3afab92b85edf5f0981014a2713a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-text-template": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.1"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2014-06-12 07:22:15"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
+ "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.1",
+ "sebastian/exporter": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2014-05-02 07:05:58"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
+ "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "http://www.github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2013-08-03 16:46:33"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a",
+ "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.0.*@dev"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2014-02-18 16:17:19"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
+ "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.0.*@dev"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net",
+ "role": "Lead"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2014-02-16 08:26:31"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
+ "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2014-03-07 15:35:33"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v2.5.1",
+ "target-dir": "Symfony/Component/Yaml",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Yaml.git",
+ "reference": "1057e87364c0b38b50f5695fc9df9dd189036bec"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/1057e87364c0b38b50f5695fc9df9dd189036bec",
+ "reference": "1057e87364c0b38b50f5695fc9df9dd189036bec",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.5-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Yaml\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "http://symfony.com",
+ "time": "2014-07-08 12:21:33"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "platform": {
+ "php": ">=5.3.0"
+ },
+ "platform-dev": []
+}
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..ca23fcd
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ ./test/
+
+
+
diff --git a/src/pjdietz/WellRESTed/RouteBuilder.php b/src/pjdietz/WellRESTed/RouteBuilder.php
index 3749711..78de6c1 100644
--- a/src/pjdietz/WellRESTed/RouteBuilder.php
+++ b/src/pjdietz/WellRESTed/RouteBuilder.php
@@ -15,26 +15,46 @@ use pjdietz\WellRESTed\Interfaces\HandlerInterface;
use pjdietz\WellRESTed\Routes\RegexRoute;
use pjdietz\WellRESTed\Routes\StaticRoute;
use pjdietz\WellRESTed\Routes\TemplateRoute;
-use stdClass;
/**
* Class for facilitating constructing Routers.
*/
class RouteBuilder
{
- private $handlerNamespace;
- private $templateVariablePatterns;
+ /** @var string Regex pattern to use for URI template patters. */
private $defaultVariablePattern;
+ /** @var string Common prefix to affix to handler class names. */
+ private $handlerNamespace;
+ /** @var array Associative array of variable names and regex patterns. */
+ private $templateVariablePatterns;
/**
* Contruct and return an array of routes.
*
- * @param $data
- * @return array
+ * If $data is a string, buildRoutes() will parse it as JSON with json_decode.
+ *
+ * If $data is an array, buildRoutes() assumes each item in the array is
+ * an object it can translate into a route.
+ *
+ * If $data is an object, buildRoutes() assumes it will have a "routes"
+ * property with an array value that is a collection of objects to
+ * translate into routes. Any other properties will be read with
+ * readConfiguration()
+ *
+ * @param string|array|object $data Description of routes to build.
+ * @return array List of routes to add to a router.
* @throws Exceptions\ParseException
*/
public function buildRoutes($data)
{
+ // If $data is a string, attempt to parse it as JSON.
+ if (is_string($data)) {
+ $data = json_decode($data);
+ if (is_null($data)) {
+ throw new ParseException("Unable to parse as JSON.");
+ }
+ }
+
// Locate the list of routes. This should be one of these:
// - If $data is an object, $data->routes
// - If $data is an array, $data
@@ -55,12 +75,116 @@ class RouteBuilder
return $routes;
}
- public function buildRoutesFromJson($json) {
- return $this->buildRoutes(json_decode($json));
+ /**
+ * Parse an object and update the instances with the new configuration.
+ *
+ * ->handlerNamespace is passed to setHandlerNamesapce()
+ *
+ * ->variablePattern is passed to setDefaultVariablePattern()
+ *
+ * ->vars is passed to setTemplateVars()
+ */
+ public function readConfiguration($data)
+ {
+ if (isset($data->handlerNamespace)) {
+ $this->setHandlerNamespace($data->handlerNamespace);
+ }
+ if (isset($data->variablePattern)) {
+ $this->setDefaultVariablePattern($data->variablePattern);
+ }
+ if (isset($data->vars)) {
+ $this->setTemplateVars((array) $data->vars);
+ }
}
/**
- * @param stdClass|array $item
+ * Return the string to prepend to handler class names.
+ *
+ * @return string
+ */
+ public function getHandlerNamespace()
+ {
+ return $this->handlerNamespace;
+ }
+
+ /**
+ * Set the prefix to prepend to handler class names.
+ *
+ * @param mixed $handlerNamespace
+ */
+ public function setHandlerNamespace($handlerNamespace = "")
+ {
+ $this->handlerNamespace = $handlerNamespace;
+ }
+
+ /**
+ * Return an associative array of variable names and regex patterns.
+ *
+ * @return mixed
+ */
+ public function getTemplateVars()
+ {
+ return $this->templateVariablePatterns;
+ }
+
+ /**
+ * Set the array of template variable patterns.
+ *
+ * Keys are names of variables for use in URI template (do not include {}).
+ * Values are regex patterns or any of the following special names: SLUG,
+ * ALPHA, ALPHANUM, DIGIT, NUM.
+ *
+ * If you wish to use additional named patterns, subclass RouteBuilder and
+ * override getTemplateVariablePattern.
+ *
+ * @param array $vars Associative array of variable name => pattern
+ */
+ public function setTemplateVars(array $vars)
+ {
+ foreach ($vars as $name => $var) {
+ $vars[$name] = $this->getTemplateVariablePattern($var);
+ }
+ $this->templateVariablePatterns = $vars;
+ }
+
+ /**
+ * Return the default regex pattern to use for URI template variables.
+ *
+ * @return string
+ */
+ public function getDefaultVariablePattern()
+ {
+ return $this->defaultVariablePattern;
+ }
+
+ /**
+ * Set the default regex pattern to use for URI template variables.
+ *
+ * $defaultVariablePattern may be a regex pattern or one of the following:
+ * SLUG, ALPHA, ALPHANUM, DIGIT, NUM.
+ *
+ * If you wish to use additional named patterns, subclass RouteBuilder and
+ * override getTemplateVariablePattern.
+ *
+ * @param mixed $defaultVariablePattern
+ */
+ public function setDefaultVariablePattern($defaultVariablePattern)
+ {
+ $this->defaultVariablePattern = $this->getTemplateVariablePattern($defaultVariablePattern);
+ }
+
+ /**
+ * Create and return an approrate route given an object describing a route.
+ *
+ * $item must contain a "handler" property providing the classname for the
+ * HandlerInterface to call getResponse() on if the route matches. "handler"
+ * may be fully qualified and begin with "\". If it does not begin with "\",
+ * the instance's $handlerNamespace is affixed to the begining.
+ *
+ * $item must also contain a "path", "template", or "pattern" property to
+ * indicate how to create the StaticRoute, TemplateRoute, or RegexRoute.
+ *
+ * @param object|array $item
* @return HandlerInterface
* @throws Exceptions\ParseException
*/
@@ -93,7 +217,7 @@ class RouteBuilder
return new TemplateRoute($item->template, $handler, $this->getDefaultVariablePattern(), $vars);
}
- // Regex Rout
+ // Regex Route
if (isset($item->pattern)) {
return new RegexRoute($item->pattern, $handler);
}
@@ -101,20 +225,20 @@ class RouteBuilder
return null;
}
- protected function readConfiguration($data)
+ /**
+ * Provide a regular expression pattern given a name.
+ *
+ * The names SLUG, ALPHA, ALPHANUM, DIGIT, NUM convert to regex patterns.
+ * Anything else passes through as is.
+ *
+ * If you wish to use additional named patterns, subclass RouteBuilder and
+ * override getTemplateVariablePattern.
+ *
+ * @param string $variable Regex pattern or name (SLUG, ALPHA, ALPHANUM, DIGIT, NUM
+ * @return string
+ */
+ protected function getTemplateVariablePattern($variable)
{
- if (isset($data->handlerNamespace)) {
- $this->setHandlerNamespace($data->handlerNamespace);
- }
- if (isset($data->variablePattern)) {
- $this->setDefaultVariablePattern($data->variablePattern);
- }
- if (isset($data->vars)) {
- $this->setTemplateVars((array) $data->vars);
- }
- }
-
- protected function getTemplateVariablePattern($variable) {
switch ($variable) {
case "SLUG":
return TemplateRoute::RE_SLUG;
@@ -130,56 +254,4 @@ class RouteBuilder
}
}
- /**
- * @param mixed $handlerNamespace
- */
- public function setHandlerNamespace($handlerNamespace)
- {
- $this->handlerNamespace = $handlerNamespace;
- }
-
- /**
- * @return mixed
- */
- public function getHandlerNamespace()
- {
- return $this->handlerNamespace;
- }
-
- /**
- * @param array $vars
- * @internal param mixed $templateVars
- */
- public function setTemplateVars(array $vars)
- {
- foreach ($vars as $name => $var) {
- $vars[$name] = $this->getTemplateVariablePattern($var);
- }
- $this->templateVariablePatterns = $vars;
- }
-
- /**
- * @return mixed
- */
- public function getTemplateVars()
- {
- return $this->templateVariablePatterns;
- }
-
- /**
- * @param mixed $defaultVariablePattern
- */
- public function setDefaultVariablePattern($defaultVariablePattern)
- {
- $this->defaultVariablePattern = $this->getTemplateVariablePattern($defaultVariablePattern);
- }
-
- /**
- * @return mixed
- */
- public function getDefaultVariablePattern()
- {
- return $this->defaultVariablePattern;
- }
-
}
diff --git a/src/pjdietz/WellRESTed/Routes/BaseRoute.php b/src/pjdietz/WellRESTed/Routes/BaseRoute.php
index 017014c..00967bf 100644
--- a/src/pjdietz/WellRESTed/Routes/BaseRoute.php
+++ b/src/pjdietz/WellRESTed/Routes/BaseRoute.php
@@ -10,7 +10,7 @@ use pjdietz\WellRESTed\Interfaces\HandlerInterface;
abstract class BaseRoute implements HandlerInterface
{
/** @var string Fully qualified name for the interface for handlers */
- const DISPATCHER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface';
+ const HANDLER_INTERFACE = '\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface';
/** @var string */
private $targetClassName;
@@ -29,7 +29,7 @@ abstract class BaseRoute implements HandlerInterface
*/
protected function getTarget()
{
- if (is_subclass_of($this->targetClassName, self::DISPATCHER_INTERFACE)) {
+ if (is_subclass_of($this->targetClassName, self::HANDLER_INTERFACE)) {
/** @var HandlerInterface $target */
$target = new $this->targetClassName();
return $target;
diff --git a/test/RouteBuilderTest.php b/test/RouteBuilderTest.php
new file mode 100644
index 0000000..be78c27
--- /dev/null
+++ b/test/RouteBuilderTest.php
@@ -0,0 +1,168 @@
+buildRoutes($json);
+ $this->assertEquals(3, count($routes));
+ }
+
+ /**
+ * Fail properly on malformed JSON
+ *
+ * @expectedException \pjdietz\WellRESTed\Exceptions\ParseException
+ * @expectedExceptionMessage Unable to parse as JSON.
+ */
+ public function testBuildInvalidJson()
+ {
+ $json = "jadhjaksd";
+ $builder = new RouteBuilder();
+ $routes = $builder->buildRoutes($json);
+ }
+
+ public function testNamesapce()
+ {
+ $namespace = "\\test\\Namespace";
+ $builder = new RouteBuilder();
+ $builder->setHandlerNamespace($namespace);
+ $this->assertEquals($namespace, $builder->getHandlerNamespace());
+ }
+
+ /**
+ * @dataProvider varProvider
+ */
+ public function testDefaultVariablePattern($name, $pattern, $expected)
+ {
+ $builder = new RouteBuilder();
+ $builder->setDefaultVariablePattern($pattern);
+ $this->assertEquals($builder->getDefaultVariablePattern(), $expected);
+ }
+
+ /**
+ * @dataProvider varProvider
+ */
+ public function testConfigurationDefaultVariablePattern($name, $pattern, $expected)
+ {
+ $builder = new RouteBuilder();
+ $conf = new stdClass();
+ $conf->variablePattern = $pattern;
+ $builder->readConfiguration($conf);
+ $this->assertEquals($builder->getDefaultVariablePattern(), $expected);
+ }
+
+ /**
+ * @dataProvider varProvider
+ */
+ public function testTemplateVariables($name, $pattern, $expected)
+ {
+ $builder = new RouteBuilder();
+ $builder->setTemplateVars(array($name => $pattern));
+ $vars = $builder->getTemplateVars();
+ $this->assertEquals($vars[$name], $expected);
+ }
+
+ /**
+ * @dataProvider varProvider
+ */
+ public function testConfigurationTemplateVariables($name, $pattern, $expected)
+ {
+ $builder = new RouteBuilder();
+ $conf = new stdClass();
+ $conf->vars = array($name => $pattern);
+ $builder->readConfiguration($conf);
+ $vars = $builder->getTemplateVars();
+ $this->assertEquals($vars[$name], $expected);
+ }
+
+ public function varProvider()
+ {
+ return array(
+ array("slug", "SLUG", TemplateRoute::RE_SLUG),
+ array("name", "ALPHA", TemplateRoute::RE_ALPHA),
+ array("name", "ALPHANUM", TemplateRoute::RE_ALPHANUM),
+ array("id", "DIGIT", TemplateRoute::RE_NUM),
+ array("id", "NUM", TemplateRoute::RE_NUM),
+ array("custom", ".*", ".*")
+ );
+ }
+
+ /**
+ * @dataProvider routeDescriptionProvider
+ */
+ public function testRoutes($key, $value, $expectedClass)
+ {
+ $mock = $this->getMock('\pjdietz\WellRESTed\Interfaces\HandlerInterface');
+ $routes = array(
+ (object) array(
+ $key => $value,
+ "handler" => get_class($mock)
+ )
+ );
+ $builder = new RouteBuilder();
+ $routes = $builder->buildRoutes($routes);
+ $route = $routes[0];
+ $this->assertInstanceOf($expectedClass, $route);
+ }
+
+ /**
+ * @dataProvider routeDescriptionProvider
+ */
+ public function testRoutesObject($key, $value, $expectedClass)
+ {
+ $mock = $this->getMock('\pjdietz\WellRESTed\Interfaces\HandlerInterface');
+ $conf = (object) array(
+ "routes" => array(
+ (object) array(
+ $key => $value,
+ "handler" => get_class($mock)
+ )
+ )
+ );
+ $builder = new RouteBuilder();
+ $routes = $builder->buildRoutes($conf);
+ $route = $routes[0];
+ $this->assertInstanceOf($expectedClass, $route);
+ }
+
+ public function routeDescriptionProvider()
+ {
+ return array(
+ array("path", "/", '\pjdietz\WellRESTed\Routes\StaticRoute'),
+ array("pattern", "/cat/[0-9]+", '\pjdietz\WellRESTed\Routes\RegexRoute'),
+ array("template", "/cat/{id}", '\pjdietz\WellRESTed\Routes\TemplateRoute'),
+ );
+ }
+
+}