From 742d3358b562b2e801638ed5c64f37d00abd3477 Mon Sep 17 00:00:00 2001 From: Bartosz Pietrzak Date: Wed, 9 Jan 2019 16:09:20 +0100 Subject: [PATCH 01/12] Injected parameter test POC --- .../injecting_parameters_into_context.feature | 44 +++++++++++++++++++ tests/Behat/Context/TestContext.php | 42 ++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 features/injecting_parameters_into_context.feature diff --git a/features/injecting_parameters_into_context.feature b/features/injecting_parameters_into_context.feature new file mode 100644 index 0000000..a1d1086 --- /dev/null +++ b/features/injecting_parameters_into_context.feature @@ -0,0 +1,44 @@ +Feature: Injecting parameters into context + + Background: + Given a context file "features/bootstrap/FeatureContext.php" containing: + """ + parameter = $parameter; + } + + /** + * @Then the parameter should be injected into the context + */ + public function behatContainerShouldBeInjectedToTheContext() + { + if (null === $this->parameter || empty($this->parameter)) { + throw new \DomainException('Required parameter was not injected!'); + } + } + } + """ + And an application kernel injecting a parameter into the FeatureContext class + And a Behat configuration with the minimal working configuration for SymfonyExtension + And a Behat configuration with the minimal working configuration for MinkExtension + + + Scenario: Injecting parameters into context with SymfonyExtension + Given a feature file "features/injecting_parameter_into_context.feature" containing: + """ + Feature: Injecting parameter into the context + Scenario: + Then the parameter should be injected into the context + """ + When I run Behat + Then it should pass diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index 8dae841..4e72daf 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -157,6 +157,48 @@ CON ); } + /** + * @Given /^an application kernel injecting a parameter into the FeatureContext class$/ + */ + public function thereIsKernelInjectingParameterIntoFeatureContextClass(): void + { + $this->thereIsFile('app/AppKernel.php', <<<'CON' +load(function (ContainerBuilder $container): void { + $container->loadFromExtension('framework', [ + 'test' => $this->getEnvironment() === 'test', + 'secret' => 'Pigeon', + ]); + + $contextDefinition = new Definition(FeatureContext::class, [new Parameter('kernel.environment')]); + $contextDefinition->setAutoconfigured(true); + $container->setDefinition(FeatureContext::class, $contextDefinition); + }); + } +} +CON + ); + } + /** * @Given /^a feature file containing(?: "([^"]+)"|:)$/ */ From 7250dfca7682ce3bb64e4f4c8cf891a4c63f5fd8 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 22:29:50 +0100 Subject: [PATCH 02/12] Get bare Behat scenario running --- .../injecting_parameters_into_context.feature | 11 +- features/running_bare_behat_scenarios.feature | 32 ++- src/ServiceContainer/SymfonyExtension.php | 29 +- tests/Behat/Context/TestContext.php | 263 +++++------------- 4 files changed, 118 insertions(+), 217 deletions(-) diff --git a/features/injecting_parameters_into_context.feature b/features/injecting_parameters_into_context.feature index a1d1086..a18e2f6 100644 --- a/features/injecting_parameters_into_context.feature +++ b/features/injecting_parameters_into_context.feature @@ -1,6 +1,7 @@ Feature: Injecting parameters into context Background: + Given a working Symfony application with SymfonyExtension configured Given a context file "features/bootstrap/FeatureContext.php" containing: """ registerSymfonyDriverFactory($extensionManager); + /** @var MinkExtension|null $minkExtension */ + $minkExtension = $extensionManager->getExtension('mink'); + if (null === $minkExtension) { + return; + } + + $minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID))); + $this->minkExtensionFound = true; } public function configure(ArrayNodeDefinition $builder): void @@ -75,8 +85,10 @@ final class SymfonyExtension implements Extension $this->loadEnvironmentHandler($container); - $this->loadMinkDefaultSession($container); - $this->loadMinkParameters($container); + if ($this->minkExtensionFound) { + $this->loadMinkDefaultSession($container); + $this->loadMinkParameters($container); + } } public function process(ContainerBuilder $container): void @@ -166,15 +178,4 @@ final class SymfonyExtension implements Extension $container->setDefinition('fob_symfony.mink.parameters', $minkParametersDefinition); } - - private function registerSymfonyDriverFactory(ExtensionManager $extensionManager): void - { - /** @var MinkExtension|null $minkExtension */ - $minkExtension = $extensionManager->getExtension('mink'); - if (null === $minkExtension) { - return; - } - - $minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID))); - } } diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index 4e72daf..b1a1cbb 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -59,13 +59,77 @@ final class TestContext implements Context self::$filesystem->remove(self::$workingDir); } + /** + * @Given a working Symfony application with SymfonyExtension configured + */ + public function workingSymfonyApplicationWithExtension(): void + { + $this->thereIsConfiguration(<<<'CON' +default: + extensions: + FriendsOfBehat\SymfonyExtension: + kernel: + class: App\Kernel +CON + ); + + $this->thereIsFile('vendor/autoload.php', sprintf(<<<'CON' +addPsr4('App\\', __DIR__ . '/../src/'); +$loader->addPsr4('App\\Tests\\', __DIR__ . '/../tests/'); + +return $loader; +CON + , __DIR__ . '/../../../vendor/autoload.php')); + + $this->thereIsFile('src/Kernel.php', <<<'CON' +load(function (ContainerBuilder $container): void { + $container->loadFromExtension('framework', [ + 'test' => $this->getEnvironment() === 'test', + 'secret' => 'Pigeon', + ]); + }); + + $loader->load(__DIR__ . '/../config/services.yaml'); + } +} +CON + ); + + $this->thereIsFile('config/services.yaml', ''); + } + /** * @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/ */ public function thereIsConfiguration($content): void { $mainConfigFile = sprintf('%s/behat.yml', self::$workingDir); - $newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5($content)); + $newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5((string) $content)); self::$filesystem->dumpFile($newConfigFile, (string) $content); @@ -79,21 +143,6 @@ final class TestContext implements Context self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration)); } - /** - * @Given /^a Behat configuration with the minimal working configuration for SymfonyExtension$/ - */ - public function thereIsConfigurationWithMinimalWorkingConfigurationForSymfonyExtension(): void - { - $this->thereIsConfiguration(<<<'CON' -default: - extensions: - FriendsOfBehat\SymfonyExtension: - kernel: - path: app/AppKernel.php - class: AppKernel -CON - ); - } /** * @Given /^a Behat configuration with the minimal working configuration for MinkExtension$/ @@ -121,84 +170,6 @@ CON self::$filesystem->dumpFile(self::$workingDir . '/' . $file, (string) $content); } - /** - * @Given /^an application kernel with the minimal working configuration for SymfonyExtension$/ - */ - public function thereIsKernelWithMinimalWorkingConfiguration(): void - { - $this->thereIsFile('app/AppKernel.php', <<<'CON' -load(function (ContainerBuilder $container): void { - $container->loadFromExtension('framework', [ - 'test' => $this->getEnvironment() === 'test', - 'secret' => 'Pigeon', - ]); - }); - } -} -CON - ); - } - - /** - * @Given /^an application kernel injecting a parameter into the FeatureContext class$/ - */ - public function thereIsKernelInjectingParameterIntoFeatureContextClass(): void - { - $this->thereIsFile('app/AppKernel.php', <<<'CON' -load(function (ContainerBuilder $container): void { - $container->loadFromExtension('framework', [ - 'test' => $this->getEnvironment() === 'test', - 'secret' => 'Pigeon', - ]); - - $contextDefinition = new Definition(FeatureContext::class, [new Parameter('kernel.environment')]); - $contextDefinition->setAutoconfigured(true); - $container->setDefinition(FeatureContext::class, $contextDefinition); - }); - } -} -CON - ); - } - /** * @Given /^a feature file containing(?: "([^"]+)"|:)$/ */ @@ -207,110 +178,6 @@ CON $this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content); } - /** - * @Given /^a feature file with passing scenario$/ - */ - public function thereIsFeatureFileWithPassingScenario(): void - { - $this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON' -thereIsFeatureFile(<<thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON' -thereIsFeatureFile(<<thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON' -thereIsFeatureFile(<<thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON' -thereIsFeatureFile(<< Date: Wed, 9 Jan 2019 22:35:57 +0100 Subject: [PATCH 03/12] Test injecting parameters --- .../injecting_parameters_into_context.feature | 76 ++++++++++--------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/features/injecting_parameters_into_context.feature b/features/injecting_parameters_into_context.feature index a18e2f6..2d7d67c 100644 --- a/features/injecting_parameters_into_context.feature +++ b/features/injecting_parameters_into_context.feature @@ -2,52 +2,60 @@ Feature: Injecting parameters into context Background: Given a working Symfony application with SymfonyExtension configured - Given a context file "features/bootstrap/FeatureContext.php" containing: - """ - parameter = $parameter; - } + final class SomeContext implements Context { + private $parameter; - /** - * @Then the parameter should be injected into the context - */ - public function behatContainerShouldBeInjectedToTheContext() - { - if (null === $this->parameter || empty($this->parameter)) { - throw new \DomainException('Required parameter was not injected!'); - } - } - } - """ - And an application kernel configured for SymfonyExtension with YAML services file containing: + public function __construct(?string $parameter = null) { $this->parameter = $parameter; } + + /** @Then the passed parameter should be :expected */ + public function parameterShouldBe(string $expected): void { assert($this->parameter === $expected); } + } + """ + + Scenario: Injecting a parameter into a context explicitly set as public + Given a services file "config/services.yaml" containing: """ services: - FeatureContext: - class: FeatureContext + App\Tests\SomeContext: public: true arguments: - "%kernel.environment%" """ - And a Behat configuration with the minimal working configuration for SymfonyExtension - And a Behat configuration with the minimal working configuration for MinkExtension + When I run Behat + Then it should pass - - Scenario: Injecting parameters into context with SymfonyExtension - Given a feature file "features/injecting_parameter_into_context.feature" containing: + Scenario: Injecting a parameter into an autoconfigured context + Given a services file "config/services.yaml" containing: """ - Feature: Injecting parameter into the context - Scenario: - Then the parameter should be injected into the context + services: + _defaults: + autoconfigure: true + + App\Tests\SomeContext: + arguments: + - "%kernel.environment%" """ When I run Behat Then it should pass From d4efe9a6df79d96bd7aa825ca99dcc81ed9f5386 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 22:37:18 +0100 Subject: [PATCH 04/12] Simplify services definition in Behat --- features/injecting_parameters_into_context.feature | 4 ++-- tests/Behat/Context/TestContext.php | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/features/injecting_parameters_into_context.feature b/features/injecting_parameters_into_context.feature index 2d7d67c..3d63e88 100644 --- a/features/injecting_parameters_into_context.feature +++ b/features/injecting_parameters_into_context.feature @@ -35,7 +35,7 @@ Feature: Injecting parameters into context """ Scenario: Injecting a parameter into a context explicitly set as public - Given a services file "config/services.yaml" containing: + Given a YAML services file containing: """ services: App\Tests\SomeContext: @@ -47,7 +47,7 @@ Feature: Injecting parameters into context Then it should pass Scenario: Injecting a parameter into an autoconfigured context - Given a services file "config/services.yaml" containing: + Given a YAML services file containing: """ services: _defaults: diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index b1a1cbb..f626634 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -123,6 +123,14 @@ CON $this->thereIsFile('config/services.yaml', ''); } + /** + * @Given /^a YAML services file containing:$/ + */ + public function yamlServicesFile($content): void + { + $this->thereIsFile('config/services.yaml', (string) $content); + } + /** * @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/ */ From 9cede4d612cdf7ab77faff98b5c40badc67950ca Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 22:40:32 +0100 Subject: [PATCH 05/12] Test injecting services --- .../injecting_services_into_context.feature | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 features/injecting_services_into_context.feature diff --git a/features/injecting_services_into_context.feature b/features/injecting_services_into_context.feature new file mode 100644 index 0000000..f8b60c7 --- /dev/null +++ b/features/injecting_services_into_context.feature @@ -0,0 +1,65 @@ +Feature: Injecting services into context + + Background: + Given a working Symfony application with SymfonyExtension configured + And a Behat configuration containing: + """ + default: + suites: + default: + contexts: + - App\Tests\SomeContext + """ + And a feature file containing: + """ + Feature: + Scenario: + Then the passed service should be an instance of "\Psr\Container\ContainerInterface" + """ + And a context file "tests/SomeContext.php" containing: + """ + service = $service; } + + /** @Then the passed service should be an instance of :expected */ + public function serviceShouldBe(string $expected): void + { + assert(is_object($this->service)); + assert($this->service instanceof $expected); + } + } + """ + + Scenario: Injecting a service into a context explicitly set as public + Given a YAML services file containing: + """ + services: + App\Tests\SomeContext: + public: true + arguments: + - "@service_container" + """ + When I run Behat + Then it should pass + + Scenario: Injecting a service into an autoconfigured context + Given a YAML services file containing: + """ + services: + _defaults: + autoconfigure: true + + App\Tests\SomeContext: + arguments: + - "@service_container" + """ + When I run Behat + Then it should pass From d5fcb25ef29e4f9b77149a9e9486a9a9ce4fc4b3 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 22:53:39 +0100 Subject: [PATCH 06/12] Test autowiring contexts --- features/autowiring_contexts.feature | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 features/autowiring_contexts.feature diff --git a/features/autowiring_contexts.feature b/features/autowiring_contexts.feature new file mode 100644 index 0000000..bcc2418 --- /dev/null +++ b/features/autowiring_contexts.feature @@ -0,0 +1,91 @@ +Feature: Autowiring contexts + + Background: + Given a working Symfony application with SymfonyExtension configured + And a Behat configuration containing: + """ + default: + suites: + default: + contexts: + - App\Tests\SomeContext + """ + + Scenario: Autowiring a context with a service + Given a feature file containing: + """ + Feature: + Scenario: + Then the container should be passed + """ + And a context file "tests/SomeContext.php" containing: + """ + container = $container; } + + /** @Then the container should be passed */ + public function containerShouldBePassed(): void + { + assert(is_object($this->container)); + assert($this->container instanceof ContainerInterface); + } + } + """ + And a YAML services file containing: + """ + services: + _defaults: + autowire: true + + App\Tests\SomeContext: + public: true + """ + When I run Behat + Then it should pass + + Scenario: Autowiring a context with a binding + Given a feature file containing: + """ + Feature: + Scenario: + Then the passed argument should be "KrzysztofKrawczyk" + """ + And a context file "tests/SomeContext.php" containing: + """ + argument = $argument; } + + /** @Then the passed argument should be :expected */ + public function passedArgumentShouldBe(string $expected): void { assert($this->argument === $expected); } + } + """ + And a YAML services file containing: + """ + services: + _defaults: + autowire: true + bind: + $argument: KrzysztofKrawczyk + + App\Tests\SomeContext: + public: true + """ + When I run Behat + Then it should pass From b4bcbb12334df457b80c8fa1e6070a8d899982fe Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 23:02:55 +0100 Subject: [PATCH 07/12] Test autowired & autoconfigured contexts --- features/autowiring_contexts.feature | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/features/autowiring_contexts.feature b/features/autowiring_contexts.feature index bcc2418..c6b9f40 100644 --- a/features/autowiring_contexts.feature +++ b/features/autowiring_contexts.feature @@ -89,3 +89,45 @@ Feature: Autowiring contexts """ When I run Behat Then it should pass + + Scenario: Autowiring and autoconfiguring context based on prototype + Given a feature file containing: + """ + Feature: + Scenario: + Then the container should be passed + """ + And a context file "tests/SomeContext.php" containing: + """ + container = $container; } + + /** @Then the container should be passed */ + public function containerShouldBePassed(): void + { + assert(is_object($this->container)); + assert($this->container instanceof ContainerInterface); + } + } + """ + And a YAML services file containing: + """ + services: + _defaults: + autowire: true + autoconfigure: true + + App\Tests\: + resource: '../tests/*' + """ + When I run Behat + Then it should pass From c8b0cbb205d8036db58149fd97535c7167c47a06 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 23:15:52 +0100 Subject: [PATCH 08/12] Test isolating contexts --- features/isolating_contexts.feature | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 features/isolating_contexts.feature diff --git a/features/isolating_contexts.feature b/features/isolating_contexts.feature new file mode 100644 index 0000000..6cfe6cd --- /dev/null +++ b/features/isolating_contexts.feature @@ -0,0 +1,54 @@ +Feature: Isolating contexts + + Scenario: Keeping contexts isolated between scenarios + Given a working Symfony application with SymfonyExtension configured + And a Behat configuration containing: + """ + default: + suites: + default: + contexts: + - App\Tests\SomeContext + """ + And a feature file containing: + """ + Feature: + Scenario: First scenario + Then the property should be "shit happens" + + Scenario: Second scenario + When I change the property to "shit does not happen" + Then the property should be "shit does not happen" + + Scenario: Third scenario + Then the property should be "shit happens" + """ + And a context file "tests/SomeContext.php" containing: + """ + container = $container; } + + /** @When I change the property to :value */ + public function changeProperty(string $value): void { $this->property = $value; } + + /** @Then the property should be :expected*/ + public function propertyShouldBe(string $expected): void { assert($this->property === $expected); } + } + """ + And a YAML services file containing: + """ + services: + App\Tests\SomeContext: + public: true + """ + When I run Behat + Then it should pass From 6061eaaf6280bca7b86a4c9a0df60208540b7d5f Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 23:47:24 +0100 Subject: [PATCH 09/12] Test Mink integration --- features/mink_integration.feature | 107 ++++++++++++++++++ ...riendsOfBehatSymfonyExtensionExtension.php | 3 + tests/Behat/Context/TestContext.php | 52 ++++----- 3 files changed, 133 insertions(+), 29 deletions(-) create mode 100644 features/mink_integration.feature diff --git a/features/mink_integration.feature b/features/mink_integration.feature new file mode 100644 index 0000000..7dad88e --- /dev/null +++ b/features/mink_integration.feature @@ -0,0 +1,107 @@ +Feature: Mink integration + + Background: + Given a working Symfony application with SymfonyExtension configured + And a Behat configuration containing: + """ + default: + extensions: + Behat\MinkExtension: + base_url: "http://localhost:8080/" + default_session: symfony + sessions: + symfony: + symfony: ~ + suites: + default: + contexts: + - App\Tests\SomeContext + """ + And a feature file containing: + """ + Feature: + Scenario: + When I visit the page "/hello-world" + Then I should see "Hello world!" on the page + And the base url from Mink parameters should be "http://localhost:8080/" + + # Doubling the scenario to account for some weird error connected to Mink's session + Scenario: + When I visit the page "/hello-world" + Then I should see "Hello world!" on the page + And the base url from Mink parameters should be "http://localhost:8080/" + """ + And a context file "tests/SomeContext.php" containing: + """ + session = $session; + $this->parameters = $minkParameters; + } + + /** @When I visit the page :page */ + public function visitPage(string $page): void + { + $this->session->visit($page); + } + + /** @Then I should see :content on the page */ + public function shouldSeeContentOnPage(string $content): void + { + assert(false !== strpos($this->session->getPage()->getContent(), $content)); + } + + /** @Then the base url from Mink parameters should be :expected */ + public function baseUrlShouldBe(string $expected): void + { + assert(isset($this->parameters['base_url'])); + assert($this->parameters['base_url'] === $expected); + } + } + """ + + Scenario: Injecting Mink session and Mink parameters + Given a YAML services file containing: + """ + services: + App\Tests\SomeContext: + public: true + arguments: + - '@behat.mink.default_session' + - '@behat.mink.parameters' + """ + When I run Behat + Then it should pass + + Scenario: Autowiring and autoconfiguring Mink session and Mink parameters + Given a YAML services file containing: + """ + services: + _defaults: + autowire: true + autoconfigure: true + + App\Tests\SomeContext: ~ + """ + When I run Behat + Then it should pass diff --git a/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php b/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php index 36091d1..6dc032f 100644 --- a/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php +++ b/src/Bundle/DependencyInjection/FriendsOfBehatSymfonyExtensionExtension.php @@ -24,6 +24,9 @@ final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements $container ->registerForAutoconfiguration(Context::class) ->addTag('fob.context') + ->setBindings([ + '$minkParameters' => new Reference('behat.mink.parameters'), + ]) ; } diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index f626634..95e91d9 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -91,13 +91,23 @@ CON namespace App; -use Symfony\Component\HttpKernel\Kernel as HttpKernel; -use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Kernel as HttpKernel; +use Symfony\Component\Routing\RouteCollectionBuilder; class Kernel extends HttpKernel { - public function registerBundles() + use MicroKernelTrait; + + public function helloWorld(): Response + { + return new Response('Hello world!'); + } + + public function registerBundles(): iterable { return [ new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), @@ -105,17 +115,20 @@ class Kernel extends HttpKernel ]; } - public function registerContainerConfiguration(LoaderInterface $loader) + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void { - $loader->load(function (ContainerBuilder $container): void { - $container->loadFromExtension('framework', [ - 'test' => $this->getEnvironment() === 'test', - 'secret' => 'Pigeon', - ]); - }); + $container->loadFromExtension('framework', [ + 'test' => $this->getEnvironment() === 'test', + 'secret' => 'Pigeon', + ]); $loader->load(__DIR__ . '/../config/services.yaml'); } + + protected function configureRoutes(RouteCollectionBuilder $routes) + { + $routes->add('/hello-world', 'kernel::helloWorld'); + } } CON ); @@ -151,25 +164,6 @@ CON self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration)); } - - /** - * @Given /^a Behat configuration with the minimal working configuration for MinkExtension$/ - */ - public function thereIsConfigurationWithMinimalWorkingConfigurationForMinkExtension(): void - { - $this->thereIsConfiguration(<<<'CON' -default: - extensions: - Behat\MinkExtension: - base_url: "http://localhost:8080/" - default_session: symfony - sessions: - symfony: - symfony: ~ -CON - ); - } - /** * @Given /^a (?:.+ |)file "([^"]+)" containing(?: "([^"]+)"|:)$/ */ From 05f4fe789f41e6c708a57779f9d44c6b0e134fda Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Wed, 9 Jan 2019 23:47:50 +0100 Subject: [PATCH 10/12] Apply coding standard fixes --- src/Driver/SymfonyDriver.php | 1 - tests/Behat/Context/TestContext.php | 30 +++++++---------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/Driver/SymfonyDriver.php b/src/Driver/SymfonyDriver.php index e2d1d26..a44c6de 100644 --- a/src/Driver/SymfonyDriver.php +++ b/src/Driver/SymfonyDriver.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace FriendsOfBehat\SymfonyExtension\Driver; use Behat\Mink\Driver\BrowserKitDriver; -use Symfony\Component\BrowserKit\Client; use Symfony\Component\HttpKernel\KernelInterface; final class SymfonyDriver extends BrowserKitDriver diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index 95e91d9..e660e75 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -12,24 +12,16 @@ use Symfony\Component\Yaml\Yaml; final class TestContext implements Context { - /** - * @var string - */ + /** @var string */ private static $workingDir; - /** - * @var Filesystem - */ + /** @var Filesystem */ private static $filesystem; - /** - * @var string - */ + /** @var string */ private static $phpBin; - /** - * @var Process - */ + /** @var Process */ private $process; /** @@ -201,7 +193,7 @@ CON } throw new \DomainException( - 'Behat was expecting to pass, but failed with the following output:' . PHP_EOL . PHP_EOL . $this->getProcessOutput() + 'Behat was expecting to pass, but failed with the following output:' . \PHP_EOL . \PHP_EOL . $this->getProcessOutput() ); } @@ -224,7 +216,7 @@ CON } throw new \DomainException( - 'Behat was expecting to fail, but passed with the following output:' . PHP_EOL . PHP_EOL . $this->getProcessOutput() + 'Behat was expecting to fail, but passed with the following output:' . \PHP_EOL . \PHP_EOL . $this->getProcessOutput() ); } @@ -260,16 +252,13 @@ CON if (0 === $result) { throw new \DomainException(sprintf( - 'Pattern "%s" does not match the following output:' . PHP_EOL . PHP_EOL . '%s', + 'Pattern "%s" does not match the following output:' . \PHP_EOL . \PHP_EOL . '%s', $pattern, $output )); } } - /** - * @return string - */ private function getProcessOutput(): string { $this->assertProcessIsAvailable(); @@ -277,9 +266,6 @@ CON return $this->process->getErrorOutput() . $this->process->getOutput(); } - /** - * @return int - */ private function getProcessExitCode(): int { $this->assertProcessIsAvailable(); @@ -298,8 +284,6 @@ CON } /** - * @return string - * * @throws \RuntimeException */ private static function findPhpBinary(): string From 4405596ca1068cbad56c5137a1bf057006ec3b75 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Thu, 10 Jan 2019 00:10:27 +0100 Subject: [PATCH 11/12] Make PHPStan passing --- phpstan.neon | 3 ++ .../ContextServiceEnvironmentHandler.php | 28 +++++++++++++------ src/Driver/SymfonyDriver.php | 13 ++++++++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 6802f22..d944ec3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,4 +2,7 @@ parameters: reportUnmatchedIgnoredErrors: false ignoreErrors: + - '/Cannot access offset 0 on callable\./' + - '/Cannot access offset 1 on callable\./' + - '/Method FriendsOfBehat\\SymfonyExtension\\Context\\Environment\\InitialisedContextServiceEnvironment::bindCallee\(\) should return callable/' - '/Cannot call method [a-zA-Z0-9]+\(\) on Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface|null\./' diff --git a/src/Context/Environment/Handler/ContextServiceEnvironmentHandler.php b/src/Context/Environment/Handler/ContextServiceEnvironmentHandler.php index d7e5d35..8792d85 100644 --- a/src/Context/Environment/Handler/ContextServiceEnvironmentHandler.php +++ b/src/Context/Environment/Handler/ContextServiceEnvironmentHandler.php @@ -60,11 +60,12 @@ final class ContextServiceEnvironmentHandler implements EnvironmentHandler } /** + * @param UninitialisedContextServiceEnvironment $uninitializedEnvironment + * * @throws EnvironmentIsolationException */ public function isolateEnvironment(Environment $uninitializedEnvironment, $testSubject = null): Environment { - /** @var UninitialisedContextServiceEnvironment $uninitializedEnvironment */ $this->assertEnvironmentCanBeIsolated($uninitializedEnvironment, $testSubject); $environment = new InitialisedContextServiceEnvironment($uninitializedEnvironment->getSuite()); @@ -136,22 +137,31 @@ final class ContextServiceEnvironmentHandler implements EnvironmentHandler return $class; } - throw new \Exception('wtf?'); + throw new \DomainException(sprintf('There is no service or class "%s".', $contextId)); } private function getContext(string $contextId): Context { - if ($this->getContainer()->has($contextId)) { - return $this->getContainer()->get($contextId); - } - $class = '\\' . ltrim($contextId, '\\'); - if (class_exists($class)) { - return new $class(); + if ($this->getContainer()->has($contextId)) { + $context = $this->getContainer()->get($contextId); + } elseif (class_exists($class)) { + $context = new $class(); + } else { + throw new \DomainException(sprintf('There is no service or class "%s".', $contextId)); } - throw new \Exception('wtf?'); + if (!$context instanceof Context) { + throw new \DomainException(sprintf( + 'Context "%s" referenced as "%s" needs to implement "%s".', + get_class($context), + $contextId, + Context::class + )); + } + + return $context; } private function getContainer(): ContainerInterface diff --git a/src/Driver/SymfonyDriver.php b/src/Driver/SymfonyDriver.php index a44c6de..dbbc18a 100644 --- a/src/Driver/SymfonyDriver.php +++ b/src/Driver/SymfonyDriver.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace FriendsOfBehat\SymfonyExtension\Driver; use Behat\Mink\Driver\BrowserKitDriver; +use Symfony\Component\BrowserKit\Client; use Symfony\Component\HttpKernel\KernelInterface; final class SymfonyDriver extends BrowserKitDriver @@ -21,6 +22,16 @@ final class SymfonyDriver extends BrowserKitDriver )); } - parent::__construct($kernel->getContainer()->get('test.client'), $baseUrl); + $testClient = $kernel->getContainer()->get('test.client'); + + if (!$testClient instanceof Client) { + throw new \RuntimeException(sprintf( + 'Service "test.client" should be an instance of "%s", "%s" given.', + Client::class, + get_class($testClient) + )); + } + + parent::__construct($testClient, $baseUrl); } } From 85796e2fef32e3b2b3029f862078eef0902b22c8 Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Thu, 10 Jan 2019 00:18:46 +0100 Subject: [PATCH 12/12] Fix build on Symfony 3.4 --- tests/Behat/Context/TestContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Behat/Context/TestContext.php b/tests/Behat/Context/TestContext.php index e660e75..1398c1f 100644 --- a/tests/Behat/Context/TestContext.php +++ b/tests/Behat/Context/TestContext.php @@ -119,7 +119,7 @@ class Kernel extends HttpKernel protected function configureRoutes(RouteCollectionBuilder $routes) { - $routes->add('/hello-world', 'kernel::helloWorld'); + $routes->add('/hello-world', 'kernel:helloWorld'); } } CON