Completed
Push — master ( c25c8e...44516d )
by Kevin
06:39
created

Initializer::initLoggingExecutor()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
namespace Magium\TestCase;
4
5
use Facebook\WebDriver\Remote\RemoteWebDriver;
6
use Interop\Container\ContainerInterface;
7
use Magium\AbstractTestCase;
8
use Magium\InvalidConfigurationException;
9
use Magium\TestCaseConfiguration;
10
use Magium\Util\Configuration\ConfigurationCollector\DefaultPropertyCollector;
11
use Magium\Util\Configuration\ConfigurationProviderInterface;
12
use Magium\Util\Configuration\StandardConfigurationProvider;
13
use Magium\Util\Log\Logger;
14
use Magium\Util\Log\LoggerInterface;
15
use Magium\Util\Log\LoggerPHPUnit5;
16
use Magium\Util\Phpunit\MasterListenerInterface;
17
use Magium\Util\TestCase\RegistrationListener;
18
use Magium\WebDriver\LoggingRemoteExecuteMethod;
19
use Magium\WebDriver\WebDriver;
20
use Zend\Di\Config;
21
use Zend\Di\Di;
22
use Zend\I18n\Translator\Translator;
23
use Zend\Log\Writer\Noop;
24
25
class Initializer
26
{
27
28
    protected $testCaseConfiguration = 'Magium\TestCaseConfiguration';
29
    protected $testCaseConfigurationObject;
30
    protected $initialized;
31
    protected $configurationProvider;
32
    protected static $initDi;
33
34
    public function __construct(
35
        $testCaseConfigurationType = null,
36
        TestCaseConfiguration $object = null,
37
        ConfigurationProviderInterface $configurationProvider = null
38
    )
39
    {
40
        if ($testCaseConfigurationType !== null) {
41
            $this->testCaseConfiguration = $testCaseConfigurationType;
42
        }
43
        if ($object instanceof TestCaseConfiguration) {
44
            $this->testCaseConfigurationObject = $object;
45
        }
46
47
        $this->configurationProvider = $configurationProvider;
48
        if (!$this->configurationProvider instanceof ConfigurationProviderInterface) {
49
            $preference = self::getInitializationDependencyInjectionContainer()->instanceManager()->getTypePreferences(ConfigurationProviderInterface::class);
50
            if (is_array($preference) && count($preference)) {
51
                $preference = array_shift($preference);
52
            } else {
53
                $preference = StandardConfigurationProvider::class;
54
            }
55
            $this->configurationProvider = self::getInitializationDependencyInjectionContainer()->get($preference);
56
        }
57
    }
58
59
    public static function setInitializationDependencyInjectionContainer(ContainerInterface $container)
60
    {
61
        self::$initDi = $container;
62
    }
63
64
    /**
65
     * This method returns a DI container that will ONLY be used to initialize this class
66
     *
67
     * @return Di
68
     */
69
70
    public static function getInitializationDependencyInjectionContainer()
71
    {
72
        if (!self::$initDi instanceof Di) {
73
            self::$initDi = new Di();
74
            self::$initDi->instanceManager()->addTypePreference(ConfigurationProviderInterface::class, StandardConfigurationProvider::class);
75
        }
76
        return self::$initDi;
77
    }
78
79
    protected function injectTestCaseHierarchy(AbstractTestCase $testCase)
80
    {
81
        $rc = new \ReflectionClass($testCase);
82
        while ($rc->getParentClass()) {
83
            $class = $rc->getParentClass()->getName();
84
            $testCase->getDi()->instanceManager()->addSharedInstance($testCase, $class);
85
            $rc = new \ReflectionClass($class);
86
        }
87
    }
88
89
    protected function configureWebDriver(AbstractTestCase $testCase)
90
    {
91
        $webDriver = $testCase->getDi()->get('Magium\WebDriver\WebDriver');
92
        if ($webDriver instanceof WebDriver) {
93
            $testCase->setWebdriver($webDriver);
94
            $testCase->setTypePreference(
95
                \Facebook\WebDriver\WebDriver::class,
96
                \Magium\WebDriver\WebDriver::class
97
            );
98
            $testCase->setTypePreference(
99
                RemoteWebDriver::class,
100
                \Magium\WebDriver\WebDriver::class
101
            );
102
        } else {
103
            throw new InvalidConfigurationException('DIC has misconfigured WebDriver object');
104
        }
105
    }
106
107
    protected function initLoggingExecutor(AbstractTestCase $testCase)
108
    {
109
        $remote = $testCase->getDi()->get(LoggingRemoteExecuteMethod::class);
110
        if ($remote instanceof LoggingRemoteExecuteMethod) {
111
            $testCase->getWebdriver()->setRemoteExecuteMethod($remote);
112
        } else {
113
            throw new InvalidConfigurationException('DIC has invalid logger configured');
114
        }
115
    }
116
117
    protected function executeCallbacks(AbstractTestCase $testCase)
118
    {
119
        RegistrationListener::executeCallbacks($testCase);
120
    }
121
122
    protected function setCharacteristics(AbstractTestCase $testCase)
123
    {
124
        $testCase->getLogger()->addCharacteristic(LoggerInterface::CHARACTERISTIC_BROWSER, $testCase->getWebdriver()->getBrowser());
125
        $testCase->getLogger()->addCharacteristic(LoggerInterface::CHARACTERISTIC_OPERATING_SYSTEM, $testCase->getWebdriver()->getPlatform());
126
    }
127
128
    protected function attachMasterListener(AbstractTestCase $testCase)
129
    {
130
        $masterListener = AbstractTestCase::getMasterListener();
131
        $testCase->getDi()->instanceManager()->addSharedInstance($masterListener, MasterListenerInterface::class);
132
    }
133
134
    public function initialize(AbstractTestCase $testCase, $force = false)
135
    {
136
        if ($this->initialized === $testCase && !$force) {
137
            return;
138
        }
139
        $this->configureDi($testCase);
140
        $this->attachMasterListener($testCase);
141
        $this->injectTestCaseHierarchy($testCase);
142
        $this->configureWebDriver($testCase);
143
        $this->initLoggingExecutor($testCase);
144
        $this->executeCallbacks($testCase);
145
        $this->setCharacteristics($testCase);
146
        $this->initialized = $testCase;
147
    }
148
149
    protected function getDefaultConfiguration()
150
    {
151
        // Choose the correct logger/listener for the version of PHPUnit being used
152
        $loggerClass = class_exists('PHPUnit_Framework_TestCase')?LoggerPHPUnit5::class:Logger::class;
153
154
        return [
155
            'definition' => [
156
                'class' => [
157
                    'Magium\WebDriver\WebDriver' => [
158
                        'instantiator' => 'Magium\WebDriver\WebDriverFactory::create'
159
                    ],
160
161
                    'Magium\WebDriver\WebDriverFactory' => [
162
                        'create'       => $this->testCaseConfigurationObject->getWebDriverConfiguration()
163
                    ]
164
                ]
165
            ],
166
            'instance'  => [
167
                'preference' => [
168
                    Translator::class => [\Magium\Util\Translator\Translator::class],
169
                    \Zend\Log\LoggerInterface::class => [$loggerClass],
170
                    LoggerInterface::class => [$loggerClass],
171
                ],
172
                'Magium\Util\Translator\Translator' => [
173
                    'parameters'    => [
174
                        'locale'    => 'en_US'
175
                    ]
176
                ],
177
                $loggerClass   => [
178
                    'parameters'    => [
179
                        'options'   => [
180
                            'writers' => [
181
                                [
182
                                    'name' => Noop::class,
183
                                    'options' => []
184
                                ]
185
                            ]
186
                        ]
187
                    ]
188
                ]
189
            ]
190
        ];
191
    }
192
193
    public function configureDi(AbstractTestCase $testCase)
194
    {
195
196
        if (!$this->testCaseConfigurationObject instanceof TestCaseConfiguration) {
197
            if ($testCase->getDi() instanceof Di) {
198
199
                $testCaseConfiguration = $testCase->get($this->testCaseConfiguration);
200
                if ($testCaseConfiguration instanceof TestCaseConfiguration) {
201
                    $this->testCaseConfigurationObject = $testCaseConfiguration;
202
                }
203
            } else {
204
                $this->testCaseConfigurationObject = new $this->testCaseConfiguration(
205
                    $this->configurationProvider
206
                    , new DefaultPropertyCollector()
207
                );
208
            }
209
        }
210
        if ($testCase->getDi() instanceof Di) {
211
            return;
212
        }
213
        /* @var $configuration TestCaseConfiguration */
214
        $configArray = $this->getDefaultConfiguration();
215
216
        $count = 0;
217
218
        $path = realpath(__DIR__ . '/../');
219
220
        while ($count++ < 5) {
221
            $dir = "{$path}/configuration/";
222
            if (is_dir($dir)) {
223
                foreach (glob($dir . '*.php') as $file) {
224
                    $configArray = array_merge_recursive($configArray, include $file);
225
                }
226
                break;
227
            }
228
            $path .= '/../';
229
        }
230
231
232
        $configArray = $this->testCaseConfigurationObject->reprocessConfiguration($configArray);
233
        $configuration = new Config($configArray);
234
235
        $di = new Di();
236
        $configuration->configure($di);
237
        $testCase->setDi($di);
238
        $di->instanceManager()->addSharedInstance($di, Di::class);
239
240
        $this->setConfigurationProvider($testCase);
241
    }
242
243
    public function setConfigurationProvider(AbstractTestCase $testCase)
244
    {
245
        $configuredProvider = self::getInitializationDependencyInjectionContainer()->instanceManager()->getTypePreferences(ConfigurationProviderInterface::class);
246
        if (is_array($configuredProvider) && count($configuredProvider)) {
247
            $configuredProvider = array_shift($configuredProvider);
248
        } else {
249
            $configuredProvider = StandardConfigurationProvider::class;
250
        }
251
        $testCase->setTypePreference(
252
            ConfigurationProviderInterface::class,
253
            $configuredProvider
254
        );
255
        $this->configurationProvider->configureDi($testCase->getDi());
256
257
    }
258
259
}
260