From e623c39a1939014a59631cd537151efb1031dd1b Mon Sep 17 00:00:00 2001 From: "lupo.lupov" Date: Sun, 31 Jan 2016 15:15:34 +0200 Subject: [PATCH 1/6] Configurable FastRoute Caching --- Slim/Container.php | 2 ++ Slim/Router.php | 57 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Slim/Container.php b/Slim/Container.php index d8fbbcb1f..5d975ba9d 100644 --- a/Slim/Container.php +++ b/Slim/Container.php @@ -58,6 +58,8 @@ class Container extends PimpleContainer implements ContainerInterface 'determineRouteBeforeAppMiddleware' => false, 'displayErrorDetails' => false, 'addContentLengthHeader' => true, + 'routerCacheDisabled' => true, + 'routerCacheFile' => '', ]; /** diff --git a/Slim/Router.php b/Slim/Router.php index 5adcec342..5f5efeba7 100644 --- a/Slim/Router.php +++ b/Slim/Router.php @@ -44,6 +44,13 @@ class Router implements RouterInterface */ protected $basePath = ''; + /** + * Path to fast route cache file + * + * @var string + */ + protected $cacheFilePath; + /** * Routes * @@ -97,6 +104,28 @@ public function setBasePath($basePath) return $this; } + /** + * Set path to fast route cache file + * + * @param string $cacheFilePath + * + * @return self + */ + public function setCacheFilePath($cacheFilePath) + { + if (!is_string($cacheFilePath)) { + throw new InvalidArgumentException('Router cacheFilePath must be a string'); + } + + if (!is_writable(dirname($cacheFilePath))) { + throw new RuntimeException('Router cacheFilePath directory must be writable'); + } + + $this->cacheFilePath = $cacheFilePath; + + return $this; + } + /** * Add route * @@ -142,7 +171,7 @@ public function map($methods, $pattern, $handler) public function dispatch(ServerRequestInterface $request) { $uri = '/' . ltrim($request->getUri()->getPath(), '/'); - + return $this->createDispatcher()->dispatch( $request->getMethod(), $uri @@ -154,13 +183,25 @@ public function dispatch(ServerRequestInterface $request) */ protected function createDispatcher() { - return $this->dispatcher ?: \FastRoute\simpleDispatcher(function (RouteCollector $r) { - foreach ($this->getRoutes() as $route) { - $r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier()); - } - }, [ - 'routeParser' => $this->routeParser - ]); + return $this->dispatcher ?: call_user_func_array( + '\FastRoute\\' . (isset($this->cacheFilePath) ? 'cachedDispatcher' : 'simpleDispatcher'), + [ + function (RouteCollector $routeCollector) { + foreach ($this->getRoutes() as $route) { + $routeCollector->addRoute( + $route->getMethods(), + $route->getPattern(), + $route->getIdentifier() + ); + } + }, + [ + 'routeParser' => $this->routeParser, + 'cacheFile' => $this->cacheFilePath, + 'cacheDisabled' => !isset($this->cacheFilePath), + ], + ] + ); } /** From 29bbe4d1047961bf2792392af583dc9c8aa81899 Mon Sep 17 00:00:00 2001 From: "lupo.lupov" Date: Sat, 6 Feb 2016 18:20:05 +0200 Subject: [PATCH 2/6] Configurable FastRoute Caching Unit tests --- tests/ContainerTest.php | 44 ++++++++++++++++++++++++++++++++++++++++ tests/RouterTest.php | 45 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 85f47a1ef..25f144436 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -156,4 +156,48 @@ public function testMagicGetMethod() $this->container->get('settings')['httpVersion'] = '1.2'; $this->assertSame('1.2', $this->container->__get('settings')['httpVersion']); } + + public function testRouteCacheDisabledByDefault() + { + $this->assertTrue($this->container->get('settings')['routerCacheDisabled']); + } + + /** + * Get cacheFilePath protected property from Route instance + * + * @return string + */ + protected function getRouteCacheFilePath() + { + $router = $this->container['router']; + $getCacheFilePath = function ($router) { + return $router->cacheFilePath; + }; + $getCacheFilePath = \Closure::bind( + $getCacheFilePath, + null, + $this->container['router'] + ); + + return $getCacheFilePath($router); + } + + /** + * Test no cache path is set to Route when option is disabled from config + */ + public function testRouteCachePathNotSetWhenCacheDisabled() + { + $this->container->get('settings')['routerCacheDisabled'] = true; + $this->assertNull($this->getRouteCacheFilePath()); + } + + /** + * Test cache path is set to Route when cache is enabled in config + */ + public function testRouteCachePathSetWhenCacheEnabled() + { + $this->container->get('settings')['routerCacheDisabled'] = false; + $this->container->get('settings')['routerCacheFile'] = 'slim'; + $this->assertEquals('slim', $this->getRouteCacheFilePath()); + } } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 6e48dce8d..3fef0d740 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -86,7 +86,7 @@ public function testRelativePathFor() $this->router->relativePathFor('foo', ['first' => 'josh', 'last' => 'lockhart']) ); } - + public function testPathForWithNoBasePath() { $this->router->setBasePath(''); @@ -104,7 +104,7 @@ public function testPathForWithNoBasePath() $this->router->pathFor('foo', ['first' => 'josh', 'last' => 'lockhart']) ); } - + public function testPathForWithBasePath() { $methods = ['GET']; @@ -306,4 +306,45 @@ public function testPathForWithModifiedRoutePattern() $this->router->relativePathFor('foo', ['voornaam' => 'josh', 'achternaam' => 'lockhart']) ); } + + /** + * Test cacheFilePath should be a string + */ + public function testSettingInvalidCacheFilePathNotString() + { + $this->setExpectedException( + '\InvalidArgumentException', + 'Router cacheFilePath must be a string' + ); + $this->router->setCacheFilePath(['invalid']); + } + + /** + * Test if cacheFilePath is not a writable directory + */ + public function testSettingInvalidCacheFilePathNotExisting() + { + $this->setExpectedException( + '\RuntimeException', + 'Router cacheFilePath directory must be writable' + ); + + $this->router->setCacheFilePath( + dirname(__FILE__) . uniqid(microtime(true)) . '/' . uniqid(microtime(true)) + ); + } + + /** + * Test route dispatcher is created in case of route cache + */ + public function testCreateDispatcherWithRouteCache() + { + $cacheFile = dirname(__FILE__) . '/' . uniqid(microtime(true)); + $this->router->setCacheFilePath($cacheFile); + $class = new \ReflectionClass($this->router); + $method = $class->getMethod('createDispatcher'); + $method->setAccessible(true); + $this->assertInstanceOf('\FastRoute\Dispatcher', $method->invoke($this->router)); + unlink($cacheFile); + } } From 5c9c6ca06a6febeb45a5f985e176b7fd4ad32814 Mon Sep 17 00:00:00 2001 From: "lupo.lupov" Date: Sat, 6 Feb 2016 20:43:42 +0200 Subject: [PATCH 3/6] Configurable FastRoute Caching add CacheDisabled flag to Router --- Slim/Router.php | 47 +++++++++++++++++++++++++++++++---------- tests/ContainerTest.php | 46 ++++++++++++++++++++++++++-------------- tests/RouterTest.php | 37 ++++++++++++++++++++++++-------- 3 files changed, 94 insertions(+), 36 deletions(-) diff --git a/Slim/Router.php b/Slim/Router.php index 5f5efeba7..b91a033ca 100644 --- a/Slim/Router.php +++ b/Slim/Router.php @@ -44,12 +44,19 @@ class Router implements RouterInterface */ protected $basePath = ''; + /** + * Fast route cache is disabled + * + * @var bool + */ + protected $cacheDisabled = true; + /** * Path to fast route cache file * * @var string */ - protected $cacheFilePath; + protected $cacheFile; /** * Routes @@ -104,24 +111,38 @@ public function setBasePath($basePath) return $this; } + /** + * Enable/disable route cache + * + * @param bool $cacheDisabled + * + * @return self + */ + public function setCacheDisabled($cacheDisabled) + { + $this->cacheDisabled = $cacheDisabled; + + return $this; + } + /** * Set path to fast route cache file * - * @param string $cacheFilePath + * @param string $cacheFile * * @return self */ - public function setCacheFilePath($cacheFilePath) + public function setCacheFile($cacheFile) { - if (!is_string($cacheFilePath)) { - throw new InvalidArgumentException('Router cacheFilePath must be a string'); + if (!is_string($cacheFile)) { + throw new InvalidArgumentException('Router cacheFile must be a string'); } - if (!is_writable(dirname($cacheFilePath))) { - throw new RuntimeException('Router cacheFilePath directory must be writable'); + if (!is_writable(dirname($cacheFile))) { + throw new RuntimeException('Router cacheFile directory must be writable'); } - $this->cacheFilePath = $cacheFilePath; + $this->cacheFile = $cacheFile; return $this; } @@ -183,8 +204,12 @@ public function dispatch(ServerRequestInterface $request) */ protected function createDispatcher() { + if (!$this->cacheDisabled && is_null($this->cacheFile)) { + throw new RuntimeException('Router cache enabled but cacheFile not set'); + } + return $this->dispatcher ?: call_user_func_array( - '\FastRoute\\' . (isset($this->cacheFilePath) ? 'cachedDispatcher' : 'simpleDispatcher'), + '\FastRoute\\' . (!$this->cacheDisabled ? 'cachedDispatcher' : 'simpleDispatcher'), [ function (RouteCollector $routeCollector) { foreach ($this->getRoutes() as $route) { @@ -197,8 +222,8 @@ function (RouteCollector $routeCollector) { }, [ 'routeParser' => $this->routeParser, - 'cacheFile' => $this->cacheFilePath, - 'cacheDisabled' => !isset($this->cacheFilePath), + 'cacheFile' => $this->cacheFile, + 'cacheDisabled' => $this->cacheDisabled, ], ] ); diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 25f144436..7d8951a34 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -163,41 +163,55 @@ public function testRouteCacheDisabledByDefault() } /** - * Get cacheFilePath protected property from Route instance + * Get cacheDisabled protected property from Route instance * * @return string */ - protected function getRouteCacheFilePath() + protected function getRouteCacheDisabled() { $router = $this->container['router']; - $getCacheFilePath = function ($router) { - return $router->cacheFilePath; + $getCacheDisabled = function ($router) { + return $router->cacheDisabled; }; - $getCacheFilePath = \Closure::bind( - $getCacheFilePath, - null, - $this->container['router'] - ); + $getCacheDisabled = \Closure::bind($getCacheDisabled, null, $this->container['router']); + return $getCacheDisabled($router); + } - return $getCacheFilePath($router); + /** + * Get cacheFile protected property from Route instance + * + * @return string + */ + protected function getRouteCacheFile() + { + $router = $this->container['router']; + $getCacheFile = function ($router) { + return $router->cacheFile; + }; + $getCacheFile = \Closure::bind($getCacheFile, null, $this->container['router']); + return $getCacheFile($router); } /** - * Test no cache path is set to Route when option is disabled from config + * Test that cache is not enabled and no cache file is set to Router + * when option is disabled from config */ - public function testRouteCachePathNotSetWhenCacheDisabled() + public function testRouteCacheFileNotSetWhenCacheDisabled() { $this->container->get('settings')['routerCacheDisabled'] = true; - $this->assertNull($this->getRouteCacheFilePath()); + $this->assertTrue($this->getRouteCacheDisabled()); + $this->assertNull($this->getRouteCacheFile()); } /** - * Test cache path is set to Route when cache is enabled in config + * Test that cache is enabled and cache file is set to Router + * when option is enabled from config */ - public function testRouteCachePathSetWhenCacheEnabled() + public function testRouteCacheSetWhenCacheEnabled() { $this->container->get('settings')['routerCacheDisabled'] = false; $this->container->get('settings')['routerCacheFile'] = 'slim'; - $this->assertEquals('slim', $this->getRouteCacheFilePath()); + $this->assertFalse($this->getRouteCacheDisabled()); + $this->assertEquals('slim', $this->getRouteCacheFile()); } } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 3fef0d740..cdc8a793f 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -308,39 +308,58 @@ public function testPathForWithModifiedRoutePattern() } /** - * Test cacheFilePath should be a string + * Test cacheFile should be a string */ - public function testSettingInvalidCacheFilePathNotString() + public function testSettingInvalidCacheFileNotString() { $this->setExpectedException( '\InvalidArgumentException', - 'Router cacheFilePath must be a string' + 'Router cacheFile must be a string' ); - $this->router->setCacheFilePath(['invalid']); + $this->router->setCacheFile(['invalid']); } /** - * Test if cacheFilePath is not a writable directory + * Test if cacheFile is not a writable directory */ - public function testSettingInvalidCacheFilePathNotExisting() + public function testSettingInvalidCacheFileNotExisting() { $this->setExpectedException( '\RuntimeException', - 'Router cacheFilePath directory must be writable' + 'Router cacheFile directory must be writable' ); - $this->router->setCacheFilePath( + $this->router->setCacheFile( dirname(__FILE__) . uniqid(microtime(true)) . '/' . uniqid(microtime(true)) ); } + /** + * Test if cache is enabled but cache file is not set + */ + public function testCacheFileNotSetButCacheEnabled() + { + $this->setExpectedException( + '\RuntimeException', + 'Router cache enabled but cacheFile not set' + ); + + $this->router->setCacheDisabled(false); + + $class = new \ReflectionClass($this->router); + $method = $class->getMethod('createDispatcher'); + $method->setAccessible(true); + $method->invoke($this->router); + } + /** * Test route dispatcher is created in case of route cache */ public function testCreateDispatcherWithRouteCache() { $cacheFile = dirname(__FILE__) . '/' . uniqid(microtime(true)); - $this->router->setCacheFilePath($cacheFile); + $this->router->setCacheDisabled(false); + $this->router->setCacheFile($cacheFile); $class = new \ReflectionClass($this->router); $method = $class->getMethod('createDispatcher'); $method->setAccessible(true); From 7b47671378c50ae260f9bd37b15595a811945614 Mon Sep 17 00:00:00 2001 From: "lupo.lupov" Date: Sun, 21 Feb 2016 09:16:25 +0200 Subject: [PATCH 4/6] Merge remote-tracking branch 'Slim/3.x' into ConfigurableFastRouteCaching Resolve conflicts --- Slim/Container.php | 2 +- Slim/DefaultServicesProvider.php | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Slim/Container.php b/Slim/Container.php index 5d975ba9d..758a7e6a2 100644 --- a/Slim/Container.php +++ b/Slim/Container.php @@ -98,7 +98,7 @@ private function registerDefaultServices($userSettings) $this['settings'] = function () use ($userSettings, $defaultSettings) { return new Collection(array_merge($defaultSettings, $userSettings)); }; - + $defaultProvider = new DefaultServicesProvider(); $defaultProvider->register($this); } diff --git a/Slim/DefaultServicesProvider.php b/Slim/DefaultServicesProvider.php index e41831b93..983237e57 100644 --- a/Slim/DefaultServicesProvider.php +++ b/Slim/DefaultServicesProvider.php @@ -83,10 +83,20 @@ public function register($container) * This service MUST return a SHARED instance * of \Slim\Interfaces\RouterInterface. * + * @param Container $container + * * @return RouterInterface */ - $container['router'] = function () { - return new Router; + $container['router'] = function ($container) { + if (is_null($container->get('settings')['routerCacheDisabled']) + || $container->get('settings')['routerCacheDisabled'] + ) { + return new Router; + } else { + return (new Router) + ->setCacheDisabled(false) + ->setCacheFile($container->get('settings')['routerCacheFile']); + } }; } From f19cf30bca524881ad56f9dbf49d8e38f211e373 Mon Sep 17 00:00:00 2001 From: Rob Allen Date: Sun, 8 May 2016 20:13:52 +0100 Subject: [PATCH 5/6] Remove routerCacheDisabled setting We can use routerCacheFile to cover this. If routerCacheFile is false, then router caching is disabled. Updated the Router::createDispatcher() method so that it is clearer. Updated and tidied up unit tests. --- Slim/Container.php | 3 +- Slim/DefaultServicesProvider.php | 13 ++--- Slim/Router.php | 81 ++++++++++++-------------------- tests/ContainerTest.php | 55 +--------------------- tests/RouterTest.php | 52 ++++++++++++-------- 5 files changed, 70 insertions(+), 134 deletions(-) diff --git a/Slim/Container.php b/Slim/Container.php index 758a7e6a2..549dda9af 100644 --- a/Slim/Container.php +++ b/Slim/Container.php @@ -58,8 +58,7 @@ class Container extends PimpleContainer implements ContainerInterface 'determineRouteBeforeAppMiddleware' => false, 'displayErrorDetails' => false, 'addContentLengthHeader' => true, - 'routerCacheDisabled' => true, - 'routerCacheFile' => '', + 'routerCacheFile' => false, ]; /** diff --git a/Slim/DefaultServicesProvider.php b/Slim/DefaultServicesProvider.php index 983237e57..c18d87572 100644 --- a/Slim/DefaultServicesProvider.php +++ b/Slim/DefaultServicesProvider.php @@ -88,15 +88,12 @@ public function register($container) * @return RouterInterface */ $container['router'] = function ($container) { - if (is_null($container->get('settings')['routerCacheDisabled']) - || $container->get('settings')['routerCacheDisabled'] - ) { - return new Router; - } else { - return (new Router) - ->setCacheDisabled(false) - ->setCacheFile($container->get('settings')['routerCacheFile']); + $routerCacheFile = false; + if (isset($container->get('settings')['routerCacheFile'])) { + $routerCacheFile = $container->get('settings')['routerCacheFile']; } + + return (new Router)->setCacheFile($routerCacheFile); }; } diff --git a/Slim/Router.php b/Slim/Router.php index b91a033ca..b9d5d132a 100644 --- a/Slim/Router.php +++ b/Slim/Router.php @@ -45,18 +45,11 @@ class Router implements RouterInterface protected $basePath = ''; /** - * Fast route cache is disabled + * Path to fast route cache file. Set to false to disable route caching * - * @var bool + * @var string|False */ - protected $cacheDisabled = true; - - /** - * Path to fast route cache file - * - * @var string - */ - protected $cacheFile; + protected $cacheFile = false; /** * Routes @@ -112,37 +105,24 @@ public function setBasePath($basePath) } /** - * Enable/disable route cache - * - * @param bool $cacheDisabled - * - * @return self - */ - public function setCacheDisabled($cacheDisabled) - { - $this->cacheDisabled = $cacheDisabled; - - return $this; - } - - /** - * Set path to fast route cache file + * Set path to fast route cache file. If this is false then route caching is disabled. * - * @param string $cacheFile + * @param string|false $cacheFile * * @return self */ public function setCacheFile($cacheFile) { - if (!is_string($cacheFile)) { - throw new InvalidArgumentException('Router cacheFile must be a string'); + if (!is_string($cacheFile) && $cacheFile !== false) { + throw new InvalidArgumentException('Router cacheFile must be a string or false'); } - if (!is_writable(dirname($cacheFile))) { + $this->cacheFile = $cacheFile; + + if ($cacheFile !== false && !is_writable(dirname($cacheFile))) { throw new RuntimeException('Router cacheFile directory must be writable'); } - $this->cacheFile = $cacheFile; return $this; } @@ -204,29 +184,28 @@ public function dispatch(ServerRequestInterface $request) */ protected function createDispatcher() { - if (!$this->cacheDisabled && is_null($this->cacheFile)) { - throw new RuntimeException('Router cache enabled but cacheFile not set'); + if ($this->dispatcher) { + return $this->dispatcher; } - return $this->dispatcher ?: call_user_func_array( - '\FastRoute\\' . (!$this->cacheDisabled ? 'cachedDispatcher' : 'simpleDispatcher'), - [ - function (RouteCollector $routeCollector) { - foreach ($this->getRoutes() as $route) { - $routeCollector->addRoute( - $route->getMethods(), - $route->getPattern(), - $route->getIdentifier() - ); - } - }, - [ - 'routeParser' => $this->routeParser, - 'cacheFile' => $this->cacheFile, - 'cacheDisabled' => $this->cacheDisabled, - ], - ] - ); + $routeDefinitionCallback = function (RouteCollector $r) { + foreach ($this->getRoutes() as $route) { + $r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier()); + } + }; + + if ($this->cacheFile) { + $this->dispatcher = \FastRoute\cachedDispatcher($routeDefinitionCallback, [ + 'routeParser' => $this->routeParser, + 'cacheFile' => $this->cacheFile, + ]); + } else { + $this->dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback, [ + 'routeParser' => $this->routeParser, + ]); + } + + return $this->dispatcher; } /** diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 7d8951a34..7cab94f3a 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -159,59 +159,6 @@ public function testMagicGetMethod() public function testRouteCacheDisabledByDefault() { - $this->assertTrue($this->container->get('settings')['routerCacheDisabled']); - } - - /** - * Get cacheDisabled protected property from Route instance - * - * @return string - */ - protected function getRouteCacheDisabled() - { - $router = $this->container['router']; - $getCacheDisabled = function ($router) { - return $router->cacheDisabled; - }; - $getCacheDisabled = \Closure::bind($getCacheDisabled, null, $this->container['router']); - return $getCacheDisabled($router); - } - - /** - * Get cacheFile protected property from Route instance - * - * @return string - */ - protected function getRouteCacheFile() - { - $router = $this->container['router']; - $getCacheFile = function ($router) { - return $router->cacheFile; - }; - $getCacheFile = \Closure::bind($getCacheFile, null, $this->container['router']); - return $getCacheFile($router); - } - - /** - * Test that cache is not enabled and no cache file is set to Router - * when option is disabled from config - */ - public function testRouteCacheFileNotSetWhenCacheDisabled() - { - $this->container->get('settings')['routerCacheDisabled'] = true; - $this->assertTrue($this->getRouteCacheDisabled()); - $this->assertNull($this->getRouteCacheFile()); - } - - /** - * Test that cache is enabled and cache file is set to Router - * when option is enabled from config - */ - public function testRouteCacheSetWhenCacheEnabled() - { - $this->container->get('settings')['routerCacheDisabled'] = false; - $this->container->get('settings')['routerCacheFile'] = 'slim'; - $this->assertFalse($this->getRouteCacheDisabled()); - $this->assertEquals('slim', $this->getRouteCacheFile()); + $this->assertFalse($this->container->get('settings')['routerCacheFile']); } } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index cdc8a793f..63b3a7ba7 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -308,9 +308,23 @@ public function testPathForWithModifiedRoutePattern() } /** - * Test cacheFile should be a string + * Test cacheFile may be set to false */ - public function testSettingInvalidCacheFileNotString() + public function testSettingCacheFileToFalse() + { + $this->router->setCacheFile(false); + + $class = new \ReflectionClass($this->router); + $property = $class->getProperty('cacheFile'); + $property->setAccessible(true); + + $this->assertFalse($property->getValue($this->router)); + } + + /** + * Test cacheFile should be a string or false + */ + public function testSettingInvalidCacheFileValue() { $this->setExpectedException( '\InvalidArgumentException', @@ -335,35 +349,35 @@ public function testSettingInvalidCacheFileNotExisting() } /** - * Test if cache is enabled but cache file is not set + * Test route dispatcher is created in case of route cache */ - public function testCacheFileNotSetButCacheEnabled() + public function testCreateDispatcherWithRouteCache() { - $this->setExpectedException( - '\RuntimeException', - 'Router cache enabled but cacheFile not set' - ); - - $this->router->setCacheDisabled(false); - + $cacheFile = dirname(__FILE__) . '/' . uniqid(microtime(true)); + $this->router->setCacheFile($cacheFile); $class = new \ReflectionClass($this->router); $method = $class->getMethod('createDispatcher'); $method->setAccessible(true); - $method->invoke($this->router); + + $dispatcher = $method->invoke($this->router); + $this->assertInstanceOf('\FastRoute\Dispatcher', $dispatcher); + $this->assertFileExists($cacheFile, 'cache file was not created'); + + unlink($cacheFile); } /** - * Test route dispatcher is created in case of route cache + * Calling createDispatcher as second time should give you back the same + * dispatcher as when you called it the first time. */ - public function testCreateDispatcherWithRouteCache() + public function testCreateDispatcherReturnsSameDispatcherASecondTime() { - $cacheFile = dirname(__FILE__) . '/' . uniqid(microtime(true)); - $this->router->setCacheDisabled(false); - $this->router->setCacheFile($cacheFile); $class = new \ReflectionClass($this->router); $method = $class->getMethod('createDispatcher'); $method->setAccessible(true); - $this->assertInstanceOf('\FastRoute\Dispatcher', $method->invoke($this->router)); - unlink($cacheFile); + + $dispatcher = $method->invoke($this->router); + $dispatcher2 = $method->invoke($this->router); + $this->assertSame($dispatcher2, $dispatcher); } } From 0f5729048815b585fb9b75bd4df4a535533b785b Mon Sep 17 00:00:00 2001 From: Rob Allen Date: Sun, 8 May 2016 20:33:40 +0100 Subject: [PATCH 6/6] Improve routeCacheFile test Ensure that the cached routes file actually contains dispatchable routes. --- tests/RouterTest.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 63b3a7ba7..425e340a2 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -349,10 +349,17 @@ public function testSettingInvalidCacheFileNotExisting() } /** - * Test route dispatcher is created in case of route cache + * Test cached routes file is created & that it holds our routes. */ - public function testCreateDispatcherWithRouteCache() + public function testRouteCacheFileCanBeDispatched() { + $methods = ['GET']; + $pattern = '/hello/{first}/{last}'; + $callable = function ($request, $response, $args) { + echo sprintf('Hello %s %s', $args['first'], $args['last']); + }; + $route = $this->router->map($methods, $pattern, $callable)->setName('foo'); + $cacheFile = dirname(__FILE__) . '/' . uniqid(microtime(true)); $this->router->setCacheFile($cacheFile); $class = new \ReflectionClass($this->router); @@ -363,6 +370,19 @@ public function testCreateDispatcherWithRouteCache() $this->assertInstanceOf('\FastRoute\Dispatcher', $dispatcher); $this->assertFileExists($cacheFile, 'cache file was not created'); + // instantiate a new router & load the cached routes file & see if + // we can dispatch to the route we cached. + $router2 = new Router(); + $router2->setCacheFile($cacheFile); + + $class = new \ReflectionClass($router2); + $method = $class->getMethod('createDispatcher'); + $method->setAccessible(true); + + $dispatcher2 = $method->invoke($this->router); + $result = $dispatcher2->dispatch('GET', '/hello/josh/lockhart'); + $this->assertSame(\FastRoute\Dispatcher::FOUND, $result[0]); + unlink($cacheFile); }