diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-10-11 18:35:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-11 18:35:07 +0200 |
commit | 6aa9e824cb0e3a00fd7d235ba7529e6dde3075c8 (patch) | |
tree | c8dcc3b4cf055b086c84a4a934e61c8387e494ff | |
parent | e0ecc0b543d4bd6fea11947bc82128ad599f245f (diff) | |
parent | 3906df8a6897ecf1f3ee96ea31bbe6e6bdff8433 (diff) | |
download | router-origin/runner.zip router-origin/runner.tar.gz router-origin/runner.tar.bz2 |
Merge pull request #4 from Minstel/runnerorigin/runner
Implementation and tests for Runner/Controller
-rw-r--r-- | src/Router/Runner/Controller.php | 14 | ||||
-rw-r--r-- | tests/Router/Runner/ControllerTest.php | 140 |
2 files changed, 153 insertions, 1 deletions
diff --git a/src/Router/Runner/Controller.php b/src/Router/Runner/Controller.php index ed8c060..0969c21 100644 --- a/src/Router/Runner/Controller.php +++ b/src/Router/Runner/Controller.php @@ -14,7 +14,7 @@ use Psr\Http\Message\ResponseInterface; class Controller extends Runner { /** - * Route to a file + * Route to a controller * * @param RequestInterface $request * @param ResponseInterface $response @@ -22,6 +22,18 @@ class Controller extends Runner */ public function run(RequestInterface $request, ResponseInterface $response) { + $class = !empty($this->route->controller) ? $this->route->controller : null; + if (!class_exists($class)) { + throw new \RuntimeException("Can not route to controller '$class': class not exists"); + } + + if (!method_exists($class, '__invoke')) { + throw new \RuntimeException("Can not route to controller '$class': class does not have '__invoke' method"); + } + + $controller = new $class($this->route); + + return $controller($request, $response); } } diff --git a/tests/Router/Runner/ControllerTest.php b/tests/Router/Runner/ControllerTest.php new file mode 100644 index 0000000..abf4246 --- /dev/null +++ b/tests/Router/Runner/ControllerTest.php @@ -0,0 +1,140 @@ +<?php + +use Jasny\Router\Route; +use Jasny\Router\Runner\Controller; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +class ControllerTest extends PHPUnit_Framework_TestCase +{ + /** + * Tmp scripts + * @var array + **/ + public static $files = []; + + /** + * Test creating Controller runner + * + * @dataProvider phpScriptProvider + * @param Route $route + * @param boolean $positive + */ + public function testPhpScript($route, $positive) + { + $runner = new Controller($route); + $this->assertEquals($route, $runner->getRoute(), "Route was not set correctly"); + + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); + + if (!$positive) $this->expectException(\RuntimeException::class); + $result = $runner->run($request, $response); + + $this->assertEquals($request, $result['request'], "Request object was not passed correctly to result"); + $this->assertEquals($response, $result['response'], "Response object was not passed correctly to result"); + } + + /** + * Provide data for testing 'create' method + */ + public function phpScriptProvider() + { + foreach (['noInvoke', 'withInvoke'] as $type) { + list($class, $path) = static::createTmpScript($type); + static::$files[$type] = compact('class', 'path'); + } + + return [ + [Route::create(['test' => 'test']), false], + [Route::create(['fn' => 'testFunction', 'value' => 'test']), false], + [Route::create(['controller' => 'TestController', 'value' => 'test']), false], + [Route::create(['controller' => '', 'value' => 'test']), false], + [Route::create(['controller' => static::$files['noInvoke']['class'], 'path' => static::$files['noInvoke']['path']]), false], + [Route::create(['controller' => static::$files['withInvoke']['class'], 'path' => static::$files['withInvoke']['path']]), true], + ]; + } + + /** + * Delete tmp test scripts + */ + public static function tearDownAfterClass() + { + foreach (static::$files as $path) { + unlink($path['path']); + } + } + + /** + * Create single tmp script file for testing + * + * @param string $type ('returnTrue', 'returnNotTrue') + * @return string $path + */ + public static function createTmpScript($type) + { + $dir = rtrim(sys_get_temp_dir(), '/'); + + do { + $name = static::getRandomString() . '-test-script.php'; + $path = $dir . '/' . $name; + + if (!file_exists($path)) break; + } while (true); + + if ($type === 'noInvoke') { + $class = 'RunnerTestConrtollerInvalid'; + $content = +<<<CONTENT +<?php + +class $class { + public \$route = null; + + public function __construct(\$route) + { + \$this->route = \$route; + } +} +CONTENT; + } else { + $class = 'RunnerTestConrtoller'; + $content = +<<<CONTENT +<?php + +class $class { + public \$route = null; + + public function __construct(\$route) + { + \$this->route = \$route; + } + + public function __invoke(Psr\Http\Message\RequestInterface \$request, Psr\Http\Message\ResponseInterface \$response) + { + return ['request' => \$request, 'response' => \$response]; + } +} +CONTENT; + } + + $bytes = file_put_contents($path, $content); + static::assertTrue((int)$bytes > 0); + + require_once $path; + + return [$class, $path]; + } + + /** + * Get random string of given length (no more then length of md5 hash) + * + * @param int $length + * @return string + */ + public static function getRandomString($length = 10) + { + return substr(md5(microtime(true) * mt_rand()), 0, $length); + } +} |