diff --git a/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php b/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php index 896f4f2704..a4254456c3 100644 --- a/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php +++ b/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php @@ -52,7 +52,7 @@ class ProxyCacheWarmer implements CacheWarmerInterface // we need the directory no matter the proxy cache generation strategy if (!is_dir($proxyCacheDir = $em->getConfiguration()->getProxyDir())) { if (false === @mkdir($proxyCacheDir, 0777, true)) { - throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory "%s".', dirname($proxyCacheDir))); + throw new \RuntimeException(sprintf('Unable to create the Doctrine Proxy directory "%s".', $proxyCacheDir)); } } elseif (!is_writable($proxyCacheDir)) { throw new \RuntimeException(sprintf('The Doctrine Proxy directory "%s" is not writeable for the current system user.', $proxyCacheDir)); diff --git a/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php b/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php index fa3395558f..3ccdfa74fb 100644 --- a/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php @@ -21,7 +21,7 @@ use Symfony\Component\HttpFoundation\Request; */ class WebProcessor extends BaseWebProcessor { - public function __construct(RequestInterface $request) + public function __construct(Request $request) { parent::__construct($request->server->all()); } diff --git a/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php b/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php index 6ecbafde14..078115c8b6 100644 --- a/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php +++ b/src/Symfony/Bundle/DoctrineBundle/DoctrineBundle.php @@ -42,14 +42,38 @@ class DoctrineBundle extends Bundle if ($this->container->hasParameter('doctrine.orm.proxy_namespace')) { $namespace = $this->container->getParameter('doctrine.orm.proxy_namespace'); $dir = $this->container->getParameter('doctrine.orm.proxy_dir'); + $container = $this->container; - spl_autoload_register(function($class) use ($namespace, $dir) { + spl_autoload_register(function($class) use ($namespace, $dir, $container) { if (0 === strpos($class, $namespace)) { $className = substr($class, strlen($namespace) +1); $file = $dir.DIRECTORY_SEPARATOR.$className.'.php'; - if (!is_file($file)) { - throw new \RuntimeException(sprintf('The proxy file "%s" does not exist. If you still have objects serialized in the session, you need to clear the session manually.', $file)); + if (!is_file($file) && $this->container->getParameter('kernel.debug')) { + $originalClassName = substr($className, 0, -5); + $registry = $container->get('doctrine'); + + // Tries to auto-generate the proxy file + foreach ($registry->getEntityManagers() as $em) { + + if ($em->getConfiguration()->getAutoGenerateProxyClasses()) { + $classes = $em->getMetadataFactory()->getAllMetadata(); + + foreach ($classes as $class) { + $name = str_replace('\\', '', $class->name); + + if ($name == $originalClassName) { + $em->getProxyFactory()->generateProxyClasses(array($class)); + } + } + } + } + + clearstatcache($file); + + if (!is_file($file)) { + throw new \RuntimeException(sprintf('The proxy file "%s" does not exist. If you still have objects serialized in the session, you need to clear the session manually.', $file)); + } } require $file; diff --git a/src/Symfony/Bundle/SwiftmailerBundle/composer.json b/src/Symfony/Bundle/SwiftmailerBundle/composer.json index e4f1fcc9ef..2d9fc62899 100644 --- a/src/Symfony/Bundle/SwiftmailerBundle/composer.json +++ b/src/Symfony/Bundle/SwiftmailerBundle/composer.json @@ -17,6 +17,7 @@ } ], "require": { - "php": ">=5.3.2" + "php": ">=5.3.2", + "swiftmailer/swiftmailer": ">=4.1.2" } } diff --git a/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php b/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php index 1689212b77..8cc6747fb2 100644 --- a/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php +++ b/src/Symfony/Component/ClassLoader/DebugUniversalClassLoader.php @@ -55,7 +55,7 @@ class DebugUniversalClassLoader extends UniversalClassLoader if ($file = $this->findFile($class)) { require $file; - if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class))) { + if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); } } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index fa3105539e..e8521ba59e 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -615,7 +615,7 @@ abstract class Kernel implements KernelInterface foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { if (!is_dir($dir)) { if (false === @mkdir($dir, 0777, true)) { - throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, dirname($dir))); + throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); } } elseif (!is_writable($dir)) { throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir)); diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index cf98e403e5..c8231ede08 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -91,7 +91,7 @@ EOF; if ($optimizable) { for ($j = $i; $j < $keysCount; $j++) { if ($keys[$j] === null) { - continue; + continue; } $testRoute = $routeIterator->offsetGet($keys[$j]); diff --git a/src/Symfony/Component/Routing/RouteCollection.php b/src/Symfony/Component/Routing/RouteCollection.php index 6aeb06f605..47b7511734 100644 --- a/src/Symfony/Component/Routing/RouteCollection.php +++ b/src/Symfony/Component/Routing/RouteCollection.php @@ -16,6 +16,9 @@ use Symfony\Component\Config\Resource\ResourceInterface; /** * A RouteCollection represents a set of Route instances. * + * When adding a route, it overrides existing routes with the + * same name defined in theinstance or its children and parents. + * * @author Fabien Potencier * * @api @@ -25,6 +28,7 @@ class RouteCollection implements \IteratorAggregate private $routes; private $resources; private $prefix; + private $parent; /** * Constructor. @@ -38,6 +42,31 @@ class RouteCollection implements \IteratorAggregate $this->prefix = ''; } + /** + * Gets the parent RouteCollection. + * + * @return RouteCollection The parent RouteCollection + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the parent RouteCollection. + * + * @param RouteCollection $parent The parent RouteCollection + */ + public function setParent(RouteCollection $parent) + { + $this->parent = $parent; + } + + /** + * Gets the current RouteCollection as an Iterator. + * + * @return \ArrayIterator An \ArrayIterator interface + */ public function getIterator() { return new \ArrayIterator($this->routes); @@ -59,6 +88,15 @@ class RouteCollection implements \IteratorAggregate throw new \InvalidArgumentException(sprintf('Name "%s" contains non valid characters for a route name.', $name)); } + $parent = $this; + while ($parent->getParent()) { + $parent = $parent->getParent(); + } + + if ($parent) { + $parent->remove($name); + } + $this->routes[$name] = $route; } @@ -106,6 +144,24 @@ class RouteCollection implements \IteratorAggregate } } + /** + * Removes a route by name. + * + * @param string $name The route name + */ + public function remove($name) + { + if (isset($this->routes[$name])) { + unset($this->routes[$name]); + } + + foreach ($this->routes as $routes) { + if ($routes instanceof RouteCollection) { + $routes->remove($name); + } + } + } + /** * Adds a route collection to the current set of routes (at the end of the current set). * @@ -116,8 +172,14 @@ class RouteCollection implements \IteratorAggregate */ public function addCollection(RouteCollection $collection, $prefix = '') { + $collection->setParent($this); $collection->addPrefix($prefix); + // remove all routes with the same name in all existing collections + foreach (array_keys($collection->all()) as $name) { + $this->remove($name); + } + $this->routes[] = $collection; } diff --git a/tests/Symfony/Tests/Bridge/Monolog/Processor/WebProcessorTest.php b/tests/Symfony/Tests/Bridge/Monolog/Processor/WebProcessorTest.php new file mode 100644 index 0000000000..5c17f0948b --- /dev/null +++ b/tests/Symfony/Tests/Bridge/Monolog/Processor/WebProcessorTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Bridge\Monolog\Processor; + +use Monolog\Logger; +use Symfony\Bridge\Monolog\Processor\WebProcessor; +use Symfony\Component\HttpFoundation\Request; + +class WebProcessorTest extends \PHPUnit_Framework_TestCase +{ + public function testUsesRequestServerData() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + ); + + $request = new Request(); + $request->server->replace($server); + + $processor = new WebProcessor($request); + $record = $processor($this->getRecord()); + + $this->assertEquals($server['REQUEST_URI'], $record['extra']['url']); + $this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']); + $this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']); + } + + /** + * @return array Record + */ + protected function getRecord($level = Logger::WARNING, $message = 'test') + { + return array( + 'message' => $message, + 'context' => array(), + 'level' => $level, + 'level_name' => Logger::getLevelName($level), + 'channel' => 'test', + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + } +} diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php index bfd8f8e0f0..7932944a34 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher1.php @@ -108,30 +108,35 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher if (0 === strpos($pathinfo, '/a')) { if (0 === strpos($pathinfo, '/a/b\'b')) { - // foo - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; - return $matches; - } - - // bar - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'bar'; - return $matches; - } - // foo1 - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { $matches['_route'] = 'foo1'; return $matches; } // bar1 - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { $matches['_route'] = 'bar1'; return $matches; } + // foo2 + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + $matches['_route'] = 'foo2'; + return $matches; + } + + // bar2 + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + $matches['_route'] = 'bar2'; + return $matches; + } + + } + + // overriden + if ($pathinfo === '/a/overriden2') { + return array('_route' => 'overriden'); } // ababa @@ -139,23 +144,23 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher return array('_route' => 'ababa'); } - // foo + // foo4 if (preg_match('#^/aba/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; + $matches['_route'] = 'foo4'; return $matches; } } - // foo + // foo3 if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; + $matches['_route'] = 'foo3'; return $matches; } - // bar + // bar3 if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'bar'; + $matches['_route'] = 'bar3'; return $matches; } diff --git a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php index e8ff94dc97..d0f1e31381 100644 --- a/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php +++ b/tests/Symfony/Tests/Component/Routing/Fixtures/dumper/url_matcher2.php @@ -120,30 +120,35 @@ class ProjectUrlMatcher extends Symfony\Tests\Component\Routing\Fixtures\Redirec if (0 === strpos($pathinfo, '/a')) { if (0 === strpos($pathinfo, '/a/b\'b')) { - // foo - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; - return $matches; - } - - // bar - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'bar'; - return $matches; - } - // foo1 - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { $matches['_route'] = 'foo1'; return $matches; } // bar1 - if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { $matches['_route'] = 'bar1'; return $matches; } + // foo2 + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + $matches['_route'] = 'foo2'; + return $matches; + } + + // bar2 + if (preg_match('#^/a/b\'b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { + $matches['_route'] = 'bar2'; + return $matches; + } + + } + + // overriden + if ($pathinfo === '/a/overriden2') { + return array('_route' => 'overriden'); } // ababa @@ -151,23 +156,23 @@ class ProjectUrlMatcher extends Symfony\Tests\Component\Routing\Fixtures\Redirec return array('_route' => 'ababa'); } - // foo + // foo4 if (preg_match('#^/aba/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; + $matches['_route'] = 'foo4'; return $matches; } } - // foo + // foo3 if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'foo'; + $matches['_route'] = 'foo3'; return $matches; } - // bar + // bar3 if (preg_match('#^/(?P<_locale>[^/]+?)/b/(?P[^/]+?)$#xs', $pathinfo, $matches)) { - $matches['_route'] = 'bar'; + $matches['_route'] = 'bar3'; return $matches; } diff --git a/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php b/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php index 08053caf6c..ec8b6688d6 100644 --- a/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/tests/Symfony/Tests/Component/Routing/Matcher/Dumper/PhpMatcherDumperTest.php @@ -19,8 +19,52 @@ use Symfony\Component\Routing\RequestContext; class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase { public function testDump() + { + $dumper = new PhpMatcherDumper($this->getRouteCollection(), new RequestContext()); + + $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.'); + + $collection = $this->getRouteCollection(); + + // force HTTPS redirection + $collection->add('secure', new Route( + '/secure', + array(), + array('_scheme' => 'https') + )); + + // force HTTP redirection + $collection->add('nonsecure', new Route( + '/nonsecure', + array(), + array('_scheme' => 'http') + )); + + $dumper = new PhpMatcherDumper($collection, new RequestContext()); + + $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher2.php', $dumper->dump(array('base_class' => 'Symfony\Tests\Component\Routing\Fixtures\RedirectableUrlMatcher')), '->dump() dumps basic routes to the correct PHP file.'); + } + + /** + * @expectedException \LogicException + */ + public function testDumpWhenSchemeIsUsedWithoutAProperDumper() { $collection = new RouteCollection(); + $collection->add('secure', new Route( + '/secure', + array(), + array('_scheme' => 'https') + )); + $dumper = new PhpMatcherDumper($collection, new RequestContext()); + $dumper->dump(); + } + + protected function getRouteCollection() + { + $collection = new RouteCollection(); + + $collection->add('overriden', new Route('/overriden')); // defaults and requirements $collection->add('foo', new Route( @@ -82,20 +126,22 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase // prefixes $collection1 = new RouteCollection(); - $collection1->add('foo', new Route('/{foo}')); - $collection1->add('bar', new Route('/{bar}')); + $collection1->add('overriden', new Route('/overriden1')); + $collection1->add('foo1', new Route('/{foo}')); + $collection1->add('bar1', new Route('/{bar}')); $collection2 = new RouteCollection(); $collection2->addCollection($collection1, '/b\'b'); + $collection2->add('overriden', new Route('/overriden2')); $collection1 = new RouteCollection(); - $collection1->add('foo1', new Route('/{foo1}')); - $collection1->add('bar1', new Route('/{bar1}')); + $collection1->add('foo2', new Route('/{foo1}')); + $collection1->add('bar2', new Route('/{bar1}')); $collection2->addCollection($collection1, '/b\'b'); $collection->addCollection($collection2, '/a'); // "dynamic" prefix $collection1 = new RouteCollection(); - $collection1->add('foo', new Route('/{foo}')); - $collection1->add('bar', new Route('/{bar}')); + $collection1->add('foo3', new Route('/{foo}')); + $collection1->add('bar3', new Route('/{bar}')); $collection2 = new RouteCollection(); $collection2->addCollection($collection1, '/b'); $collection->addCollection($collection2, '/{_locale}'); @@ -104,42 +150,9 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase // some more prefixes $collection1 = new RouteCollection(); - $collection1->add('foo', new Route('/{foo}')); + $collection1->add('foo4', new Route('/{foo}')); $collection->addCollection($collection1, '/aba'); - $dumper = new PhpMatcherDumper($collection, new RequestContext()); - - $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.'); - - // force HTTPS redirection - $collection->add('secure', new Route( - '/secure', - array(), - array('_scheme' => 'https') - )); - - // force HTTP redirection - $collection->add('nonsecure', new Route( - '/nonsecure', - array(), - array('_scheme' => 'http') - )); - - $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher2.php', $dumper->dump(array('base_class' => 'Symfony\Tests\Component\Routing\Fixtures\RedirectableUrlMatcher')), '->dump() dumps basic routes to the correct PHP file.'); - } - - /** - * @expectedException \LogicException - */ - public function testDumpWhenSchemeIsUsedWithoutAProperDumper() - { - $collection = new RouteCollection(); - $collection->add('secure', new Route( - '/secure', - array(), - array('_scheme' => 'https') - )); - $dumper = new PhpMatcherDumper($collection, new RequestContext()); - $dumper->dump(); + return $collection; } } diff --git a/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php b/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php index 1f735ca558..5d3349d453 100644 --- a/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php +++ b/tests/Symfony/Tests/Component/Routing/Matcher/UrlMatcherTest.php @@ -170,6 +170,23 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('_route' => 'foo', 'foo' => "\n"), $matcher->match('/'.urlencode("\n").'/bar'), 'linefeed character is matched'); } + public function testMatchOverridenRoute() + { + $collection = new RouteCollection(); + $collection->add('foo', new Route('/foo')); + + $collection1 = new RouteCollection(); + $collection1->add('foo', new Route('/foo1')); + + $collection->addCollection($collection1); + + $matcher = new UrlMatcher($collection, new RequestContext(), array()); + + $this->assertEquals(array('_route' => 'foo'), $matcher->match('/foo1')); + $this->setExpectedException('Symfony\Component\Routing\Exception\ResourceNotFoundException'); + $this->assertEquals(array(), $matcher->match('/foo')); + } + public function testMatchRegression() { $coll = new RouteCollection(); @@ -188,4 +205,4 @@ class UrlMatcherTest extends \PHPUnit_Framework_TestCase } catch (ResourceNotFoundException $e) { } } -} \ No newline at end of file +} diff --git a/tests/Symfony/Tests/Component/Routing/RouteCollectionTest.php b/tests/Symfony/Tests/Component/Routing/RouteCollectionTest.php index 4ddd128c69..f0569065c1 100644 --- a/tests/Symfony/Tests/Component/Routing/RouteCollectionTest.php +++ b/tests/Symfony/Tests/Component/Routing/RouteCollectionTest.php @@ -28,7 +28,6 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase } /** - * @covers Symfony\Component\Routing\RouteCollection::add * @expectedException InvalidArgumentException */ public function testAddInvalidRoute() @@ -38,6 +37,58 @@ class RouteCollectionTest extends \PHPUnit_Framework_TestCase $collection->add('f o o', $route); } + public function testOverridenRoute() + { + $collection = new RouteCollection(); + $collection->add('foo', new Route('/foo')); + $collection->add('foo', new Route('/foo1')); + + $this->assertEquals('/foo1', $collection->get('foo')->getPattern()); + } + + public function testDeepOverridenRoute() + { + $collection = new RouteCollection(); + $collection->add('foo', new Route('/foo')); + + $collection1 = new RouteCollection(); + $collection1->add('foo', new Route('/foo1')); + + $collection2 = new RouteCollection(); + $collection2->add('foo', new Route('/foo2')); + + $collection1->addCollection($collection2); + $collection->addCollection($collection1); + + $this->assertEquals('/foo2', $collection1->get('foo')->getPattern()); + $this->assertEquals('/foo2', $collection->get('foo')->getPattern()); + } + + public function testIteratorWithOverridenRoutes() + { + $collection = new RouteCollection(); + $collection->add('foo', new Route('/foo')); + + $collection1 = new RouteCollection(); + $collection->addCollection($collection1); + $collection1->add('foo', new Route('/foo1')); + + $this->assertEquals('/foo1', $this->getFirstNamedRoute($collection, 'foo')->getPattern()); + } + + protected function getFirstNamedRoute(RouteCollection $routeCollection, $name) + { + foreach ($routeCollection as $key => $route) { + if ($route instanceof RouteCollection) { + return $this->getFirstNamedRoute($route, $name); + } + + if ($name === $key) { + return $route; + } + } + } + public function testAddCollection() { $collection = new RouteCollection(); diff --git a/tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php b/tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php index a0de14568e..f9b8a74835 100644 --- a/tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php +++ b/tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php @@ -28,7 +28,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException Exception + * @expectedException \RuntimeException */ public function testLoadInvalidResource() { @@ -37,7 +37,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException Exception + * @expectedException \RuntimeException */ public function testLoadResourceDoesNotValidate() {