Skip to content
This repository was archived by the owner on Apr 29, 2025. It is now read-only.

Commit 815ec1f

Browse files
committed
Merge pull request #70 from Behat/feature/service-injection
Application service injection
2 parents e461dc3 + f1f18c9 commit 815ec1f

File tree

6 files changed

+146
-3
lines changed

6 files changed

+146
-3
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace spec\Behat\Symfony2Extension\Context\Argument;
4+
5+
use PhpSpec\ObjectBehavior;
6+
use Prophecy\Argument;
7+
use ReflectionClass;
8+
use stdClass;
9+
use Symfony\Component\DependencyInjection\ContainerInterface;
10+
use Symfony\Component\HttpKernel\KernelInterface;
11+
12+
class ServiceArgumentResolverSpec extends ObjectBehavior
13+
{
14+
function let(KernelInterface $kernel, ContainerInterface $container)
15+
{
16+
$kernel->getContainer()->willReturn($container);
17+
18+
$this->beConstructedWith($kernel);
19+
}
20+
21+
function it_resolves_arguments_starting_from_at_sign_if_they_point_to_existing_service(
22+
ReflectionClass $reflectionClass,
23+
ContainerInterface $container
24+
) {
25+
$container->has('service')->willReturn(true);
26+
$container->get('service')->willReturn($service = new stdClass());
27+
28+
$this->resolveArguments($reflectionClass, array('service' => '@service'))->shouldReturn(
29+
array('service' => $service)
30+
);
31+
}
32+
33+
function it_does_not_resolve_arguments_starting_from_at_sign_if_they_do_not_point_to_existing_service(
34+
ReflectionClass $reflectionClass,
35+
ContainerInterface $container
36+
) {
37+
$container->has('service')->willReturn(false);
38+
$container->get(Argument::any())->shouldNotBeCalled();
39+
40+
$this->resolveArguments($reflectionClass, array('service' => '@service'))->shouldReturn(
41+
array('service' => '@service')
42+
);
43+
}
44+
45+
function it_does_not_resolve_arguments_not_starting_from_at_sign(
46+
ReflectionClass $reflectionClass,
47+
ContainerInterface $container
48+
) {
49+
$container->get(Argument::any())->shouldNotBeCalled();
50+
51+
$this->resolveArguments($reflectionClass, array('service' => 'my_service'))->shouldReturn(
52+
array('service' => 'my_service')
53+
);
54+
}
55+
}

spec/Behat/Symfony2Extension/Context/Initializer/KernelAwareInitializerSpec.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function it_is_an_event_subscriber()
2626

2727
function it_subscribes_to_events()
2828
{
29-
$this->getSubscribedEvents()->shouldHaveCount(4);
29+
$this->getSubscribedEvents()->shouldHaveCount(2);
3030
}
3131

3232
function it_does_nothing_for_non_kernel_aware_contexts(Context $context)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Behat Symfony2Extension
5+
*
6+
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*/
11+
12+
namespace Behat\Symfony2Extension\Context\Argument;
13+
14+
use Behat\Behat\Context\Argument\ArgumentResolver;
15+
use ReflectionClass;
16+
use Symfony\Component\HttpKernel\KernelInterface;
17+
18+
/**
19+
* Resolves service arguments using the application container.
20+
*
21+
* @author Konstantin Kudryashov <ever.zet@gmail.com>
22+
*/
23+
final class ServiceArgumentResolver implements ArgumentResolver
24+
{
25+
private $kernel;
26+
27+
/**
28+
* Initializes resolver.
29+
*
30+
* @param KernelInterface $kernel
31+
*/
32+
public function __construct(KernelInterface $kernel)
33+
{
34+
$this->kernel = $kernel;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function resolveArguments(ReflectionClass $classReflection, array $arguments)
41+
{
42+
$newArguments = array();
43+
44+
foreach ($arguments as $key => $argument) {
45+
$newArguments[$key] = $this->resolveArgument($argument);
46+
}
47+
48+
return $newArguments;
49+
}
50+
51+
/**
52+
* Resolves single argument using container.
53+
*
54+
* @param mixed $argument
55+
*
56+
* @return object
57+
*/
58+
private function resolveArgument($argument)
59+
{
60+
$container = $this->kernel->getContainer();
61+
62+
if (!is_string($argument) || '@' != $argument[0]) {
63+
return $argument;
64+
}
65+
66+
$serviceId = mb_substr($argument, 1, mb_strlen($argument, 'utf8'), 'utf8');
67+
68+
return $container->has($serviceId) ? $container->get($serviceId) : $argument;
69+
}
70+
}

src/Behat/Symfony2Extension/ServiceContainer/Symfony2Extension.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function load(ContainerBuilder $container, array $config)
106106
$this->loadFeatureLocator($container);
107107
$this->loadKernel($container, $config['kernel']);
108108
$this->loadSuiteGenerator($container, $config['context']);
109+
$this->loadServiceArgumentResolver($container);
109110
}
110111

111112
/**
@@ -186,4 +187,13 @@ private function loadSuiteGenerator(ContainerBuilder $container, array $config)
186187
$definition->addTag(SuiteExtension::GENERATOR_TAG, array('priority' => 100));
187188
$container->setDefinition('symfony2_extension.suite.generator', $definition);
188189
}
190+
191+
private function loadServiceArgumentResolver(ContainerBuilder $container)
192+
{
193+
$definition = new Definition('Behat\Symfony2Extension\Context\Argument\ServiceArgumentResolver', array(
194+
new Reference(self::KERNEL_ID)
195+
));
196+
$definition->addTag(ContextExtension::ARGUMENT_RESOLVER_TAG, array('priority' => 0));
197+
$container->setDefinition('symfony2_extension.context.argument.service_resolver', $definition);
198+
}
189199
}

testapp/behat.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ default:
1717
tags: '~@web'
1818
web:
1919
type: symfony_bundle
20-
contexts: ['Behat\Sf2DemoBundle\Features\Context\WebContext']
20+
contexts:
21+
- Behat\Sf2DemoBundle\Features\Context\WebContext:
22+
simpleArg: 'string'
23+
session: @session
2124
bundle: 'BehatSf2DemoBundle'
2225
filters:
2326
tags: '@web'

testapp/src/Behat/Sf2DemoBundle/Features/Context/WebContext.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
namespace Behat\Sf2DemoBundle\Features\Context;
44

55
use Behat\MinkExtension\Context\MinkContext;
6-
use Symfony\Component\HttpKernel\KernelInterface;
76
use Behat\Symfony2Extension\Context\KernelAwareContext;
7+
use Symfony\Component\HttpFoundation\Session\Session;
8+
use Symfony\Component\HttpKernel\KernelInterface;
89

910
class WebContext extends MinkContext implements KernelAwareContext
1011
{
1112
private $kernel;
1213

14+
public function __construct(Session $session, $simpleArg)
15+
{
16+
}
17+
1318
/**
1419
* Sets HttpKernel instance.
1520
* This method will be automatically called by Symfony2Extension ContextInitializer.

0 commit comments

Comments
 (0)