From e6ac9e067174b384d55a3c2e444baf5d5c58973b Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 11 Dec 2016 16:54:47 -0500 Subject: [PATCH 1/8] Start work on new settings interface --- Slim/App.php | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/Slim/App.php b/Slim/App.php index d539ef3c2..ce4eed4a6 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -63,6 +63,19 @@ class App */ protected $router; + /** + * @var array + */ + protected $settings = [ + 'httpVersion' => '1.1', + 'responseChunkSize' => 4096, + 'outputBuffering' => 'append', + 'determineRouteBeforeAppMiddleware' => false, + 'displayErrorDetails' => false, + 'addContentLengthHeader' => true, + 'routerCacheFile' => false, + ]; + /******************************************************************************** * Constructor *******************************************************************************/ @@ -130,6 +143,75 @@ public function __call($method, $args) throw new \BadMethodCallException("Method $method is not a valid method"); } + /******************************************************************************** + * Settings management + *******************************************************************************/ + + /** + * Does app have a setting with given key? + * + * @param string $key + * @return bool + */ + public function hasSetting($key) + { + return isset($this->settings[$key]); + } + + /** + * Get app settings + * + * @return array + */ + public function getSettings() + { + return $this->settings; + } + + /** + * Get app setting with given key + * + * @param string $key + * @return mixed|null + */ + public function getSetting($key) + { + return $this->hasSetting($key) ? $this->settings[$key] : null; + } + + /** + * Merge a key-value array with existing app settings + * + * @param array $settings + */ + public function addSettings(array $settings) + { + $this->settings = array_merge($this->settings, $settings); + } + + /** + * Add single app setting + * + * @param string $key + * @param mixed $value + */ + public function addSetting($key, $value) + { + $this->settings[$key] = $value; + } + + /** + * Remove/unset app setting + * + * @param $key + */ + public function removeSetting($key) + { + if ($this->hasSetting($key)) { + unset($this->settings[$key]); + } + } + /******************************************************************************** * Setter and getter methods *******************************************************************************/ From b6c2927bec93ad9fa3ed58293ccc34742197ee0f Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 11 Dec 2016 17:05:43 -0500 Subject: [PATCH 2/8] Unset will work even if key doesn't exist --- Slim/App.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index ce4eed4a6..b5b10ad62 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -207,9 +207,7 @@ public function addSetting($key, $value) */ public function removeSetting($key) { - if ($this->hasSetting($key)) { - unset($this->settings[$key]); - } + unset($this->settings[$key]); } /******************************************************************************** From dac7c1f76f35ce9812cb76403fac75f8f09f7506 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 11 Dec 2016 17:22:11 -0500 Subject: [PATCH 3/8] Add unit tests --- Slim/App.php | 10 ---------- tests/AppTest.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index b5b10ad62..9fb4ebc92 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -200,16 +200,6 @@ public function addSetting($key, $value) $this->settings[$key] = $value; } - /** - * Remove/unset app setting - * - * @param $key - */ - public function removeSetting($key) - { - unset($this->settings[$key]); - } - /******************************************************************************** * Setter and getter methods *******************************************************************************/ diff --git a/tests/AppTest.php b/tests/AppTest.php index e44fec458..5e3ff55af 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -52,6 +52,51 @@ public function testIssetInContainer() $router = $app->getRouter(); $this->assertTrue(isset($router)); } + + /******************************************************************************** + * Settings management methods + *******************************************************************************/ + + public function testHasSetting() + { + $app = new App(); + $this->assertTrue($app->hasSetting('httpVersion')); + $this->assertFalse($app->hasSetting('foo')); + } + + public function testGetSettings() + { + $app = new App(); + $appSettings = $app->getSettings(); + $this->assertAttributeEquals($appSettings, 'settings', $app); + } + + public function testGetSettingExists() + { + $app = new App(); + $this->assertEquals('1.1', $app->getSetting('httpVersion')); + } + + public function testGetSettingNotExists() + { + $app = new App(); + $this->assertNull($app->getSetting('foo')); + } + + public function testAddSettings() + { + $app = new App(); + $app->addSettings(['foo' => 'bar']); + $this->assertAttributeContains('foo', 'settings', $app); + } + + public function testAddSetting() + { + $app = new App(); + $app->addSetting('foo', 'bar'); + $this->assertAttributeContains('foo', 'settings', $app); + } + /******************************************************************************** * Router proxy methods *******************************************************************************/ From b06c71ddc5af43c25f5eee70c552bb194c33e7e5 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 11 Dec 2016 17:25:42 -0500 Subject: [PATCH 4/8] Allow default value for App::getSetting --- Slim/App.php | 7 ++++--- tests/AppTest.php | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index 9fb4ebc92..bd034acf0 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -172,11 +172,12 @@ public function getSettings() * Get app setting with given key * * @param string $key - * @return mixed|null + * @param mixed $defaultValue + * @return mixed */ - public function getSetting($key) + public function getSetting($key, $defaultValue = null) { - return $this->hasSetting($key) ? $this->settings[$key] : null; + return $this->hasSetting($key) ? $this->settings[$key] : $defaultValue; } /** diff --git a/tests/AppTest.php b/tests/AppTest.php index 5e3ff55af..3e8385250 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -83,6 +83,12 @@ public function testGetSettingNotExists() $this->assertNull($app->getSetting('foo')); } + public function testGetSettingNotExistsWithDefault() + { + $app = new App(); + $this->assertEquals('what', $app->getSetting('foo', 'what')); + } + public function testAddSettings() { $app = new App(); From 7a5c616c5e924c9daddc454344871d71b174d209 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 11 Dec 2016 17:33:34 -0500 Subject: [PATCH 5/8] Let App use new settings methods --- Slim/App.php | 23 ++++++----------------- tests/AppTest.php | 3 +-- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index bd034acf0..2baece6c3 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -256,11 +256,7 @@ public function getRouter() if ($resolver instanceof CallableResolverInterface) { $router->setCallableResolver($resolver); } - // TODO: Refactor settings out of container - $routerCacheFile = false; - if (isset($this->container->get('settings')['routerCacheFile'])) { - $routerCacheFile = $this->container->get('settings')['routerCacheFile']; - } + $routerCacheFile = $this->getSetting('routerCacheFile', false); $router->setCacheFile($routerCacheFile); $this->router = $router; @@ -383,10 +379,9 @@ public function map(array $methods, $pattern, $callable) $router = $this->getRouter(); $route = $router->map($methods, $pattern, $callable); - // TODO: Set route output buffering without a container - // TODO: Refactor app settings out of container + // TODO: Do we keep output buffering? if (is_callable([$route, 'setOutputBuffering'])) { - $route->setOutputBuffering($this->container->get('settings')['outputBuffering']); + $route->setOutputBuffering($this->getSetting('outputBuffering', 'append')); } // TODO: Route callable binding and output buffering should be handled within router @@ -474,8 +469,7 @@ public function process(ServerRequestInterface $request, ResponseInterface $resp $router = $this->getRouter(); // Dispatch the Router first if the setting for this is on - // TODO: Refactor settings out of container - if ($this->container->get('settings')['determineRouteBeforeAppMiddleware'] === true) { + if ($this->getSetting('determineRouteBeforeAppMiddleware') === true) { // Dispatch router (note: you won't be able to alter routes after this) $request = $this->dispatchRouterAndPrepareRoute($request, $router); } @@ -525,10 +519,7 @@ public function respond(ResponseInterface $response) if ($body->isSeekable()) { $body->rewind(); } - // TODO: Refactor settings out of container - $settings = $this->container->get('settings'); - $chunkSize = $settings['responseChunkSize']; - + $chunkSize = $this->getSetting('responseChunkSize', 4096); $contentLength = $response->getHeaderLine('Content-Length'); if (!$contentLength) { $contentLength = $body->getSize(); @@ -651,10 +642,8 @@ protected function finalize(ResponseInterface $response) return $response->withoutHeader('Content-Type')->withoutHeader('Content-Length'); } - // TODO: Refactor settings out of container // Add Content-Length header if `addContentLengthHeader` setting is set - if (isset($this->container->get('settings')['addContentLengthHeader']) && - $this->container->get('settings')['addContentLengthHeader'] == true) { + if ($this->getSetting('addContentLengthHeader') == true) { if (ob_get_length() > 0) { throw new \RuntimeException("Unexpected data in output buffer. " . "Maybe you have characters before an opening getBody()->write('foo'); $app = new App(); - $container = $app->getContainer(); - $container['settings']['addContentLengthHeader'] = false; + $app->addSetting('addContentLengthHeader', false); $response = $method->invoke($app, $response); $this->assertFalse($response->hasHeader('Content-Length')); From 4730f97b23ce5486c2e226d5f839076b1c89b55f Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sat, 17 Dec 2016 10:03:03 -0500 Subject: [PATCH 6/8] Progress --- Slim/App.php | 185 +++++++++++++++++++++++++++++++++++++--------- tests/AppTest.php | 25 +------ 2 files changed, 153 insertions(+), 57 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index 2baece6c3..8785ce252 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -9,6 +9,8 @@ namespace Slim; use Exception; +use Slim\Handlers\NotAllowed; +use Slim\Handlers\NotFound; use Slim\Interfaces\CallableResolverInterface; use Throwable; use Closure; @@ -29,6 +31,7 @@ use Slim\Interfaces\RouteGroupInterface; use Slim\Interfaces\RouteInterface; use Slim\Interfaces\RouterInterface; +use Slim\Handlers\Error; /** * App @@ -63,6 +66,21 @@ class App */ protected $router; + /** + * @var callable + */ + protected $notFoundHandler; + + /** + * @var callable + */ + protected $notAllowedHandler; + + /** + * @var callable + */ + protected $errorHandler; + /** * @var array */ @@ -83,30 +101,34 @@ class App /** * Create new application * - * @param ContainerInterface|array $container Either a ContainerInterface or an associative array of app settings - * @throws InvalidArgumentException when no container is provided that implements ContainerInterface + * @param array $settings */ - public function __construct($container = []) + public function __construct(array $settings = []) { - if (is_array($container)) { - $container = new Container($container); - } - if (!$container instanceof ContainerInterface) { - throw new InvalidArgumentException('Expected a ContainerInterface'); - } - $this->container = $container; + $this->addSettings($settings); + $this->container = new Container(); } /** - * Enable access to the DI container by consumers of $app + * Get container * - * @return ContainerInterface + * @return ContainerInterface|null */ public function getContainer() { return $this->container; } + /** + * Set container + * + * @param ContainerInterface $container + */ + public function setContainer(ContainerInterface $container) + { + $this->container = $container; + } + /** * Add middleware * @@ -252,6 +274,7 @@ public function getRouter() if ($container instanceof ContainerInterface) { $router->setContainer($container); } + $resolver = $this->getCallableResolver(); if ($resolver instanceof CallableResolverInterface) { $router->setCallableResolver($resolver); @@ -265,6 +288,112 @@ public function getRouter() return $this->router; } + /** + * Set callable to handle scenarios where a suitable + * route does not match the current request. + * + * This service MUST return a callable that accepts + * two arguments: + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Psr\Http\Message\ResponseInterface + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param callable $handler + */ + public function setNotFoundHandler(callable $handler) + { + $this->notFoundHandler = $handler; + } + + /** + * Get callable to handle scenarios where a suitable + * route does not match the current request. + * + * @return callable|Error + */ + public function getNotFoundHandler() + { + if (!$this->notFoundHandler) { + $this->notFoundHandler = new NotFound(); + } + + return $this->notFoundHandler; + } + + /** + * Set callable to handle scenarios where a suitable + * route matches the request URI but not the request method. + * + * This service MUST return a callable that accepts + * three arguments: + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Psr\Http\Message\ResponseInterface + * 3. Array of allowed HTTP methods + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param callable $handler + */ + public function setNotAllowedHandler(callable $handler) + { + $this->notAllowedHandler = $handler; + } + + /** + * Get callable to handle scenarios where a suitable + * route matches the request URI but not the request method. + * + * @return callable|Error + */ + public function getNotAllowedHandler() + { + if (!$this->notAllowedHandler) { + $this->notAllowedHandler = new NotAllowed(); + } + + return $this->notAllowedHandler; + } + + /** + * Set callable to handle scenarios where an error + * occurs when processing the current request. + * + * This service MUST return a callable that accepts three arguments: + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Psr\Http\Message\ResponseInterface + * 3. Instance of \Error + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param callable $handler + */ + public function setErrorHandler(callable $handler) + { + $this->errorHandler = $handler; + } + + /** + * Get callable to handle scenarios where an error + * occurs when processing the current request. + * + * @return callable|Error + */ + public function getErrorHandler() + { + if (!$this->errorHandler) { + $this->errorHandler = new Error($this->getSetting('displayErrorDetails')); + } + + return $this->errorHandler; + } + /******************************************************************************** * Router proxy methods *******************************************************************************/ @@ -561,8 +690,6 @@ public function respond(ResponseInterface $response) * @param ResponseInterface $response The most recent Response object * * @return ResponseInterface - * @throws MethodNotAllowedException - * @throws NotFoundException */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response) { @@ -582,20 +709,12 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res $route = $router->lookupRoute($routeInfo[1]); return $route->run($request, $response); } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { - if (!$this->container->has('notAllowedHandler')) { - throw new MethodNotAllowedException($request, $response, $routeInfo[1]); - } - /** @var callable $notAllowedHandler */ - $notAllowedHandler = $this->container->get('notAllowedHandler'); + $notAllowedHandler = $this->getNotAllowedHandler(); return $notAllowedHandler($request, $response, $routeInfo[1]); } - if (!$this->container->has('notFoundHandler')) { - throw new NotFoundException($request, $response); - } - /** @var callable $notFoundHandler */ - $notFoundHandler = $this->container->get('notFoundHandler'); - return $notFoundHandler($request, $response); + $notFoundHandler = $this->getNotFoundHandler(); + return $notFoundHandler($request, $response, $routeInfo[1]); } /** @@ -689,28 +808,21 @@ protected function isEmptyResponse(ResponseInterface $response) protected function handleException(Exception $e, ServerRequestInterface $request, ResponseInterface $response) { if ($e instanceof MethodNotAllowedException) { - $handler = 'notAllowedHandler'; + $handler = $this->getNotAllowedHandler(); $params = [$e->getRequest(), $e->getResponse(), $e->getAllowedMethods()]; } elseif ($e instanceof NotFoundException) { - $handler = 'notFoundHandler'; + $handler = $this->getNotFoundHandler(); $params = [$e->getRequest(), $e->getResponse()]; } elseif ($e instanceof SlimException) { // This is a Stop exception and contains the response return $e->getResponse(); } else { // Other exception, use $request and $response params - $handler = 'errorHandler'; + $handler = $this->getErrorHandler(); $params = [$request, $response, $e]; } - if ($this->container->has($handler)) { - $callable = $this->container->get($handler); - // Call the registered handler - return call_user_func_array($callable, $params); - } - - // No handlers found, so just throw the exception - throw $e; + return call_user_func_array($handler, $params); } /** @@ -725,6 +837,7 @@ protected function handleException(Exception $e, ServerRequestInterface $request */ protected function handlePhpError(Throwable $e, ServerRequestInterface $request, ResponseInterface $response) { + // TODO: Why does this exist in addition to normal error handler? $handler = 'phpErrorHandler'; $params = [$request, $response, $e]; diff --git a/tests/AppTest.php b/tests/AppTest.php index 3438115a3..7d006bf72 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -40,19 +40,6 @@ public static function tearDownAfterClass() // ini_set('log_errors', 1); } - public function testContainerInterfaceException() - { - $this->setExpectedException('InvalidArgumentException', 'Expected a ContainerInterface'); - $app = new App(''); - } - - public function testIssetInContainer() - { - $app = new App(); - $router = $app->getRouter(); - $this->assertTrue(isset($router)); - } - /******************************************************************************** * Settings management methods *******************************************************************************/ @@ -1164,12 +1151,10 @@ public function testInvokeWithMatchingRouteWithNamedParameter() public function testInvokeWithMatchingRouteWithNamedParameterRequestResponseArgStrategy() { - $c = new Container(); - $c['foundHandler'] = function ($c) { + $app = new App(); + $app->setNotFoundHandler(function ($c) { return new RequestResponseArgs(); - }; - - $app = new App($c); + }); $app->get('/foo/{name}', function ($req, $res, $name) { return $res->write("Hello {$name}"); }); @@ -1940,9 +1925,7 @@ public function testAppRunWithdetermineRouteBeforeAppMiddleware() public function testExceptionErrorHandlerDisplaysErrorDetails() { $app = new App([ - 'settings' => [ - 'displayErrorDetails' => true - ], + 'displayErrorDetails' => true ]); // Prepare request and response objects From f95710774cb7c48f9d808ec18e007d4ebeb4c223 Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sat, 17 Dec 2016 10:28:12 -0500 Subject: [PATCH 7/8] Continue settings changes, let app handlers have own setter methods --- Slim/App.php | 68 +++++++++++++-------- tests/AppTest.php | 153 +++++++++++++++++++++------------------------- 2 files changed, 112 insertions(+), 109 deletions(-) diff --git a/Slim/App.php b/Slim/App.php index 2e18e1144..b3bedcfe5 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -11,11 +11,9 @@ use Exception; use Slim\Handlers\NotAllowed; use Slim\Handlers\NotFound; +use Slim\Handlers\PhpError; use Slim\Interfaces\CallableResolverInterface; use Throwable; -use Closure; -use InvalidArgumentException; -use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Interop\Container\ContainerInterface; @@ -23,11 +21,6 @@ use Slim\Exception\SlimException; use Slim\Exception\MethodNotAllowedException; use Slim\Exception\NotFoundException; -use Slim\Http\Uri; -use Slim\Http\Headers; -use Slim\Http\Body; -use Slim\Http\Request; -use Slim\Interfaces\Http\EnvironmentInterface; use Slim\Interfaces\RouteGroupInterface; use Slim\Interfaces\RouteInterface; use Slim\Interfaces\RouterInterface; @@ -39,11 +32,6 @@ * This is the primary class with which you instantiate, * configure, and run a Slim Framework application. * The \Slim\App class also accepts Slim Framework middleware. - * - * @property-read callable $errorHandler - * @property-read callable $phpErrorHandler - * @property-read callable $notFoundHandler function($request, $response) - * @property-read callable $notAllowedHandler function($request, $response, $allowedHttpMethods) */ class App { @@ -81,6 +69,11 @@ class App */ protected $errorHandler; + /** + * @var callable + */ + protected $phpErrorHandler; + /** * @var array */ @@ -389,6 +382,41 @@ public function getErrorHandler() return $this->errorHandler; } + /** + * Set callable to handle scenarios where a PHP error + * occurs when processing the current request. + * + * This service MUST return a callable that accepts three arguments: + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Psr\Http\Message\ResponseInterface + * 3. Instance of \Error + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param callable $handler + */ + public function setPhpErrorHandler(callable $handler) + { + $this->phpErrorHandler = $handler; + } + + /** + * Get callable to handle scenarios where a PHP error + * occurs when processing the current request. + * + * @return callable|Error + */ + public function getPhpErrorHandler() + { + if (!$this->phpErrorHandler) { + $this->phpErrorHandler = new PhpError($this->getSetting('displayErrorDetails')); + } + + return $this->phpErrorHandler; + } + /******************************************************************************** * Router proxy methods *******************************************************************************/ @@ -703,7 +731,7 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res } $notFoundHandler = $this->getNotFoundHandler(); - return $notFoundHandler($request, $response, $routeInfo[1]); + return $notFoundHandler($request, $response); } /** @@ -826,17 +854,9 @@ protected function handleException(Exception $e, ServerRequestInterface $request */ protected function handlePhpError(Throwable $e, ServerRequestInterface $request, ResponseInterface $response) { - // TODO: Why does this exist in addition to normal error handler? - $handler = 'phpErrorHandler'; + $handler = $this->getPhpErrorHandler(); $params = [$request, $response, $e]; - if ($this->container->has($handler)) { - $callable = $this->container->get($handler); - // Call the registered handler - return call_user_func_array($callable, $params); - } - - // No handlers found, so just throw the exception - throw $e; + return call_user_func_array($handler, $params); } } diff --git a/tests/AppTest.php b/tests/AppTest.php index 54bc7442f..662733fea 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -1030,9 +1030,9 @@ public function testInvokeReturnMethodNotAllowed() ); // now test that exception is raised if the handler isn't registered - unset($app->getContainer()['notAllowedHandler']); - $this->setExpectedException('Slim\Exception\MethodNotAllowedException'); - $app($req, $res); +// unset($app->getContainer()['notAllowedHandler']); +// $this->setExpectedException('Slim\Exception\MethodNotAllowedException'); +// $app($req, $res); } public function testInvokeWithMatchingRoute() @@ -1152,12 +1152,7 @@ public function testInvokeWithMatchingRouteWithNamedParameter() public function testInvokeWithMatchingRouteWithNamedParameterRequestResponseArgStrategy() { $app = new App(); - $app->setNotFoundHandler(function ($c) { - return new RequestResponseArgs(); - }; - - $app = new App($c); - $app->getRouter()->setDefaultInvocationStrategy($c['foundHandler']); + $app->getRouter()->setDefaultInvocationStrategy(new RequestResponseArgs()); $app->get('/foo/{name}', function ($req, $res, $name) { return $res->write("Hello {$name}"); }); @@ -1241,9 +1236,9 @@ public function testInvokeWithoutMatchingRoute() $this->assertAttributeEquals(404, 'status', $resOut); // now test that exception is raised if the handler isn't registered - unset($app->getContainer()['notFoundHandler']); - $this->setExpectedException('Slim\Exception\NotFoundException'); - $app($req, $res); + //unset($app->getContainer()['notFoundHandler']); + //$this->setExpectedException('Slim\Exception\NotFoundException'); + //$app($req, $res); } public function testInvokeWithPimpleCallable() @@ -1413,13 +1408,8 @@ public function testCurrentRequestAttributesAreNotLostWhenAddingRouteArguments() public function testCurrentRequestAttributesAreNotLostWhenAddingRouteArgumentsRequestResponseArg() { - $c = new Container(); - $c['foundHandler'] = function () { - return new RequestResponseArgs(); - }; - - $app = new App($c); - $app->getRouter()->setDefaultInvocationStrategy($c['foundHandler']); + $app = new App(); + $app->getRouter()->setDefaultInvocationStrategy(new RequestResponseArgs()); $app->get('/foo/{name}', function ($req, $res, $name) { return $res->write($req->getAttribute('one') . $name); }); @@ -1783,26 +1773,26 @@ public function appFactory() } /** - * @throws \Exception - * @throws \Slim\Exception\MethodNotAllowedException - * @throws \Slim\Exception\NotFoundException - * @expectedException \Exception + * throws \Exception + * throws \Slim\Exception\MethodNotAllowedException + * throws \Slim\Exception\NotFoundException + * expectedException \Exception */ - public function testRunExceptionNoHandler() - { - $app = $this->appFactory(); - - $container = $app->getContainer(); - unset($container['errorHandler']); - - $app->get('/foo', function ($req, $res, $args) { - return $res; - }); - $app->add(function ($req, $res, $args) { - throw new \Exception(); - }); - $res = $app->run(true); - } +// public function testRunExceptionNoHandler() +// { +// $app = $this->appFactory(); +// +// $container = $app->getContainer(); +// unset($container['errorHandler']); +// +// $app->get('/foo', function ($req, $res, $args) { +// return $res; +// }); +// $app->add(function ($req, $res, $args) { +// throw new \Exception(); +// }); +// $res = $app->run(true); +// } public function testRunSlimException() { @@ -1858,24 +1848,22 @@ public function testRunNotFound() } /** - * @expectedException \Slim\Exception\NotFoundException + * expectedException \Slim\Exception\NotFoundException */ - public function testRunNotFoundWithoutHandler() - { - $app = $this->appFactory(); - $container = $app->getContainer(); - unset($container['notFoundHandler']); - - $app->get('/foo', function ($req, $res, $args) { - return $res; - }); - $app->add(function ($req, $res, $args) { - throw new NotFoundException($req, $res); - }); - $res = $app->run(true); - } - - +// public function testRunNotFoundWithoutHandler() +// { +// $app = $this->appFactory(); +// $container = $app->getContainer(); +// unset($container['notFoundHandler']); +// +// $app->get('/foo', function ($req, $res, $args) { +// return $res; +// }); +// $app->add(function ($req, $res, $args) { +// throw new NotFoundException($req, $res); +// }); +// $res = $app->run(true); +// } public function testRunNotAllowed() { @@ -1892,40 +1880,36 @@ public function testRunNotAllowed() } /** - * @expectedException \Slim\Exception\MethodNotAllowedException + * expectedException \Slim\Exception\MethodNotAllowedException */ - public function testRunNotAllowedWithoutHandler() - { - $app = $this->appFactory(); - $container = $app->getContainer(); - unset($container['notAllowedHandler']); - - $app->get('/foo', function ($req, $res, $args) { - return $res; - }); - $app->add(function ($req, $res, $args) { - throw new MethodNotAllowedException($req, $res, ['POST']); - }); - $res = $app->run(true); - } +// public function testRunNotAllowedWithoutHandler() +// { +// $app = $this->appFactory(); +// $container = $app->getContainer(); +// unset($container['notAllowedHandler']); +// +// $app->get('/foo', function ($req, $res, $args) { +// return $res; +// }); +// $app->add(function ($req, $res, $args) { +// throw new MethodNotAllowedException($req, $res, ['POST']); +// }); +// $res = $app->run(true); +// } public function testAppRunWithdetermineRouteBeforeAppMiddleware() { $app = $this->appFactory(); - + $app->addSetting('determineRouteBeforeAppMiddleware', true); $app->get('/foo', function ($req, $res) { return $res->write("Test"); }); - $app->getContainer()['settings']['determineRouteBeforeAppMiddleware'] = true; - $resOut = $app->run(true); $resOut->getBody()->rewind(); $this->assertEquals("Test", $resOut->getBody()->getContents()); } - - public function testExceptionErrorHandlerDisplaysErrorDetails() { $app = new App([ @@ -1991,15 +1975,13 @@ public function testFinalizeWithoutBody() public function testCallingAContainerCallable() { - $settings = [ - 'foo' => function ($c) { - return function ($a) { - return $a; - }; - } - ]; - $app = new App($settings); - + $app = new App(); + $container = $app->getContainer(); + $container['foo'] = function ($c) { + return function ($a) { + return $a; + }; + }; $result = $app->foo('bar'); $this->assertSame('bar', $result); @@ -2008,7 +1990,8 @@ public function testCallingAContainerCallable() $request = new Request('GET', Uri::createFromString(''), $headers, [], [], $body); $response = new Response(); - $response = $app->notFoundHandler($request, $response); + $notFoundHandler = $app->getNotFoundHandler(); + $response = $notFoundHandler($request, $response); $this->assertSame(404, $response->getStatusCode()); } From 1db36bc87c1e7c1b143f009233cd1f6b168648da Mon Sep 17 00:00:00 2001 From: Josh Lockhart Date: Sun, 19 Feb 2017 09:59:46 -0500 Subject: [PATCH 8/8] Fix missing use declarations --- Slim/App.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Slim/App.php b/Slim/App.php index 03c76260e..6706538e5 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -20,6 +20,10 @@ use Slim\Exception\MethodNotAllowedException; use Slim\Exception\NotFoundException; use Slim\Exception\SlimException; +use Slim\Handlers\Error; +use Slim\Handlers\NotAllowed; +use Slim\Handlers\NotFound; +use Slim\Handlers\PhpError; use Slim\Http\Body; use Slim\Http\Headers; use Slim\Http\Request; @@ -867,7 +871,7 @@ protected function handleException(Exception $e, ServerRequestInterface $request $params = [$e->getRequest(), $e->getResponse(), $e->getAllowedMethods()]; } elseif ($e instanceof NotFoundException) { $handler = $this->getNotFoundHandler(); - $params = [$e->getRequest(), $e->getResponse()];s + $params = [$e->getRequest(), $e->getResponse()]; } elseif ($e instanceof SlimException) { // This is a Stop exception and contains the response return $e->getResponse();