diff --git a/tests/Symfony/Tests/Components/Routing/CompiledRouteTest.php b/tests/Symfony/Tests/Components/Routing/CompiledRouteTest.php new file mode 100644 index 000000000000..23148d43de94 --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/CompiledRouteTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing; + +use Symfony\Components\Routing\CompiledRoute; +use Symfony\Components\Routing\Route; + +class CompiledRouteTest extends \PHPUnit_Framework_TestCase +{ + public function testAccessors() + { + $route = new Route('/:foo', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar')); + + $compiled = new CompiledRoute($route, 'prefix', 'regex', array('tokens'), array('variables')); + $this->assertEquals($route, $compiled->getRoute(), '__construct() takes a route as its first argument'); + $this->assertEquals('prefix', $compiled->getStaticPrefix(), '__construct() takes a static prefix as its second argument'); + $this->assertEquals('regex', $compiled->getRegex(), '__construct() takes a regexp as its third argument'); + $this->assertEquals(array('tokens'), $compiled->getTokens(), '__construct() takes an array of tokens as its fourth argument'); + $this->assertEquals(array('variables'), $compiled->getVariables(), '__construct() takes an array of variables as its fith argument'); + } + + public function testgetPatterngetDefaultsgetOptionsgetRequirements() + { + $route = new Route('/:foo', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar')); + + $compiled = new CompiledRoute($route, 'prefix', 'regex', array('tokens'), array('variables')); + $this->assertEquals('/:foo', $compiled->getPattern(), '->getPattern() returns the route pattern'); + $this->assertEquals(array('foo' => 'bar'), $compiled->getDefaults(), '->getDefaults() returns the route defaults'); + $this->assertEquals(array('foo' => '\d+'), $compiled->getRequirements(), '->getRequirements() returns the route requirements'); + $this->assertEquals(array_merge(array( + 'variable_prefixes' => array(':'), + 'segment_separators' => array('/', '.'), + 'variable_regex' => '[\w\d_]+', + 'text_regex' => '.+?', + 'compiler_class' => 'Symfony\\Components\\Routing\\RouteCompiler', + ), array('foo' => 'bar')), $compiled->getOptions(), '->getOptions() returns the route options'); + } +} diff --git a/tests/Symfony/Tests/Components/Routing/FileResourceTest.php b/tests/Symfony/Tests/Components/Routing/FileResourceTest.php new file mode 100644 index 000000000000..82e1d5a267f5 --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/FileResourceTest.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing; + +use Symfony\Components\Routing\FileResource; + +class FileResourceTest extends \PHPUnit_Framework_TestCase +{ + public function testGetResource() + { + $file = sys_get_temp_dir().'/tmp.xml'; + touch($file); + $resource = new FileResource($file); + $this->assertEquals($file, $resource->getResource(), '->getResource() returns the path to the resource'); + unlink($file); + } + + public function testIsUptodate() + { + $file = sys_get_temp_dir().'/tmp.xml'; + touch($file); + $resource = new FileResource($file); + $this->assertTrue($resource->isUptodate(time() + 10), '->isUptodate() returns true if the resource has not changed'); + $this->assertTrue(!$resource->isUptodate(time() - 86400), '->isUptodate() returns false if the resource has been updated'); + + $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); + $this->assertTrue(!$resource->isUptodate(time()), '->isUptodate() returns false if the resource does not exist'); + } +} diff --git a/tests/Symfony/Tests/Components/Routing/Matcher/UrlMatcherTest.php b/tests/Symfony/Tests/Components/Routing/Matcher/UrlMatcherTest.php new file mode 100644 index 000000000000..8508ee943237 --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/Matcher/UrlMatcherTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing\Matcher; + +use Symfony\Components\Routing\Matcher\UrlMatcher; +use Symfony\Components\Routing\RouteCollection; +use Symfony\Components\Routing\Route; + +class UrlMatcherTest extends \PHPUnit_Framework_TestCase +{ + public function testNormalizeUrl() + { + $collection = new RouteCollection(); + $collection->addRoute('foo', new Route('/:foo')); + + $matcher = new UrlMatcherForTests($collection, array(), array()); + + $this->assertEquals('/', $matcher->normalizeUrl(''), '->normalizeUrl() adds a / at the beginning of the URL if needed'); + $this->assertEquals('/foo', $matcher->normalizeUrl('foo'), '->normalizeUrl() adds a / at the beginning of the URL if needed'); + $this->assertEquals('/foo', $matcher->normalizeUrl('/foo?foo=bar'), '->normalizeUrl() removes the query string'); + $this->assertEquals('/foo/bar', $matcher->normalizeUrl('/foo//bar'), '->normalizeUrl() removes duplicated /'); + } +} + +class UrlMatcherForTests extends UrlMatcher +{ + public function normalizeUrl($url) + { + return parent::normalizeUrl($url); + } +} diff --git a/tests/Symfony/Tests/Components/Routing/RouteCollectionTest.php b/tests/Symfony/Tests/Components/Routing/RouteCollectionTest.php new file mode 100644 index 000000000000..77e56c45d20b --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/RouteCollectionTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing; + +use Symfony\Components\Routing\RouteCollection; +use Symfony\Components\Routing\Route; +use Symfony\Components\Routing\FileResource; + +class RouteCollectionTest extends \PHPUnit_Framework_TestCase +{ + public function testRoute() + { + $collection = new RouteCollection(); + $route = new Route('/foo'); + $collection->addRoute('foo', $route); + $this->assertEquals(array('foo' => $route), $collection->getRoutes(), '->addRoute() adds a route'); + $this->assertEquals($route, $collection->getRoute('foo'), '->getRoute() returns a route by name'); + $this->assertNull($collection->getRoute('bar'), '->getRoute() returns null if a route does not exist'); + } + + public function testAddCollection() + { + $collection = new RouteCollection(); + $collection->addRoute('foo', $foo = new Route('/foo')); + $collection1 = new RouteCollection(); + $collection1->addRoute('foo', $foo1 = new Route('/foo1')); + $collection1->addRoute('bar', $bar1 = new Route('/bar1')); + $collection->addCollection($collection1); + $this->assertEquals(array('foo' => $foo1, 'bar' => $bar1), $collection->getRoutes(), '->addCollection() adds routes from another collection'); + + $collection = new RouteCollection(); + $collection->addRoute('foo', $foo = new Route('/foo')); + $collection1 = new RouteCollection(); + $collection1->addRoute('foo', $foo1 = new Route('/foo1')); + $collection->addCollection($collection1, '/foo'); + $this->assertEquals('/foo/foo1', $collection->getRoute('foo')->getPattern(), '->addCollection() can add a prefix to all merged routes'); + + $collection = new RouteCollection(); + $collection->addResource($foo = new FileResource('foo')); + $collection1 = new RouteCollection(); + $collection1->addResource($foo1 = new FileResource('foo1')); + $collection->addCollection($collection1); + $this->assertEquals(array($foo, $foo1), $collection->getResources(), '->addCollection() merges resources'); + } + + public function testAddPrefix() + { + $collection = new RouteCollection(); + $collection->addRoute('foo', $foo = new Route('/foo')); + $collection->addRoute('bar', $bar = new Route('/bar')); + $collection->addPrefix('/admin'); + $this->assertEquals('/admin/foo', $collection->getRoute('foo')->getPattern(), '->addPrefix() adds a prefix to all routes'); + $this->assertEquals('/admin/bar', $collection->getRoute('bar')->getPattern(), '->addPrefix() adds a prefix to all routes'); + } + + public function testResource() + { + $collection = new RouteCollection(); + $collection->addResource($foo = new FileResource('foo')); + $this->assertEquals(array($foo), $collection->getResources(), '->addResources() adds a resource'); + } +} diff --git a/tests/Symfony/Tests/Components/Routing/RouteCompiler.php b/tests/Symfony/Tests/Components/Routing/RouteCompiler.php new file mode 100644 index 000000000000..f7a5077e755b --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/RouteCompiler.php @@ -0,0 +1,44 @@ +options['variable_regex'].')#', $buffer, $match)) { + // a labelled variable + $this->tokens[] = array('label', $currentSeparator, $match[0], $match[1]); + + $currentSeparator = ''; + $buffer = substr($buffer, strlen($match[0])); + $afterASeparator = false; + } else { + return false; + } + } + + protected function compileForLabel($separator, $name, $variable) + { + if (null === $requirement = $this->route->getRequirement($variable)) { + $requirement = $this->options['variable_content_regex']; + } + + $this->segments[] = preg_quote($separator, '#').$variable.$separator.'(?P<'.$variable.'>'.$requirement.')'; + $this->variables[$variable] = $name; + + if (!$this->route->getDefault($variable)) { + $this->firstOptional = count($this->segments); + } + } + + protected function generateForLabel($optional, $tparams, $separator, $name, $variable) + { + if (!empty($tparams[$variable]) && (!$optional || !isset($this->defaults[$variable]) || $tparams[$variable] != $this->defaults[$variable])) { + return $variable.'/'.urlencode($tparams[$variable]); + } + } +} diff --git a/tests/Symfony/Tests/Components/Routing/RouteCompilerTest.php b/tests/Symfony/Tests/Components/Routing/RouteCompilerTest.php new file mode 100644 index 000000000000..8a6e2de965d6 --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/RouteCompilerTest.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing; + +use Symfony\Components\Routing\Route; + +require __DIR__.'/RouteCompiler.php'; + +class RouteCompilerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideCompileData + */ + public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens) + { + $r = new \ReflectionClass('Symfony\\Components\\Routing\\Route'); + $route = $r->newInstanceArgs($arguments); + + $compiled = $route->compile(); + $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)'); + $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)'); + $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)'); + $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)'); + } + + public function provideCompileData() + { + return array( + array( + 'Static route', + array('/foo'), + '/foo', '#^/foo$#x', array(), array( + array('text', '/', 'foo', null), + )), + + array( + 'Route with a variable', + array('/foo/:bar'), + '/foo', '#^/foo/(?P[^/\.]+?)$#x', array('bar' => ':bar'), array( + array('variable', '/', ':bar', 'bar'), + array('text', '/', 'foo', null), + )), + + array( + 'Route with a variable that has a default value', + array('/foo/:bar', array('bar' => 'bar')), + '/foo', '#^/foo(?:/(?P[^/\.]+?))?$#x', array('bar' => ':bar'), array( + array('variable', '/', ':bar', 'bar'), + array('text', '/', 'foo', null), + )), + + array( + 'Route with several variables', + array('/foo/:bar/:foobar'), + '/foo', '#^/foo/(?P[^/\.]+?)/(?P[^/\.]+?)$#x', array('bar' => ':bar', 'foobar' => ':foobar'), array( + array('variable', '/', ':foobar', 'foobar'), + array('variable', '/', ':bar', 'bar'), + array('text', '/', 'foo', null), + )), + + array( + 'Route with several variables that have default values', + array('/foo/:bar/:foobar', array('bar' => 'bar', 'foobar' => 'foobar')), + '/foo', '#^/foo(?:/(?P[^/\.]+?) (?:/(?P[^/\.]+?) )?)?$#x', array('bar' => ':bar', 'foobar' => ':foobar'), array( + array('variable', '/', ':foobar', 'foobar'), + array('variable', '/', ':bar', 'bar'), + array('text', '/', 'foo', null), + )), + + array( + 'Route with several variables but some of them have no default values', + array('/foo/:bar/:foobar', array('bar' => 'bar')), + '/foo', '#^/foo/(?P[^/\.]+?)/(?P[^/\.]+?)$#x', array('bar' => ':bar', 'foobar' => ':foobar'), array( + array('variable', '/', ':foobar', 'foobar'), + array('variable', '/', ':bar', 'bar'), + array('text', '/', 'foo', null), + )), + + array( + 'Route with a custom token', + array('/=foo', array(), array(), array('compiler_class' => 'Symfony\\Tests\\Components\\Routing\\RouteCompiler')), + '', '#^/foo/(?P[^/\.]+?)$#x', array('foo' => '=foo'), array( + array('label', '/', '=foo', 'foo'), + )), + ); + } +} diff --git a/tests/Symfony/Tests/Components/Routing/RouteTest.php b/tests/Symfony/Tests/Components/Routing/RouteTest.php new file mode 100644 index 000000000000..88cb66613542 --- /dev/null +++ b/tests/Symfony/Tests/Components/Routing/RouteTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Components\Routing; + +use Symfony\Components\Routing\Route; + +class RouteTest extends \PHPUnit_Framework_TestCase +{ + public function testConstructor() + { + $route = new Route('/:foo', array('foo' => 'bar'), array('foo' => '\d+'), array('foo' => 'bar')); + $this->assertEquals('/:foo', $route->getPattern(), '__construct() takes a pattern as its first argument'); + $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '__construct() takes defaults as its second argument'); + $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '__construct() takes requirements as its third argument'); + $this->assertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument'); + } + + public function testPattern() + { + $route = new Route('/:foo'); + $route->setPattern('/:bar'); + $this->assertEquals('/:bar', $route->getPattern(), '->setPattern() sets the pattern'); + $route->setPattern(''); + $this->assertEquals('/', $route->getPattern(), '->setPattern() adds a / at the beginning of the pattern if needed'); + $route->setPattern('bar'); + $this->assertEquals('/bar', $route->getPattern(), '->setPattern() adds a / at the beginning of the pattern if needed'); + $this->assertEquals($route, $route->setPattern(''), '->setPattern() implements a fluent interface'); + } + + public function testOptions() + { + $route = new Route('/:foo'); + $route->setOptions(array('foo' => 'bar')); + $this->assertEquals(array_merge(array('variable_prefixes' => array(':'), + 'segment_separators' => array('/', '.'), + 'variable_regex' => '[\w\d_]+', + 'text_regex' => '.+?', + 'compiler_class' => 'Symfony\\Components\\Routing\\RouteCompiler', + ), array('foo' => 'bar')), $route->getOptions(), '->setOptions() sets the options'); + $this->assertEquals($route, $route->setOptions(array()), '->setOptions() implements a fluent interface'); + } + + public function testDefaults() + { + $route = new Route('/:foo'); + $route->setDefaults(array('foo' => 'bar')); + $this->assertEquals(array('foo' => 'bar'), $route->getDefaults(), '->setDefaults() sets the defaults'); + $this->assertEquals($route, $route->setDefaults(array()), '->setDefaults() implements a fluent interface'); + } + + public function testRequirements() + { + $route = new Route('/:foo'); + $route->setRequirements(array('foo' => '\d+')); + $this->assertEquals(array('foo' => '\d+'), $route->getRequirements(), '->setRequirements() sets the requirements'); + $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() returns a requirement'); + $this->assertNull($route->getRequirement('bar'), '->getRequirement() returns null if a requirement is not defined'); + $route->setRequirements(array('foo' => '^\d+$')); + $this->assertEquals('\d+', $route->getRequirement('foo'), '->getRequirement() removes ^ and $ from the pattern'); + $this->assertEquals($route, $route->setRequirements(array()), '->setRequirements() implements a fluent interface'); + } + + public function testCompile() + { + $route = new Route('/:foo'); + $this->assertEquals('Symfony\\Components\\Routing\\CompiledRoute', get_class($compiled = $route->compile()), '->compile() returns a compiled route'); + $this->assertEquals($compiled, $route->compile(), '->compile() only compiled the route once'); + } +}