diff --git a/.gitignore b/.gitignore index 3a9875b..1c451b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/vendor/ +vendor/ composer.lock +bin/ diff --git a/.travis.yml b/.travis.yml index 4bcf7ea..6d1e0fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,5 @@ before_script: - composer install --prefer-source script: - - ./vendor/bin/phpspec run --format=pretty - - ./vendor/bin/behat -fprogress --strict + - ./bin/phpspec run --format=pretty + - ./bin/behat -fprogress --strict diff --git a/composer.json b/composer.json index d7ae5af..8bd1cd6 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,11 @@ "require-dev": { "symfony/filesystem": "^2.8", "symfony/yaml": "^2.8", - "phpspec/phpspec": "^2.5" + "phpspec/phpspec": "^2.5", + "phpunit/phpunit": "^4.0" + }, + "config": { + "bin-dir": "bin" }, "extra": { "branch-alias": { diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 6fa1a55..babe06d 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -1,5 +1,6 @@ sessionBuilder->addBootstrapScript($this->directory . '/' . $file); } + + /** + * @Then the page content should include the error :errorMessage + */ + public function thePageContentShouldIncludeTheError($errorMessage) + { + $pageContent = $this->session->getPage()->getContent(); + + if (strpos($pageContent, $errorMessage) === false) { + throw new RuntimeException(sprintf("Expected page contain error with: %s, page content was:\n%s", $errorMessage, $pageContent)); + } + } } diff --git a/features/bootstrap/SessionBuilder.php b/features/bootstrap/SessionBuilder.php index f85b0cb..3edd4cd 100644 --- a/features/bootstrap/SessionBuilder.php +++ b/features/bootstrap/SessionBuilder.php @@ -3,6 +3,7 @@ use Behat\Mink\Driver\BrowserKitDriver; use Behat\Mink\Session; use carlosV2\LegacyDriver\Client; +use carlosV2\LegacyDriver\LegacyApp\Controllers; use carlosV2\LegacyDriver\LegacyApp\LegacyAppBuilder; use carlosV2\LegacyDriver\Serializer; use Symfony\Component\Routing\Route; @@ -16,7 +17,7 @@ class SessionBuilder private $documentRoot; /** - * @var RouteCollection + * @var Controllers */ private $controllers; @@ -36,7 +37,7 @@ class SessionBuilder public function __construct($documentRoot) { $this->documentRoot = $documentRoot; - $this->controllers = new RouteCollection(); + $this->controllers = new Controllers(new RouteCollection()); $this->environment = array(); $this->bootstrapScripts = array(); } @@ -46,7 +47,7 @@ public function __construct($documentRoot) */ public function addController(Route $route) { - $this->controllers->add(md5(serialize($route)), $route); + $this->controllers->add($route); } /** diff --git a/features/passing_parameters.feature b/features/passing_parameters.feature new file mode 100644 index 0000000..56afa1b --- /dev/null +++ b/features/passing_parameters.feature @@ -0,0 +1,34 @@ +Feature: Passing parameters + In order to emulate ... + As a developer + I need to be able to pass GET and POST parameters to the application + + Background: + Given the file "index.php" is configured as the unique frontend controller + + Scenario: Error is generated when trying to render input when no parameters passed + Given the "index.php" file contains: + """ + beConstructedWith($routeCollection); + } +} diff --git a/spec/LegacyApp/LegacyAppSpec.php b/spec/LegacyApp/LegacyAppSpec.php new file mode 100644 index 0000000..7d275fa --- /dev/null +++ b/spec/LegacyApp/LegacyAppSpec.php @@ -0,0 +1,48 @@ +__toString()->willReturn('script.php'); + $documentRoot = './'; + $environmentVariables = []; + $bootstrapScripts = [$bootstrapScript]; + + $bootstrapScript->load()->willReturn(); + + $this->beConstructedWith($documentRoot, $controllers, $environmentVariables, $bootstrapScripts); + } + + function it_loads_all_bootstrap_scripts(Script $bootstrapScript, Controllers $controllers) + { + $request = new Request('http://localhost/', 'GET'); + $controllers->getFront($request)->willReturn($bootstrapScript); + + $bootstrapScript->load()->shouldBeCalledTimes(2); + + $this->handle($request); + } + + function it_sets_up_request_parameters_from_query_string_on_GET(Script $bootstrapScript, Controllers $controllers) + { + $request = new Request('http://localhost/?name=jon', 'GET'); + $controllers->getFront($request)->willReturn($bootstrapScript); + + $this->handle($request); + + PHPUnit_Framework_Assert::assertEquals($_REQUEST['name'], 'jon'); + } +} diff --git a/spec/LegacyApp/ScriptSpec.php b/spec/LegacyApp/ScriptSpec.php new file mode 100644 index 0000000..d6324d9 --- /dev/null +++ b/spec/LegacyApp/ScriptSpec.php @@ -0,0 +1,13 @@ +beConstructedWith(['bootstrap.php']); + } +} diff --git a/src/Client.php b/src/Client.php index afda8b9..520711e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -57,11 +57,11 @@ protected function doRequest($request) /** * Compose the command to run with the same PHP binary that was used to run Behat * - * @param Request $request + * @param object $request * * @return string */ - private function composeCommand(Request $request) + private function composeCommand($request) { return sprintf( '%s %s %s %s %s', diff --git a/src/LegacyApp/Controllers.php b/src/LegacyApp/Controllers.php new file mode 100644 index 0000000..e56b4e8 --- /dev/null +++ b/src/LegacyApp/Controllers.php @@ -0,0 +1,52 @@ +routeCollection = $routeCollection; + } + + /** + * @param Request $request + * + * @return Script + */ + public function getFront(Request $request) + { + $parts = parse_url($request->getUri()); + + $matcher = new UrlMatcher( + $this->routeCollection, + new RequestContext( + '/', + strtoupper($request->getMethod()) + ) + ); + + $parameters = $matcher->match($parts['path']); + + return new Script($parameters['file']); + } + + public function add(Route $route) + { + $this->routeCollection->add(md5(serialize($route)), $route); + } +} diff --git a/src/LegacyApp/LegacyApp.php b/src/LegacyApp/LegacyApp.php index aa74a01..97be22c 100644 --- a/src/LegacyApp/LegacyApp.php +++ b/src/LegacyApp/LegacyApp.php @@ -3,8 +3,6 @@ namespace carlosV2\LegacyDriver\LegacyApp; use Symfony\Component\BrowserKit\Request; -use Symfony\Component\Routing\Matcher\UrlMatcher; -use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RouteCollection; final class LegacyApp @@ -30,14 +28,14 @@ final class LegacyApp private $bootstrapScripts; /** - * @param string $documentRoot - * @param RouteCollection $controllers - * @param string[] $environmentVariables - * @param string[] $bootstrapScripts + * @param string $documentRoot + * @param Controllers $controllers + * @param string[] $environmentVariables + * @param string[] $bootstrapScripts */ public function __construct( $documentRoot, - RouteCollection $controllers, + Controllers $controllers, array $environmentVariables, array $bootstrapScripts ) { @@ -52,32 +50,11 @@ public function __construct( */ public function handle(Request $request) { - $controller = $this->getFrontendControllerScript($request); - - chdir(dirname($controller)); $this->setVariables($request); - $this->bootstrapScripts[] = $controller; - $this->bootstrapApp(); - } + $this->bootstrapScripts[] = $this->controllers->getFront($request); - /** - * @param Request $request - * - * @return string - */ - private function getFrontendControllerScript(Request $request) - { - $parts = parse_url($request->getUri()); - $matcher = new UrlMatcher( - $this->controllers, - new RequestContext( - '/', - strtoupper($request->getMethod()) - ) - ); - $parameters = $matcher->match($parts['path']); - return $parameters['file']; + $this->bootstrapApp(); } /** @@ -135,7 +112,10 @@ private function setEnvironmentVariables() private function setGetVariables(Request $request) { if (strtoupper($request->getMethod()) === 'GET') { - $_GET = $request->getParameters(); + $parts = parse_url($request->getUri()); + if (isset($parts['query'])) { + parse_str($parts['query'], $_GET); + } } $_REQUEST = array_merge($_REQUEST, $_GET); @@ -170,7 +150,7 @@ private function setServerVariables(Request $request) { $_SERVER = $request->getServer(); $_SERVER['DOCUMENT_ROOT'] = $this->documentRoot . '/'; - $_SERVER['SCRIPT_FILENAME'] = $this->getFrontendControllerScript($request); + $_SERVER['SCRIPT_FILENAME'] = $this->controllers->getFront($request); $_SERVER['SCRIPT_NAME'] = str_replace($this->documentRoot, '', $_SERVER['SCRIPT_FILENAME']); $_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME']; @@ -184,15 +164,13 @@ private function setServerVariables(Request $request) $_SERVER['QUERY_STRING'] = $parts['query']; } - if ($_SERVER['HTTP_HOST'] === 'https') { + if ($_SERVER['REQUEST_SCHEME'] === 'https') { $_SERVER['HTTPS'] = 'on'; } } private function bootstrapApp() { - foreach ($this->bootstrapScripts as $bootstrapScript) { - require_once $bootstrapScript; - } + array_map(function(Script $script) { $script->load(); }, $this->bootstrapScripts); } } diff --git a/src/LegacyApp/LegacyAppBuilder.php b/src/LegacyApp/LegacyAppBuilder.php index d3195ed..3b684da 100644 --- a/src/LegacyApp/LegacyAppBuilder.php +++ b/src/LegacyApp/LegacyAppBuilder.php @@ -2,8 +2,6 @@ namespace carlosV2\LegacyDriver\LegacyApp; -use Symfony\Component\Routing\RouteCollection; - final class LegacyAppBuilder { /** @@ -12,7 +10,7 @@ final class LegacyAppBuilder private $documentRoot; /** - * @var RouteCollection + * @var Controllers */ private $controllers; @@ -27,15 +25,14 @@ final class LegacyAppBuilder private $bootstrapScripts; /** - * @param string $documentRoot - * @param RouteCollection $controllers + * @param string $documentRoot + * @param Controllers $controllers */ - public function __construct($documentRoot, RouteCollection $controllers) + public function __construct($documentRoot, Controllers $controllers) { $this->documentRoot = $documentRoot; $this->controllers = $controllers; $this->environmentVariables = array(); - $this->bootstrapScripts = array(); } /** @@ -51,7 +48,9 @@ public function addEnvironmentVariables(array $environmentVariables) */ public function addBootstrapScripts(array $bootstrapScripts) { - $this->bootstrapScripts = $bootstrapScripts; + $this->bootstrapScripts = array_map(function($script) { + return new Script($script); + }, $bootstrapScripts); } /** diff --git a/src/LegacyApp/Script.php b/src/LegacyApp/Script.php new file mode 100644 index 0000000..9615ef1 --- /dev/null +++ b/src/LegacyApp/Script.php @@ -0,0 +1,32 @@ +script = $script; + } + + /** + */ + public function load() + { + chdir(dirname($this->script)); + require_once $this->script; + } + + public function __toString() + { + return $this->script; + } +}