diff --git a/cake/libs/route/cake_route.php b/cake/libs/route/cake_route.php new file mode 100644 index 000000000..706323f3a --- /dev/null +++ b/cake/libs/route/cake_route.php @@ -0,0 +1,371 @@ + 'content_type', + 'method' => 'request_method', + 'server' => 'server_name' + ); + +/** + * Constructor for a Route + * + * @param string $template Template string with parameter placeholders + * @param array $defaults Array of defaults for the route. + * @param string $params Array of parameters and additional options for the Route + * @return void + */ + public function __construct($template, $defaults = array(), $options = array()) { + $this->template = $template; + $this->defaults = (array)$defaults; + $this->options = (array)$options; + } + +/** + * Check if a Route has been compiled into a regular expression. + * + * @return boolean + */ + public function compiled() { + return !empty($this->_compiledRoute); + } + +/** + * Compiles the route's regular expression. Modifies defaults property so all necessary keys are set + * and populates $this->names with the named routing elements. + * + * @return array Returns a string regular expression of the compiled route. + */ + public function compile() { + if ($this->compiled()) { + return $this->_compiledRoute; + } + $this->_writeRoute(); + return $this->_compiledRoute; + } + +/** + * Builds a route regular expression. Uses the template, defaults and options + * properties to compile a regular expression that can be used to parse request strings. + * + * @return void + */ + protected function _writeRoute() { + if (empty($this->template) || ($this->template === '/')) { + $this->_compiledRoute = '#^/*$#'; + $this->keys = array(); + return; + } + $route = $this->template; + $names = $routeParams = array(); + $parsed = preg_quote($this->template, '#'); + + preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements); + foreach ($namedElements[1] as $i => $name) { + $search = '\\' . $namedElements[0][$i]; + if (isset($this->options[$name])) { + $option = null; + if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) { + $option = '?'; + } + $slashParam = '/\\' . $namedElements[0][$i]; + if (strpos($parsed, $slashParam) !== false) { + $routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; + } else { + $routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; + } + } else { + $routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))'; + } + $names[] = $name; + } + if (preg_match('#\/\*$#', $route, $m)) { + $parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed); + $this->_greedy = true; + } + krsort($routeParams); + $parsed = str_replace(array_keys($routeParams), array_values($routeParams), $parsed); + $this->_compiledRoute = '#^' . $parsed . '[/]*$#'; + $this->keys = $names; + } + +/** + * Checks to see if the given URL can be parsed by this route. + * If the route can be parsed an array of parameters will be returned if not + * false will be returned. String urls are parsed if they match a routes regular expression. + * + * @param string $url The url to attempt to parse. + * @return mixed Boolean false on failure, otherwise an array or parameters + */ + public function parse($url) { + if (!$this->compiled()) { + $this->compile(); + } + if (!preg_match($this->_compiledRoute, $url, $route)) { + return false; + } else { + foreach ($this->defaults as $key => $val) { + if ($key[0] === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) { + if (isset($this->__headerMap[$header[1]])) { + $header = $this->__headerMap[$header[1]]; + } else { + $header = 'http_' . $header[1]; + } + + $val = (array)$val; + $h = false; + + foreach ($val as $v) { + if (env(strtoupper($header)) === $v) { + $h = true; + } + } + if (!$h) { + return false; + } + } + } + array_shift($route); + $count = count($this->keys); + for ($i = 0; $i <= $count; $i++) { + unset($route[$i]); + } + $route['pass'] = $route['named'] = array(); + $route += $this->defaults; + + //move numerically indexed elements from the defaults into pass. + foreach ($route as $key => $value) { + if (is_integer($key)) { + $route['pass'][] = $value; + unset($route[$key]); + } + } + return $route; + } + } + +/** + * Apply persistent parameters to a url array. Persistant parameters are a special + * key used during route creation to force route parameters to persist when omitted from + * a url array. + * + * @param array $url The array to apply persistent parameters to. + * @param array $params An array of persistent values to replace persistent ones. + * @return array An array with persistent parameters applied. + */ + public function persistParams($url, $params) { + foreach ($this->options['persist'] as $persistKey) { + if (array_key_exists($persistKey, $params) && !isset($url[$persistKey])) { + $url[$persistKey] = $params[$persistKey]; + } + } + return $url; + } + +/** + * Attempt to match a url array. If the url matches the route parameters + settings, then + * return a generated string url. If the url doesn't match the route parameters false will be returned. + * This method handles the reverse routing or conversion of url arrays into string urls. + * + * @param array $url An array of parameters to check matching with. + * @return mixed Either a string url for the parameters if they match or false. + */ + public function match($url) { + if (!$this->compiled()) { + $this->compile(); + } + $defaults = $this->defaults; + + if (isset($defaults['prefix'])) { + $url['prefix'] = $defaults['prefix']; + } + + //check that all the key names are in the url + $keyNames = array_flip($this->keys); + if (array_intersect_key($keyNames, $url) != $keyNames) { + return false; + } + + $diffUnfiltered = Set::diff($url, $defaults); + $diff = array(); + + foreach ($diffUnfiltered as $key => $var) { + if ($var === 0 || $var === '0' || !empty($var)) { + $diff[$key] = $var; + } + } + + //if a not a greedy route, no extra params are allowed. + if (!$this->_greedy && array_diff_key($diff, $keyNames) != array()) { + return false; + } + + //remove defaults that are also keys. They can cause match failures + foreach ($this->keys as $key) { + unset($defaults[$key]); + } + $filteredDefaults = array_filter($defaults); + + //if the difference between the url diff and defaults contains keys from defaults its not a match + if (array_intersect_key($filteredDefaults, $diffUnfiltered) !== array()) { + return false; + } + + $passedArgsAndParams = array_diff_key($diff, $filteredDefaults, $keyNames); + list($named, $params) = Router::getNamedElements($passedArgsAndParams, $url['controller'], $url['action']); + + //remove any pass params, they have numeric indexes, skip any params that are in the defaults + $pass = array(); + $i = 0; + while (isset($url[$i])) { + if (!isset($diff[$i])) { + $i++; + continue; + } + $pass[] = $url[$i]; + unset($url[$i], $params[$i]); + $i++; + } + + //still some left over parameters that weren't named or passed args, bail. + if (!empty($params)) { + return false; + } + + //check patterns for routed params + if (!empty($this->options)) { + foreach ($this->options as $key => $pattern) { + if (array_key_exists($key, $url) && !preg_match('#^' . $pattern . '$#', $url[$key])) { + return false; + } + } + } + return $this->_writeUrl(array_merge($url, compact('pass', 'named'))); + } + +/** + * Converts a matching route array into a url string. Composes the string url using the template + * used to create the route. + * + * @param array $params The params to convert to a string url. + * @return string Composed route string. + */ + protected function _writeUrl($params) { + if (isset($params['prefix'], $params['action'])) { + $params['action'] = str_replace($params['prefix'] . '_', '', $params['action']); + unset($params['prefix']); + } + + if (is_array($params['pass'])) { + $params['pass'] = implode('/', $params['pass']); + } + + $separator = Router::$named['separator']; + + if (!empty($params['named']) && is_array($params['named'])) { + $named = array(); + foreach ($params['named'] as $key => $value) { + $named[] = $key . $separator . $value; + } + $params['pass'] = $params['pass'] . '/' . implode('/', $named); + } + $out = $this->template; + + $search = $replace = array(); + foreach ($this->keys as $key) { + $string = null; + if (isset($params[$key])) { + $string = $params[$key]; + } elseif (strpos($out, $key) != strlen($out) - strlen($key)) { + $key .= '/'; + } + $search[] = ':' . $key; + $replace[] = $string; + } + $out = str_replace($search, $replace, $out); + + if (strpos($this->template, '*')) { + $out = str_replace('*', $params['pass'], $out); + } + $out = str_replace('//', '/', $out); + return $out; + } +} \ No newline at end of file diff --git a/cake/libs/route/plugin_short_route.php b/cake/libs/route/plugin_short_route.php new file mode 100644 index 000000000..1c1c4330b --- /dev/null +++ b/cake/libs/route/plugin_short_route.php @@ -0,0 +1,56 @@ +defaults['controller'] = $url['controller']; + $result = parent::match($url); + unset($this->defaults['controller']); + return $result; + } +} \ No newline at end of file diff --git a/cake/libs/router.php b/cake/libs/router.php index e714a4945..aed15183c 100644 --- a/cake/libs/router.php +++ b/cake/libs/router.php @@ -19,6 +19,7 @@ */ App::import('Core', 'CakeRequest'); +App::import('Core', 'route/CakeRoute'); /** * Parses the request URL into controller, action, and parameters. @@ -526,6 +527,7 @@ class Router { */ function __connectDefaultRoutes() { if ($plugins = App::objects('plugin')) { + App::import('Core', 'route/PluginShortRoute'); foreach ($plugins as $key => $value) { $plugins[$key] = Inflector::underscore($value); } @@ -1161,408 +1163,8 @@ class Router { } } +//Save the initial state Router::reload(); -/** - * A single Route used by the Router to connect requests to - * parameter maps. - * - * Not normally created as a standalone. Use Router::connect() to create - * Routes for your application. - * - * @package cake.libs - * @since 1.3.0 - * @see Router::connect() - */ -class CakeRoute { - -/** - * An array of named segments in a Route. - * `/:controller/:action/:id` has 3 key elements - * - * @var array - * @access public - */ - public $keys = array(); - -/** - * An array of additional parameters for the Route. - * - * @var array - * @access public - */ - public $options = array(); - -/** - * Default parameters for a Route - * - * @var array - * @access public - */ - public $defaults = array(); - -/** - * The routes template string. - * - * @var string - * @access public - */ - public $template = null; - -/** - * Is this route a greedy route? Greedy routes have a `/*` in their - * template - * - * @var string - * @access protected - */ - protected $_greedy = false; - -/** - * The compiled route regular expresssion - * - * @var string - * @access protected - */ - protected $_compiledRoute = null; - -/** - * HTTP header shortcut map. Used for evaluating header-based route expressions. - * - * @var array - * @access private - */ - private $__headerMap = array( - 'type' => 'content_type', - 'method' => 'request_method', - 'server' => 'server_name' - ); - -/** - * Constructor for a Route - * - * @param string $template Template string with parameter placeholders - * @param array $defaults Array of defaults for the route. - * @param string $params Array of parameters and additional options for the Route - * @return void - */ - public function __construct($template, $defaults = array(), $options = array()) { - $this->template = $template; - $this->defaults = (array)$defaults; - $this->options = (array)$options; - } - -/** - * Check if a Route has been compiled into a regular expression. - * - * @return boolean - */ - public function compiled() { - return !empty($this->_compiledRoute); - } - -/** - * Compiles the route's regular expression. Modifies defaults property so all necessary keys are set - * and populates $this->names with the named routing elements. - * - * @return array Returns a string regular expression of the compiled route. - */ - public function compile() { - if ($this->compiled()) { - return $this->_compiledRoute; - } - $this->_writeRoute(); - return $this->_compiledRoute; - } - -/** - * Builds a route regular expression. Uses the template, defaults and options - * properties to compile a regular expression that can be used to parse request strings. - * - * @return void - */ - protected function _writeRoute() { - if (empty($this->template) || ($this->template === '/')) { - $this->_compiledRoute = '#^/*$#'; - $this->keys = array(); - return; - } - $route = $this->template; - $names = $routeParams = array(); - $parsed = preg_quote($this->template, '#'); - - preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements); - foreach ($namedElements[1] as $i => $name) { - $search = '\\' . $namedElements[0][$i]; - if (isset($this->options[$name])) { - $option = null; - if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) { - $option = '?'; - } - $slashParam = '/\\' . $namedElements[0][$i]; - if (strpos($parsed, $slashParam) !== false) { - $routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; - } else { - $routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option; - } - } else { - $routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))'; - } - $names[] = $name; - } - if (preg_match('#\/\*$#', $route, $m)) { - $parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed); - $this->_greedy = true; - } - krsort($routeParams); - $parsed = str_replace(array_keys($routeParams), array_values($routeParams), $parsed); - $this->_compiledRoute = '#^' . $parsed . '[/]*$#'; - $this->keys = $names; - } - -/** - * Checks to see if the given URL can be parsed by this route. - * If the route can be parsed an array of parameters will be returned if not - * false will be returned. String urls are parsed if they match a routes regular expression. - * - * @param string $url The url to attempt to parse. - * @return mixed Boolean false on failure, otherwise an array or parameters - */ - public function parse($url) { - if (!$this->compiled()) { - $this->compile(); - } - if (!preg_match($this->_compiledRoute, $url, $route)) { - return false; - } else { - foreach ($this->defaults as $key => $val) { - if ($key[0] === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) { - if (isset($this->__headerMap[$header[1]])) { - $header = $this->__headerMap[$header[1]]; - } else { - $header = 'http_' . $header[1]; - } - - $val = (array)$val; - $h = false; - - foreach ($val as $v) { - if (env(strtoupper($header)) === $v) { - $h = true; - } - } - if (!$h) { - return false; - } - } - } - array_shift($route); - $count = count($this->keys); - for ($i = 0; $i <= $count; $i++) { - unset($route[$i]); - } - $route['pass'] = $route['named'] = array(); - $route += $this->defaults; - - //move numerically indexed elements from the defaults into pass. - foreach ($route as $key => $value) { - if (is_integer($key)) { - $route['pass'][] = $value; - unset($route[$key]); - } - } - return $route; - } - } - -/** - * Apply persistent parameters to a url array. Persistant parameters are a special - * key used during route creation to force route parameters to persist when omitted from - * a url array. - * - * @param array $url The array to apply persistent parameters to. - * @param array $params An array of persistent values to replace persistent ones. - * @return array An array with persistent parameters applied. - */ - public function persistParams($url, $params) { - foreach ($this->options['persist'] as $persistKey) { - if (array_key_exists($persistKey, $params) && !isset($url[$persistKey])) { - $url[$persistKey] = $params[$persistKey]; - } - } - return $url; - } - -/** - * Attempt to match a url array. If the url matches the route parameters + settings, then - * return a generated string url. If the url doesn't match the route parameters false will be returned. - * This method handles the reverse routing or conversion of url arrays into string urls. - * - * @param array $url An array of parameters to check matching with. - * @return mixed Either a string url for the parameters if they match or false. - */ - public function match($url) { - if (!$this->compiled()) { - $this->compile(); - } - $defaults = $this->defaults; - - if (isset($defaults['prefix'])) { - $url['prefix'] = $defaults['prefix']; - } - - //check that all the key names are in the url - $keyNames = array_flip($this->keys); - if (array_intersect_key($keyNames, $url) != $keyNames) { - return false; - } - - $diffUnfiltered = Set::diff($url, $defaults); - $diff = array(); - - foreach ($diffUnfiltered as $key => $var) { - if ($var === 0 || $var === '0' || !empty($var)) { - $diff[$key] = $var; - } - } - - //if a not a greedy route, no extra params are allowed. - if (!$this->_greedy && array_diff_key($diff, $keyNames) != array()) { - return false; - } - - //remove defaults that are also keys. They can cause match failures - foreach ($this->keys as $key) { - unset($defaults[$key]); - } - $filteredDefaults = array_filter($defaults); - - //if the difference between the url diff and defaults contains keys from defaults its not a match - if (array_intersect_key($filteredDefaults, $diffUnfiltered) !== array()) { - return false; - } - - $passedArgsAndParams = array_diff_key($diff, $filteredDefaults, $keyNames); - list($named, $params) = Router::getNamedElements($passedArgsAndParams, $url['controller'], $url['action']); - - //remove any pass params, they have numeric indexes, skip any params that are in the defaults - $pass = array(); - $i = 0; - while (isset($url[$i])) { - if (!isset($diff[$i])) { - $i++; - continue; - } - $pass[] = $url[$i]; - unset($url[$i], $params[$i]); - $i++; - } - - //still some left over parameters that weren't named or passed args, bail. - if (!empty($params)) { - return false; - } - - //check patterns for routed params - if (!empty($this->options)) { - foreach ($this->options as $key => $pattern) { - if (array_key_exists($key, $url) && !preg_match('#^' . $pattern . '$#', $url[$key])) { - return false; - } - } - } - return $this->_writeUrl(array_merge($url, compact('pass', 'named'))); - } - -/** - * Converts a matching route array into a url string. Composes the string url using the template - * used to create the route. - * - * @param array $params The params to convert to a string url. - * @return string Composed route string. - */ - protected function _writeUrl($params) { - if (isset($params['prefix'], $params['action'])) { - $params['action'] = str_replace($params['prefix'] . '_', '', $params['action']); - unset($params['prefix']); - } - - if (is_array($params['pass'])) { - $params['pass'] = implode('/', $params['pass']); - } - - $separator = Router::$named['separator']; - - if (!empty($params['named']) && is_array($params['named'])) { - $named = array(); - foreach ($params['named'] as $key => $value) { - $named[] = $key . $separator . $value; - } - $params['pass'] = $params['pass'] . '/' . implode('/', $named); - } - $out = $this->template; - - $search = $replace = array(); - foreach ($this->keys as $key) { - $string = null; - if (isset($params[$key])) { - $string = $params[$key]; - } elseif (strpos($out, $key) != strlen($out) - strlen($key)) { - $key .= '/'; - } - $search[] = ':' . $key; - $replace[] = $string; - } - $out = str_replace($search, $replace, $out); - - if (strpos($this->template, '*')) { - $out = str_replace('*', $params['pass'], $out); - } - $out = str_replace('//', '/', $out); - return $out; - } -} - -/** - * Plugin short route, that copies the plugin param to the controller parameters - * It is used for supporting /:plugin routes. - * - * @package cake.libs - */ -class PluginShortRoute extends CakeRoute { - -/** - * Parses a string url into an array. If a plugin key is found, it will be copied to the - * controller parameter - * - * @param string $url The url to parse - * @return mixed false on failure, or an array of request parameters - */ - public function parse($url) { - $params = parent::parse($url); - if (!$params) { - return false; - } - $params['controller'] = $params['plugin']; - return $params; - } - -/** - * Reverse route plugin shortcut urls. If the plugin and controller - * are not the same the match is an auto fail. - * - * @param array $url Array of parameters to convert to a string. - * @return mixed either false or a string url. - */ - public function match($url) { - if (isset($url['controller']) && isset($url['plugin']) && $url['plugin'] != $url['controller']) { - return false; - } - $this->defaults['controller'] = $url['controller']; - $result = parent::match($url); - unset($this->defaults['controller']); - return $result; - } -} ?> \ No newline at end of file diff --git a/cake/tests/cases/libs/route/cake_route.test.php b/cake/tests/cases/libs/route/cake_route.test.php new file mode 100644 index 000000000..04f992d98 --- /dev/null +++ b/cake/tests/cases/libs/route/cake_route.test.php @@ -0,0 +1,406 @@ +_routing = Configure::read('Routing'); + Configure::write('Routing', array('admin' => null, 'prefixes' => array())); + Router::reload(); + } + +/** + * end the test and reset the environment + * + * @return void + **/ + function endTest() { + Configure::write('Routing', $this->_routing); + } + +/** + * Test the construction of a CakeRoute + * + * @return void + **/ + function testConstruction() { + $route = new CakeRoute('/:controller/:action/:id', array(), array('id' => '[0-9]+')); + + $this->assertEqual($route->template, '/:controller/:action/:id'); + $this->assertEqual($route->defaults, array()); + $this->assertEqual($route->options, array('id' => '[0-9]+')); + $this->assertFalse($route->compiled()); + } + +/** + * test Route compiling. + * + * @return void + **/ + function testBasicRouteCompiling() { + $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home')); + $result = $route->compile(); + $expected = '#^/*$#'; + $this->assertEqual($result, $expected); + $this->assertEqual($route->keys, array()); + + $route = new CakeRoute('/:controller/:action', array('controller' => 'posts')); + $result = $route->compile(); + + $this->assertPattern($result, '/posts/edit'); + $this->assertPattern($result, '/posts/super_delete'); + $this->assertNoPattern($result, '/posts'); + $this->assertNoPattern($result, '/posts/super_delete/1'); + + $route = new CakeRoute('/posts/foo:id', array('controller' => 'posts', 'action' => 'view')); + $result = $route->compile(); + + $this->assertPattern($result, '/posts/foo:1'); + $this->assertPattern($result, '/posts/foo:param'); + $this->assertNoPattern($result, '/posts'); + $this->assertNoPattern($result, '/posts/'); + + $this->assertEqual($route->keys, array('id')); + + $route = new CakeRoute('/:plugin/:controller/:action/*', array('plugin' => 'test_plugin', 'action' => 'index')); + $result = $route->compile(); + $this->assertPattern($result, '/test_plugin/posts/index'); + $this->assertPattern($result, '/test_plugin/posts/edit/5'); + $this->assertPattern($result, '/test_plugin/posts/edit/5/name:value/nick:name'); + } + +/** + * test that route parameters that overlap don't cause errors. + * + * @return void + */ + function testRouteParameterOverlap() { + $route = new CakeRoute('/invoices/add/:idd/:id', array('controller' => 'invoices', 'action' => 'add')); + $result = $route->compile(); + $this->assertPattern($result, '/invoices/add/1/3'); + + $route = new CakeRoute('/invoices/add/:id/:idd', array('controller' => 'invoices', 'action' => 'add')); + $result = $route->compile(); + $this->assertPattern($result, '/invoices/add/1/3'); + } + +/** + * test compiling routes with keys that have patterns + * + * @return void + **/ + function testRouteCompilingWithParamPatterns() { + extract(Router::getNamedExpressions()); + + $route = new CakeRoute( + '/:controller/:action/:id', + array(), + array('id' => $ID) + ); + $result = $route->compile(); + $this->assertPattern($result, '/posts/edit/1'); + $this->assertPattern($result, '/posts/view/518098'); + $this->assertNoPattern($result, '/posts/edit/name-of-post'); + $this->assertNoPattern($result, '/posts/edit/4/other:param'); + $this->assertEqual($route->keys, array('controller', 'action', 'id')); + + $route = new CakeRoute( + '/:lang/:controller/:action/:id', + array('controller' => 'testing4'), + array('id' => $ID, 'lang' => '[a-z]{3}') + ); + $result = $route->compile(); + $this->assertPattern($result, '/eng/posts/edit/1'); + $this->assertPattern($result, '/cze/articles/view/1'); + $this->assertNoPattern($result, '/language/articles/view/2'); + $this->assertNoPattern($result, '/eng/articles/view/name-of-article'); + $this->assertEqual($route->keys, array('lang', 'controller', 'action', 'id')); + + foreach (array(':', '@', ';', '$', '-') as $delim) { + $route = new CakeRoute('/posts/:id' . $delim . ':title'); + $result = $route->compile(); + + $this->assertPattern($result, '/posts/1' . $delim . 'name-of-article'); + $this->assertPattern($result, '/posts/13244' . $delim . 'name-of_Article[]'); + $this->assertNoPattern($result, '/posts/11!nameofarticle'); + $this->assertNoPattern($result, '/posts/11'); + + $this->assertEqual($route->keys, array('id', 'title')); + } + + $route = new CakeRoute( + '/posts/:id::title/:year', + array('controller' => 'posts', 'action' => 'view'), + array('id' => $ID, 'year' => $Year, 'title' => '[a-z-_]+') + ); + $result = $route->compile(); + $this->assertPattern($result, '/posts/1:name-of-article/2009/'); + $this->assertPattern($result, '/posts/13244:name-of-article/1999'); + $this->assertNoPattern($result, '/posts/hey_now:nameofarticle'); + $this->assertNoPattern($result, '/posts/:nameofarticle/2009'); + $this->assertNoPattern($result, '/posts/:nameofarticle/01'); + $this->assertEqual($route->keys, array('id', 'title', 'year')); + + $route = new CakeRoute( + '/posts/:url_title-(uuid::id)', + array('controller' => 'posts', 'action' => 'view'), + array('pass' => array('id', 'url_title'), 'id' => $ID) + ); + $result = $route->compile(); + $this->assertPattern($result, '/posts/some_title_for_article-(uuid:12534)/'); + $this->assertPattern($result, '/posts/some_title_for_article-(uuid:12534)'); + $this->assertNoPattern($result, '/posts/'); + $this->assertNoPattern($result, '/posts/nameofarticle'); + $this->assertNoPattern($result, '/posts/nameofarticle-12347'); + $this->assertEqual($route->keys, array('url_title', 'id')); + } + +/** + * test more complex route compiling & parsing with mid route greedy stars + * and optional routing parameters + * + * @return void + */ + function testComplexRouteCompilingAndParsing() { + extract(Router::getNamedExpressions()); + + $route = new CakeRoute( + '/posts/:month/:day/:year/*', + array('controller' => 'posts', 'action' => 'view'), + array('year' => $Year, 'month' => $Month, 'day' => $Day) + ); + $result = $route->compile(); + $this->assertPattern($result, '/posts/08/01/2007/title-of-post'); + $result = $route->parse('/posts/08/01/2007/title-of-post'); + + $this->assertEqual(count($result), 8); + $this->assertEqual($result['controller'], 'posts'); + $this->assertEqual($result['action'], 'view'); + $this->assertEqual($result['year'], '2007'); + $this->assertEqual($result['month'], '08'); + $this->assertEqual($result['day'], '01'); + + $route = new CakeRoute( + "/:extra/page/:slug/*", + array('controller' => 'pages', 'action' => 'view', 'extra' => null), + array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view') + ); + $result = $route->compile(); + + $this->assertPattern($result, '/some_extra/page/this_is_the_slug'); + $this->assertPattern($result, '/page/this_is_the_slug'); + $this->assertEqual($route->keys, array('extra', 'slug')); + $this->assertEqual($route->options, array('extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view')); + $expected = array( + 'controller' => 'pages', + 'action' => 'view', + 'extra' => null, + ); + $this->assertEqual($route->defaults, $expected); + + $route = new CakeRoute( + '/:controller/:action/*', + array('project' => false), + array( + 'controller' => 'source|wiki|commits|tickets|comments|view', + 'action' => 'branches|history|branch|logs|view|start|add|edit|modify' + ) + ); + $this->assertFalse($route->parse('/chaw_test/wiki')); + + $result = $route->compile(); + $this->assertNoPattern($result, '/some_project/source'); + $this->assertPattern($result, '/source/view'); + $this->assertPattern($result, '/source/view/other/params'); + $this->assertNoPattern($result, '/chaw_test/wiki'); + $this->assertNoPattern($result, '/source/wierd_action'); + } + +/** + * test that routes match their pattern. + * + * @return void + **/ + function testMatchBasic() { + $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null)); + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null)); + $this->assertFalse($result); + + $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 0)); + $this->assertFalse($result); + + $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 1)); + $this->assertEqual($result, '/posts/view/1'); + + $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home')); + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home')); + $this->assertEqual($result, '/'); + + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about')); + $this->assertFalse($result); + + + $route = new CakeRoute('/pages/*', array('controller' => 'pages', 'action' => 'display')); + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home')); + $this->assertEqual($result, '/pages/home'); + + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about')); + $this->assertEqual($result, '/pages/about'); + + + $route = new CakeRoute('/blog/:action', array('controller' => 'posts')); + $result = $route->match(array('controller' => 'posts', 'action' => 'view')); + $this->assertEqual($result, '/blog/view'); + + $result = $route->match(array('controller' => 'nodes', 'action' => 'view')); + $this->assertFalse($result); + + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 1)); + $this->assertFalse($result); + + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 2)); + $this->assertFalse($result); + + + $route = new CakeRoute('/foo/:controller/:action', array('action' => 'index')); + $result = $route->match(array('controller' => 'posts', 'action' => 'view')); + $this->assertEqual($result, '/foo/posts/view'); + + + $route = new CakeRoute('/:plugin/:id/*', array('controller' => 'posts', 'action' => 'view')); + $result = $route->match(array('plugin' => 'test', 'controller' => 'posts', 'action' => 'view', 'id' => '1')); + $this->assertEqual($result, '/test/1/'); + + $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'view', 'id' => '1', '0')); + $this->assertEqual($result, '/fo/1/0'); + + $result = $route->match(array('plugin' => 'fo', 'controller' => 'nodes', 'action' => 'view', 'id' => 1)); + $this->assertFalse($result); + + $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1)); + $this->assertFalse($result); + + + $route = new CakeRoute('/admin/subscriptions/:action/*', array( + 'controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin' + )); + + $url = array('controller' => 'subscribe', 'admin' => true, 'action' => 'edit', 1); + $result = $route->match($url); + $expected = '/admin/subscriptions/edit/1'; + $this->assertEqual($result, $expected); + } + +/** + * test match() with greedy routes, named parameters and passed args. + * + * @return void + */ + function testMatchWithNamedParametersAndPassedArgs() { + Router::connectNamed(true); + + $route = new CakeRoute('/:controller/:action/*', array('plugin' => null)); + $result = $route->match(array('controller' => 'posts', 'action' => 'index', 'plugin' => null, 'page' => 1)); + $this->assertEqual($result, '/posts/index/page:1'); + + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5)); + $this->assertEqual($result, '/posts/view/5'); + + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title')); + $this->assertEqual($result, '/posts/view/5/page:1/limit:20/order:title'); + + + $route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2)); + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 1)); + $this->assertFalse($result); + + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 2, 'something')); + $this->assertEqual($result, '/test2/something'); + + $result = $route->match(array('controller' => 'pages', 'action' => 'display', 5, 'something')); + $this->assertFalse($result); + } + +/** + * test that match with patterns works. + * + * @return void + */ + function testMatchWithPatterns() { + $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null), array('id' => '[0-9]+')); + $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 'foo')); + $this->assertFalse($result); + + $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '9')); + $this->assertEqual($result, '/posts/view/9'); + + $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '922')); + $this->assertEqual($result, '/posts/view/922'); + + $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 'a99')); + $this->assertFalse($result); + } + +/** + * test persistParams ability to persist parameters from $params and remove params. + * + * @return void + */ + function testPersistParams() { + $route = new CakeRoute( + '/:lang/:color/blog/:action', + array('controller' => 'posts'), + array('persist' => array('lang', 'color')) + ); + $url = array('controller' => 'posts', 'action' => 'index'); + $params = array('lang' => 'en', 'color' => 'blue'); + $result = $route->persistParams($url, $params); + $this->assertEqual($result['lang'], 'en'); + $this->assertEqual($result['color'], 'blue'); + + $url = array('controller' => 'posts', 'action' => 'index', 'color' => 'red'); + $params = array('lang' => 'en', 'color' => 'blue'); + $result = $route->persistParams($url, $params); + $this->assertEqual($result['lang'], 'en'); + $this->assertEqual($result['color'], 'red'); + } + +/** + * test the parse method of CakeRoute. + * + * @return void + */ + function testParse() { + extract(Router::getNamedExpressions()); + $route = new CakeRoute('/:controller/:action/:id', array('controller' => 'testing4', 'id' => null), array('id' => $ID)); + $route->compile(); + $result = $route->parse('/posts/view/1'); + $this->assertEqual($result['controller'], 'posts'); + $this->assertEqual($result['action'], 'view'); + $this->assertEqual($result['id'], '1'); + + $route = new Cakeroute( + '/admin/:controller', + array('prefix' => 'admin', 'admin' => 1, 'action' => 'index') + ); + $route->compile(); + $result = $route->parse('/admin/'); + $this->assertFalse($result); + + $result = $route->parse('/admin/posts'); + $this->assertEqual($result['controller'], 'posts'); + $this->assertEqual($result['action'], 'index'); + } +} \ No newline at end of file diff --git a/cake/tests/cases/libs/route/plugin_short_route.test.php b/cake/tests/cases/libs/route/plugin_short_route.test.php new file mode 100644 index 000000000..d52061844 --- /dev/null +++ b/cake/tests/cases/libs/route/plugin_short_route.test.php @@ -0,0 +1,61 @@ +_routing = Configure::read('Routing'); + Configure::write('Routing', array('admin' => null, 'prefixes' => array())); + Router::reload(); + } + +/** + * end the test and reset the environment + * + * @return void + **/ + function endTest() { + Configure::write('Routing', $this->_routing); + } + +/** + * test the parsing of routes. + * + * @return void + */ + function testParsing() { + $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar')); + + $result = $route->parse('/foo'); + $this->assertEqual($result['plugin'], 'foo'); + $this->assertEqual($result['controller'], 'foo'); + $this->assertEqual($result['action'], 'index'); + + $result = $route->parse('/wrong'); + $this->assertFalse($result, 'Wrong plugin name matched %s'); + } + +/** + * test the reverse routing of the plugin shortcut urls. + * + * @return void + */ + function testMatch() { + $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar')); + + $result = $route->match(array('plugin' => 'foo', 'controller' => 'posts', 'action' => 'index')); + $this->assertFalse($result, 'plugin controller mismatch was converted. %s'); + + $result = $route->match(array('plugin' => 'foo', 'controller' => 'foo', 'action' => 'index')); + $this->assertEqual($result, '/foo'); + } +} diff --git a/cake/tests/cases/libs/router.test.php b/cake/tests/cases/libs/router.test.php index 5cacbe155..bffeb544a 100644 --- a/cake/tests/cases/libs/router.test.php +++ b/cake/tests/cases/libs/router.test.php @@ -2195,466 +2195,5 @@ class RouterTest extends CakeTestCase { } } -/** - * Test case for CakeRoute - * - * @package cake.tests.cases.libs. - **/ -class CakeRouteTestCase extends CakeTestCase { -/** - * startTest method - * - * @access public - * @return void - */ - function startTest() { - $this->_routing = Configure::read('Routing'); - Configure::write('Routing', array('admin' => null, 'prefixes' => array())); - Router::reload(); - } - -/** - * end the test and reset the environment - * - * @return void - **/ - function endTest() { - Configure::write('Routing', $this->_routing); - } - -/** - * Test the construction of a CakeRoute - * - * @return void - **/ - function testConstruction() { - $route = new CakeRoute('/:controller/:action/:id', array(), array('id' => '[0-9]+')); - - $this->assertEqual($route->template, '/:controller/:action/:id'); - $this->assertEqual($route->defaults, array()); - $this->assertEqual($route->options, array('id' => '[0-9]+')); - $this->assertFalse($route->compiled()); - } - -/** - * test Route compiling. - * - * @return void - **/ - function testBasicRouteCompiling() { - $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home')); - $result = $route->compile(); - $expected = '#^/*$#'; - $this->assertEqual($result, $expected); - $this->assertEqual($route->keys, array()); - - $route = new CakeRoute('/:controller/:action', array('controller' => 'posts')); - $result = $route->compile(); - - $this->assertPattern($result, '/posts/edit'); - $this->assertPattern($result, '/posts/super_delete'); - $this->assertNoPattern($result, '/posts'); - $this->assertNoPattern($result, '/posts/super_delete/1'); - - $route = new CakeRoute('/posts/foo:id', array('controller' => 'posts', 'action' => 'view')); - $result = $route->compile(); - - $this->assertPattern($result, '/posts/foo:1'); - $this->assertPattern($result, '/posts/foo:param'); - $this->assertNoPattern($result, '/posts'); - $this->assertNoPattern($result, '/posts/'); - - $this->assertEqual($route->keys, array('id')); - - $route = new CakeRoute('/:plugin/:controller/:action/*', array('plugin' => 'test_plugin', 'action' => 'index')); - $result = $route->compile(); - $this->assertPattern($result, '/test_plugin/posts/index'); - $this->assertPattern($result, '/test_plugin/posts/edit/5'); - $this->assertPattern($result, '/test_plugin/posts/edit/5/name:value/nick:name'); - } - -/** - * test that route parameters that overlap don't cause errors. - * - * @return void - */ - function testRouteParameterOverlap() { - $route = new CakeRoute('/invoices/add/:idd/:id', array('controller' => 'invoices', 'action' => 'add')); - $result = $route->compile(); - $this->assertPattern($result, '/invoices/add/1/3'); - - $route = new CakeRoute('/invoices/add/:id/:idd', array('controller' => 'invoices', 'action' => 'add')); - $result = $route->compile(); - $this->assertPattern($result, '/invoices/add/1/3'); - } - -/** - * test compiling routes with keys that have patterns - * - * @return void - **/ - function testRouteCompilingWithParamPatterns() { - extract(Router::getNamedExpressions()); - - $route = new CakeRoute( - '/:controller/:action/:id', - array(), - array('id' => $ID) - ); - $result = $route->compile(); - $this->assertPattern($result, '/posts/edit/1'); - $this->assertPattern($result, '/posts/view/518098'); - $this->assertNoPattern($result, '/posts/edit/name-of-post'); - $this->assertNoPattern($result, '/posts/edit/4/other:param'); - $this->assertEqual($route->keys, array('controller', 'action', 'id')); - - $route = new CakeRoute( - '/:lang/:controller/:action/:id', - array('controller' => 'testing4'), - array('id' => $ID, 'lang' => '[a-z]{3}') - ); - $result = $route->compile(); - $this->assertPattern($result, '/eng/posts/edit/1'); - $this->assertPattern($result, '/cze/articles/view/1'); - $this->assertNoPattern($result, '/language/articles/view/2'); - $this->assertNoPattern($result, '/eng/articles/view/name-of-article'); - $this->assertEqual($route->keys, array('lang', 'controller', 'action', 'id')); - - foreach (array(':', '@', ';', '$', '-') as $delim) { - $route = new CakeRoute('/posts/:id' . $delim . ':title'); - $result = $route->compile(); - - $this->assertPattern($result, '/posts/1' . $delim . 'name-of-article'); - $this->assertPattern($result, '/posts/13244' . $delim . 'name-of_Article[]'); - $this->assertNoPattern($result, '/posts/11!nameofarticle'); - $this->assertNoPattern($result, '/posts/11'); - - $this->assertEqual($route->keys, array('id', 'title')); - } - - $route = new CakeRoute( - '/posts/:id::title/:year', - array('controller' => 'posts', 'action' => 'view'), - array('id' => $ID, 'year' => $Year, 'title' => '[a-z-_]+') - ); - $result = $route->compile(); - $this->assertPattern($result, '/posts/1:name-of-article/2009/'); - $this->assertPattern($result, '/posts/13244:name-of-article/1999'); - $this->assertNoPattern($result, '/posts/hey_now:nameofarticle'); - $this->assertNoPattern($result, '/posts/:nameofarticle/2009'); - $this->assertNoPattern($result, '/posts/:nameofarticle/01'); - $this->assertEqual($route->keys, array('id', 'title', 'year')); - - $route = new CakeRoute( - '/posts/:url_title-(uuid::id)', - array('controller' => 'posts', 'action' => 'view'), - array('pass' => array('id', 'url_title'), 'id' => $ID) - ); - $result = $route->compile(); - $this->assertPattern($result, '/posts/some_title_for_article-(uuid:12534)/'); - $this->assertPattern($result, '/posts/some_title_for_article-(uuid:12534)'); - $this->assertNoPattern($result, '/posts/'); - $this->assertNoPattern($result, '/posts/nameofarticle'); - $this->assertNoPattern($result, '/posts/nameofarticle-12347'); - $this->assertEqual($route->keys, array('url_title', 'id')); - } - -/** - * test more complex route compiling & parsing with mid route greedy stars - * and optional routing parameters - * - * @return void - */ - function testComplexRouteCompilingAndParsing() { - extract(Router::getNamedExpressions()); - - $route = new CakeRoute( - '/posts/:month/:day/:year/*', - array('controller' => 'posts', 'action' => 'view'), - array('year' => $Year, 'month' => $Month, 'day' => $Day) - ); - $result = $route->compile(); - $this->assertPattern($result, '/posts/08/01/2007/title-of-post'); - $result = $route->parse('/posts/08/01/2007/title-of-post'); - - $this->assertEqual(count($result), 8); - $this->assertEqual($result['controller'], 'posts'); - $this->assertEqual($result['action'], 'view'); - $this->assertEqual($result['year'], '2007'); - $this->assertEqual($result['month'], '08'); - $this->assertEqual($result['day'], '01'); - - $route = new CakeRoute( - "/:extra/page/:slug/*", - array('controller' => 'pages', 'action' => 'view', 'extra' => null), - array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view') - ); - $result = $route->compile(); - - $this->assertPattern($result, '/some_extra/page/this_is_the_slug'); - $this->assertPattern($result, '/page/this_is_the_slug'); - $this->assertEqual($route->keys, array('extra', 'slug')); - $this->assertEqual($route->options, array('extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view')); - $expected = array( - 'controller' => 'pages', - 'action' => 'view', - 'extra' => null, - ); - $this->assertEqual($route->defaults, $expected); - - $route = new CakeRoute( - '/:controller/:action/*', - array('project' => false), - array( - 'controller' => 'source|wiki|commits|tickets|comments|view', - 'action' => 'branches|history|branch|logs|view|start|add|edit|modify' - ) - ); - $this->assertFalse($route->parse('/chaw_test/wiki')); - - $result = $route->compile(); - $this->assertNoPattern($result, '/some_project/source'); - $this->assertPattern($result, '/source/view'); - $this->assertPattern($result, '/source/view/other/params'); - $this->assertNoPattern($result, '/chaw_test/wiki'); - $this->assertNoPattern($result, '/source/wierd_action'); - } - -/** - * test that routes match their pattern. - * - * @return void - **/ - function testMatchBasic() { - $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null)); - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null)); - $this->assertFalse($result); - - $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 0)); - $this->assertFalse($result); - - $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 1)); - $this->assertEqual($result, '/posts/view/1'); - - $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home')); - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home')); - $this->assertEqual($result, '/'); - - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about')); - $this->assertFalse($result); - - - $route = new CakeRoute('/pages/*', array('controller' => 'pages', 'action' => 'display')); - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home')); - $this->assertEqual($result, '/pages/home'); - - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about')); - $this->assertEqual($result, '/pages/about'); - - - $route = new CakeRoute('/blog/:action', array('controller' => 'posts')); - $result = $route->match(array('controller' => 'posts', 'action' => 'view')); - $this->assertEqual($result, '/blog/view'); - - $result = $route->match(array('controller' => 'nodes', 'action' => 'view')); - $this->assertFalse($result); - - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 1)); - $this->assertFalse($result); - - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 2)); - $this->assertFalse($result); - - - $route = new CakeRoute('/foo/:controller/:action', array('action' => 'index')); - $result = $route->match(array('controller' => 'posts', 'action' => 'view')); - $this->assertEqual($result, '/foo/posts/view'); - - - $route = new CakeRoute('/:plugin/:id/*', array('controller' => 'posts', 'action' => 'view')); - $result = $route->match(array('plugin' => 'test', 'controller' => 'posts', 'action' => 'view', 'id' => '1')); - $this->assertEqual($result, '/test/1/'); - - $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'view', 'id' => '1', '0')); - $this->assertEqual($result, '/fo/1/0'); - - $result = $route->match(array('plugin' => 'fo', 'controller' => 'nodes', 'action' => 'view', 'id' => 1)); - $this->assertFalse($result); - - $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1)); - $this->assertFalse($result); - - - $route = new CakeRoute('/admin/subscriptions/:action/*', array( - 'controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin' - )); - - $url = array('controller' => 'subscribe', 'admin' => true, 'action' => 'edit', 1); - $result = $route->match($url); - $expected = '/admin/subscriptions/edit/1'; - $this->assertEqual($result, $expected); - } - -/** - * test match() with greedy routes, named parameters and passed args. - * - * @return void - */ - function testMatchWithNamedParametersAndPassedArgs() { - Router::connectNamed(true); - - $route = new CakeRoute('/:controller/:action/*', array('plugin' => null)); - $result = $route->match(array('controller' => 'posts', 'action' => 'index', 'plugin' => null, 'page' => 1)); - $this->assertEqual($result, '/posts/index/page:1'); - - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5)); - $this->assertEqual($result, '/posts/view/5'); - - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title')); - $this->assertEqual($result, '/posts/view/5/page:1/limit:20/order:title'); - - - $route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2)); - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 1)); - $this->assertFalse($result); - - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 2, 'something')); - $this->assertEqual($result, '/test2/something'); - - $result = $route->match(array('controller' => 'pages', 'action' => 'display', 5, 'something')); - $this->assertFalse($result); - } - -/** - * test that match with patterns works. - * - * @return void - */ - function testMatchWithPatterns() { - $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null), array('id' => '[0-9]+')); - $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 'foo')); - $this->assertFalse($result); - - $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '9')); - $this->assertEqual($result, '/posts/view/9'); - - $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '922')); - $this->assertEqual($result, '/posts/view/922'); - - $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 'a99')); - $this->assertFalse($result); - } - -/** - * test persistParams ability to persist parameters from $params and remove params. - * - * @return void - */ - function testPersistParams() { - $route = new CakeRoute( - '/:lang/:color/blog/:action', - array('controller' => 'posts'), - array('persist' => array('lang', 'color')) - ); - $url = array('controller' => 'posts', 'action' => 'index'); - $params = array('lang' => 'en', 'color' => 'blue'); - $result = $route->persistParams($url, $params); - $this->assertEqual($result['lang'], 'en'); - $this->assertEqual($result['color'], 'blue'); - - $url = array('controller' => 'posts', 'action' => 'index', 'color' => 'red'); - $params = array('lang' => 'en', 'color' => 'blue'); - $result = $route->persistParams($url, $params); - $this->assertEqual($result['lang'], 'en'); - $this->assertEqual($result['color'], 'red'); - } - -/** - * test the parse method of CakeRoute. - * - * @return void - */ - function testParse() { - extract(Router::getNamedExpressions()); - $route = new CakeRoute('/:controller/:action/:id', array('controller' => 'testing4', 'id' => null), array('id' => $ID)); - $route->compile(); - $result = $route->parse('/posts/view/1'); - $this->assertEqual($result['controller'], 'posts'); - $this->assertEqual($result['action'], 'view'); - $this->assertEqual($result['id'], '1'); - - $route = new Cakeroute( - '/admin/:controller', - array('prefix' => 'admin', 'admin' => 1, 'action' => 'index') - ); - $route->compile(); - $result = $route->parse('/admin/'); - $this->assertFalse($result); - - $result = $route->parse('/admin/posts'); - $this->assertEqual($result['controller'], 'posts'); - $this->assertEqual($result['action'], 'index'); - } -} - -/** - * test case for PluginShortRoute - * - * @package cake.tests.libs - */ -class PluginShortRouteTestCase extends CakeTestCase { -/** - * startTest method - * - * @access public - * @return void - */ - function startTest() { - $this->_routing = Configure::read('Routing'); - Configure::write('Routing', array('admin' => null, 'prefixes' => array())); - Router::reload(); - } - -/** - * end the test and reset the environment - * - * @return void - **/ - function endTest() { - Configure::write('Routing', $this->_routing); - } - -/** - * test the parsing of routes. - * - * @return void - */ - function testParsing() { - $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar')); - - $result = $route->parse('/foo'); - $this->assertEqual($result['plugin'], 'foo'); - $this->assertEqual($result['controller'], 'foo'); - $this->assertEqual($result['action'], 'index'); - - $result = $route->parse('/wrong'); - $this->assertFalse($result, 'Wrong plugin name matched %s'); - } - -/** - * test the reverse routing of the plugin shortcut urls. - * - * @return void - */ - function testMatch() { - $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar')); - - $result = $route->match(array('plugin' => 'foo', 'controller' => 'posts', 'action' => 'index')); - $this->assertFalse($result, 'plugin controller mismatch was converted. %s'); - - $result = $route->match(array('plugin' => 'foo', 'controller' => 'foo', 'action' => 'index')); - $this->assertEqual($result, '/foo'); - } -} ?> \ No newline at end of file