Skip to content

Commit

Permalink
Add ability to inject route instances.
Browse files Browse the repository at this point in the history
Being able to inject route instances makes testing a few different
scenarios easier. It also follows the patterns in Cache, and Log.

This change also simplifies instance checking for routes.
  • Loading branch information
markstory committed Jun 27, 2014
1 parent b34d43c commit ac4f411
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 30 deletions.
57 changes: 27 additions & 30 deletions src/Routing/ScopedRouteCollection.php
Expand Up @@ -352,25 +352,7 @@ public function connect($route, array $defaults = [], $options = []) {
$options['_ext'] = $this->_extensions;
}

// TODO don't hardcode
$routeClass = 'Cake\Routing\Route\Route';
if (isset($options['routeClass'])) {
$routeClass = App::className($options['routeClass'], 'Routing/Route');
$routeClass = $this->_validateRouteClass($routeClass);
unset($options['routeClass']);
}
if ($routeClass === 'Cake\Routing\Route\RedirectRoute' && isset($defaults['redirect'])) {
$defaults = $defaults['redirect'];
}

$route = str_replace('//', '/', $this->_path . $route);
if (is_array($defaults)) {
$defaults += $this->_params;
}

// Store the route and named index if possible.
$route = new $routeClass($route, $defaults, $options);

$route = $this->_makeRoute($route, $defaults, $options);
if (isset($options['_name'])) {
$this->_named[$options['_name']] = $route;
}
Expand All @@ -384,20 +366,35 @@ public function connect($route, array $defaults = [], $options = []) {
}

/**
* Validates that the passed route class exists and is a subclass of Cake\Routing\Route\Route
* Create a route object, or return the provided object.
*
* @param string $routeClass Route class name
* @return string
* @throws \Cake\Error\Exception
* @param string|\Cake\Routing\Route\Route $route The route template or route object.
* @param array $defaults Default parameters.
* @param array $options Additional options parameters.
* @return \Cake\Routing\Route\Route
*/
protected function _validateRouteClass($routeClass) {
if (
$routeClass !== 'Cake\Routing\Route\Route' &&
(!class_exists($routeClass) || !is_subclass_of($routeClass, 'Cake\Routing\Route\Route'))
) {
throw new Error\Exception('Route class not found, or route class is not a subclass of Cake\Routing\Route\Route');
protected function _makeRoute($route, $defaults, $options) {
if (is_string($route)) {
$routeClass = 'Cake\Routing\Route\Route';
if (isset($options['routeClass'])) {
$routeClass = App::className($options['routeClass'], 'Routing/Route');
unset($options['routeClass']);
}
if ($routeClass === 'Cake\Routing\Route\RedirectRoute' && isset($defaults['redirect'])) {
$defaults = $defaults['redirect'];
}

$route = str_replace('//', '/', $this->_path . $route);
if (is_array($defaults)) {
$defaults += $this->_params;
}
$route = new $routeClass($route, $defaults, $options);
}

if ($route instanceof Route) {
return $route;
}
return $routeClass;
throw new Error\Exception('Route class not found, or route class is not a subclass of Cake\Routing\Route\Route');
}

/**
Expand Down
15 changes: 15 additions & 0 deletions tests/TestCase/Routing/ScopedRouteCollectionTest.php
Expand Up @@ -101,6 +101,21 @@ public function testGetNamed() {
$this->assertEquals('/l/:controller', $route->template);
}

/**
* Test connecting an instance routes.
*
* @return void
*/
public function testConnectInstance() {
$routes = new ScopedRouteCollection('/l', ['prefix' => 'api']);

$route = new Route('/:controller');
$this->assertNull($routes->connect($route));

$result = $routes->routes()[0];
$this->assertSame($route, $result);
}

/**
* Test connecting basic routes.
*
Expand Down

0 comments on commit ac4f411

Please sign in to comment.