From 4056cba2e99c7acf449216c3b3d0ba0c038880e3 Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:24:07 +0100 Subject: [PATCH 1/7] Describe new feature - injecting application service into context constructor --- testapp/behat.yml | 5 ++++- .../Behat/Sf2DemoBundle/Features/Context/WebContext.php | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/testapp/behat.yml b/testapp/behat.yml index 370b0ae..a8e2956 100644 --- a/testapp/behat.yml +++ b/testapp/behat.yml @@ -17,7 +17,10 @@ default: tags: '~@web' web: type: symfony_bundle - contexts: ['Behat\Sf2DemoBundle\Features\Context\WebContext'] + contexts: + - Behat\Sf2DemoBundle\Features\Context\WebContext: + simpleArg: 'string' + session: @session bundle: 'BehatSf2DemoBundle' filters: tags: '@web' diff --git a/testapp/src/Behat/Sf2DemoBundle/Features/Context/WebContext.php b/testapp/src/Behat/Sf2DemoBundle/Features/Context/WebContext.php index fb55a99..8829473 100644 --- a/testapp/src/Behat/Sf2DemoBundle/Features/Context/WebContext.php +++ b/testapp/src/Behat/Sf2DemoBundle/Features/Context/WebContext.php @@ -3,13 +3,18 @@ namespace Behat\Sf2DemoBundle\Features\Context; use Behat\MinkExtension\Context\MinkContext; -use Symfony\Component\HttpKernel\KernelInterface; use Behat\Symfony2Extension\Context\KernelAwareContext; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpKernel\KernelInterface; class WebContext extends MinkContext implements KernelAwareContext { private $kernel; + public function __construct(Session $session, $simpleArg) + { + } + /** * Sets HttpKernel instance. * This method will be automatically called by Symfony2Extension ContextInitializer. From e7037f0bf20a476651d94ae16818c431d9bc759d Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:30:19 +0100 Subject: [PATCH 2/7] Describe ServiceArgumentResolver and its behaviour --- .../Argument/ServiceArgumentResolverSpec.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php diff --git a/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php b/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php new file mode 100644 index 0000000..d5031dd --- /dev/null +++ b/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php @@ -0,0 +1,54 @@ +getContainer()->willReturn($container); + + $this->beConstructedWith($kernel); + } + + function it_resolves_arguments_starting_from_at_sign_if_they_point_to_existing_service( + ReflectionClass $reflectionClass, ContainerInterface $container, stdClass $service + ) { + $container->has('service')->willReturn(true); + $container->get('service')->willReturn($service); + + $this->resolveArguments($reflectionClass, array('service' => '@service'))->shouldReturn( + array('service' => $service) + ); + } + + function it_does_not_resolve_arguments_starting_from_at_sign_if_they_do_not_point_to_existing_service( + ReflectionClass $reflectionClass, + ContainerInterface $container + ) { + $container->has('service')->willReturn(false); + $container->get(Argument::any())->shouldNotBeCalled(); + + $this->resolveArguments($reflectionClass, array('service' => '@service'))->shouldReturn( + array('service' => '@service') + ); + } + + function it_does_not_resolve_arguments_not_starting_from_at_sign( + ReflectionClass $reflectionClass, + ContainerInterface $container + ) { + $container->get(Argument::any())->shouldNotBeCalled(); + + $this->resolveArguments($reflectionClass, array('service' => 'my_service'))->shouldReturn( + array('service' => 'my_service') + ); + } +} From 0d9188016c77a0a06d6ee6dffa6855c5ce4b5d1f Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:30:35 +0100 Subject: [PATCH 3/7] Implement ServiceArgumentResolver --- .../Argument/ServiceArgumentResolver.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php diff --git a/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php new file mode 100644 index 0000000..0a28e36 --- /dev/null +++ b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php @@ -0,0 +1,70 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Behat\Symfony2Extension\Context\Argument; + +use Behat\Behat\Context\Argument\ArgumentResolver; +use ReflectionClass; +use Symfony\Component\HttpKernel\KernelInterface; + +/** + * Resolves service arguments using the application container. + * + * @author Konstantin Kudryashov + */ +final class ServiceArgumentResolver implements ArgumentResolver +{ + private $kernel; + + /** + * Initializes resolver. + * + * @param KernelInterface $kernel + */ + public function __construct(KernelInterface $kernel) + { + $this->kernel = $kernel; + } + + /** + * {@inheritdoc} + */ + public function resolveArguments(ReflectionClass $classReflection, array $arguments) + { + $newArguments = $arguments; + + foreach ($arguments as $key => $argument) { + $newArguments[$key] = $this->resolveArgument($argument); + } + + return $newArguments; + } + + /** + * Resolves single argument using container. + * + * @param mixed $argument + * + * @return object + */ + private function resolveArgument($argument) + { + $container = $this->kernel->getContainer(); + + if (!is_string($argument) || '@' != $argument[0]) { + return $argument; + } + + $serviceId = mb_substr($argument, 1, null, 'utf8'); + + return $container->has($serviceId) ? $container->get($serviceId) : $argument; + } +} From 72f5a273e766c5afd1c9a66db5a225f8f3fde91c Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:31:54 +0100 Subject: [PATCH 4/7] Fix failing KernelAwareInitializerSpec --- .../Context/Initializer/KernelAwareInitializerSpec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Behat/Symfony2Extension/Context/Initializer/KernelAwareInitializerSpec.php b/spec/Behat/Symfony2Extension/Context/Initializer/KernelAwareInitializerSpec.php index 1de0ccb..bff7166 100644 --- a/spec/Behat/Symfony2Extension/Context/Initializer/KernelAwareInitializerSpec.php +++ b/spec/Behat/Symfony2Extension/Context/Initializer/KernelAwareInitializerSpec.php @@ -26,7 +26,7 @@ function it_is_an_event_subscriber() function it_subscribes_to_events() { - $this->getSubscribedEvents()->shouldHaveCount(4); + $this->getSubscribedEvents()->shouldHaveCount(2); } function it_does_nothing_for_non_kernel_aware_contexts(Context $context) From 6462ea70277e3ca11d4eb0c6c8db4e7cd5dc3193 Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:32:17 +0100 Subject: [PATCH 5/7] Register ServiceArgumentResolver in the extension --- .../ServiceContainer/Symfony2Extension.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Behat/Symfony2Extension/ServiceContainer/Symfony2Extension.php b/src/Behat/Symfony2Extension/ServiceContainer/Symfony2Extension.php index 27e88d3..dffbfd6 100644 --- a/src/Behat/Symfony2Extension/ServiceContainer/Symfony2Extension.php +++ b/src/Behat/Symfony2Extension/ServiceContainer/Symfony2Extension.php @@ -106,6 +106,7 @@ public function load(ContainerBuilder $container, array $config) $this->loadFeatureLocator($container); $this->loadKernel($container, $config['kernel']); $this->loadSuiteGenerator($container, $config['context']); + $this->loadServiceArgumentResolver($container); } /** @@ -186,4 +187,13 @@ private function loadSuiteGenerator(ContainerBuilder $container, array $config) $definition->addTag(SuiteExtension::GENERATOR_TAG, array('priority' => 100)); $container->setDefinition('symfony2_extension.suite.generator', $definition); } + + private function loadServiceArgumentResolver(ContainerBuilder $container) + { + $definition = new Definition('Behat\Symfony2Extension\Context\Argument\ServiceArgumentResolver', array( + new Reference(self::KERNEL_ID) + )); + $definition->addTag(ContextExtension::ARGUMENT_RESOLVER_TAG, array('priority' => 0)); + $container->setDefinition('symfony2_extension.context.argument.service_resolver', $definition); + } } From f3a03955762d8100d8e9e7b6c4c191efb02d6328 Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 22:47:18 +0100 Subject: [PATCH 6/7] Cleanup ServiceArgumentResolver --- .../Context/Argument/ServiceArgumentResolverSpec.php | 5 +++-- .../Context/Argument/ServiceArgumentResolver.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php b/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php index d5031dd..5ad0308 100644 --- a/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php +++ b/spec/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolverSpec.php @@ -19,10 +19,11 @@ function let(KernelInterface $kernel, ContainerInterface $container) } function it_resolves_arguments_starting_from_at_sign_if_they_point_to_existing_service( - ReflectionClass $reflectionClass, ContainerInterface $container, stdClass $service + ReflectionClass $reflectionClass, + ContainerInterface $container ) { $container->has('service')->willReturn(true); - $container->get('service')->willReturn($service); + $container->get('service')->willReturn($service = new stdClass()); $this->resolveArguments($reflectionClass, array('service' => '@service'))->shouldReturn( array('service' => $service) diff --git a/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php index 0a28e36..b115ac6 100644 --- a/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php +++ b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php @@ -39,7 +39,7 @@ public function __construct(KernelInterface $kernel) */ public function resolveArguments(ReflectionClass $classReflection, array $arguments) { - $newArguments = $arguments; + $newArguments = array(); foreach ($arguments as $key => $argument) { $newArguments[$key] = $this->resolveArgument($argument); From f1f18c90a12b0521dc845e780f2ec2574b7492b4 Mon Sep 17 00:00:00 2001 From: everzet Date: Thu, 4 Sep 2014 23:03:28 +0100 Subject: [PATCH 7/7] Fix bug in php 5.3 --- .../Context/Argument/ServiceArgumentResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php index b115ac6..7aa9ed0 100644 --- a/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php +++ b/src/Behat/Symfony2Extension/Context/Argument/ServiceArgumentResolver.php @@ -63,7 +63,7 @@ private function resolveArgument($argument) return $argument; } - $serviceId = mb_substr($argument, 1, null, 'utf8'); + $serviceId = mb_substr($argument, 1, mb_strlen($argument, 'utf8'), 'utf8'); return $container->has($serviceId) ? $container->get($serviceId) : $argument; }