Completed
Push — master ( 531aca...edc713 )
by Kamil
04:19
created

isolateEnvironment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the ContextServiceExtension package.
5
 *
6
 * (c) FriendsOfBehat
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FriendsOfBehat\ContextServiceExtension\Context\Environment\Handler;
13
14
use Behat\Behat\Context\Context;
15
use Behat\Testwork\Environment\Environment;
16
use Behat\Testwork\Environment\Exception\EnvironmentIsolationException;
17
use Behat\Testwork\Environment\Handler\EnvironmentHandler;
18
use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
19
use Behat\Testwork\Suite\Suite;
20
use FriendsOfBehat\ContextServiceExtension\Context\ContextRegistry;
21
use FriendsOfBehat\ContextServiceExtension\Context\Environment\InitialisedContextServiceEnvironment;
22
use FriendsOfBehat\ContextServiceExtension\Context\Environment\UninitialisedContextServiceEnvironment;
23
use Symfony\Component\DependencyInjection\ContainerInterface;
24
25
/**
26
 * @internal
27
 */
28
final class ContextServiceEnvironmentHandler implements EnvironmentHandler
29
{
30
    /**
31
     * @var ContainerInterface
32
     */
33
    private $container;
34
35
    /**
36
     * @var ContextRegistry
37
     */
38
    private $contextRegistry;
39
40
    /**
41
     * @param ContainerInterface $container
42
     * @param ContextRegistry $contextRegistry
43
     */
44
    public function __construct(ContainerInterface $container, ContextRegistry $contextRegistry)
45
    {
46
        $this->container = $container;
47
        $this->contextRegistry = $contextRegistry;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function supportsSuite(Suite $suite)
54
    {
55
        return $suite->hasSetting('contexts_services');
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function buildEnvironment(Suite $suite)
62
    {
63
        $environment = new UninitialisedContextServiceEnvironment($suite);
64
        foreach ($this->getSuiteContextsServices($suite) as $serviceId) {
65
            $environment->registerContextService($serviceId, $this->contextRegistry->getClass($serviceId));
66
        }
67
68
        return $environment;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function supportsEnvironmentAndSubject(Environment $environment, $testSubject = null)
75
    {
76
        return $environment instanceof UninitialisedContextServiceEnvironment;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     *
82
     * @throws EnvironmentIsolationException
83
     */
84
    public function isolateEnvironment(Environment $uninitializedEnvironment, $testSubject = null)
85
    {
86
        /** @var UninitialisedContextServiceEnvironment $uninitializedEnvironment */
87
        $this->assertEnvironmentCanBeIsolated($uninitializedEnvironment, $testSubject);
88
89
        $environment = new InitialisedContextServiceEnvironment($uninitializedEnvironment->getSuite());
90
        foreach ($uninitializedEnvironment->getContextServices() as $serviceId) {
91
            /** @var Context $context */
92
            $context = $this->container->get($serviceId);
93
            $environment->registerContext($context);
94
        }
95
96
        return $environment;
97
    }
98
99
    /**
100
     * @param Suite $suite
101
     *
102
     * @return string[]
103
     *
104
     * @throws SuiteConfigurationException If "contexts_services" setting is not an array
105
     */
106
    private function getSuiteContextsServices(Suite $suite)
107
    {
108
        $contextsServices = $suite->getSetting('contexts_services');
109
110
        if (!is_array($contextsServices)) {
111
            throw new SuiteConfigurationException(sprintf(
112
                '"contexts_services" setting of the "%s" suite is expected to be an array, %s given.',
113
                $suite->getName(),
114
                gettype($contextsServices)
115
            ), $suite->getName());
116
        }
117
118
        return $contextsServices;
119
    }
120
121
    /**
122
     * @param Environment $uninitializedEnvironment
123
     * @param mixed $testSubject
124
     *
125
     * @throws EnvironmentIsolationException
126
     */
127
    private function assertEnvironmentCanBeIsolated(Environment $uninitializedEnvironment, $testSubject)
128
    {
129
        if (!$this->supportsEnvironmentAndSubject($uninitializedEnvironment, $testSubject)) {
130
            throw new EnvironmentIsolationException(sprintf(
131
                '"%s" does not support isolation of "%s" environment.',
132
                static::class,
133
                get_class($uninitializedEnvironment)
134
            ), $uninitializedEnvironment);
135
        }
136
    }
137
}
138