Passed
Push — master ( 492f4c...0725f5 )
by Jakub
02:01
created

MyTesterExtension::loadConfiguration()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 9
Bugs 0 Features 3
Metric Value
cc 3
eloc 13
c 9
b 0
f 3
nc 3
nop 0
dl 0
loc 16
ccs 12
cts 13
cp 0.9231
crap 3.004
rs 9.8333
1
<?php
2
declare(strict_types=1);
3
4
namespace MyTester\Bridges\NetteDI;
5
6
use Exception;
7
use MyTester\Bridges\NetteRobotLoader\TestSuitesFinder;
8
use MyTester\Tester;
9
use Nette\DI\Helpers;
10
use Nette\Schema\Expect;
11
12
/**
13
 * MyTester Extension for Nette DIC
14
 *
15
 * @author Jakub Konečný
16
 * @method array getConfig()
17
 */
18
final class MyTesterExtension extends \Nette\DI\CompilerExtension
19
{
20
    public const TAG = "mytester.test";
21
    private const SERVICE_RUNNER = "runner";
22
    private const SERVICE_SUITE_FACTORY = "suiteFactory";
23
24
    public function getConfigSchema(): \Nette\Schema\Schema
25
    {
26 1
        $params = $this->getContainerBuilder()->parameters;
27 1
        return Expect::structure([
28 1
            "folder" => Expect::string(Helpers::expand("%appDir%/../tests", $params)),
29 1
            "onExecute" => Expect::array()->default([]),
30 1
            "onFinish" => Expect::array()->default([]),
31 1
            "colors" => Expect::bool(false),
32 1
        ])->castTo("array");
33
    }
34
35
    /**
36
     * @throws Exception
37
     */
38
    public function loadConfiguration(): void
39
    {
40 1
        $config = $this->getConfig();
41 1
        $builder = $this->getContainerBuilder();
42 1
        if (!is_dir($config["folder"])) {
43
            throw new Exception("Invalid folder {$config["folder"]} for $this->name.folder");
44
        }
45 1
        $builder->addDefinition($this->prefix(static::SERVICE_RUNNER))
46 1
            ->setFactory(Tester::class, [$config["folder"]]);
47 1
        $builder->addDefinition($this->prefix(static::SERVICE_SUITE_FACTORY))
48 1
            ->setType(ContainerSuiteFactory::class);
49 1
        $suites = (new TestSuitesFinder())->getSuites($config["folder"]);
50 1
        foreach ($suites as $index => $suite) {
51 1
            $builder->addDefinition($this->prefix("test." . ($index + 1)))
52 1
                ->setType($suite)
53 1
                ->addTag(self::TAG);
54
        }
55
    }
56
57
    public function afterCompile(\Nette\PhpGenerator\ClassType $class): void
58
    {
59 1
        $config = $this->getConfig();
60 1
        $this->initialization->addBody('$runner = $this->getService(?);', [$this->prefix(static::SERVICE_RUNNER)]);
61 1
        $this->initialization->addBody('$runner->useColors = ?;', [$config["colors"]]);
62 1
        $this->writeRunnerEventHandlers("onExecute", $config["onExecute"]);
63 1
        $this->writeRunnerEventHandlers("onFinish", $config["onFinish"]);
64
    }
65
66
    private function writeRunnerEventHandlers(string $eventName, array $callbacks): void
67
    {
68 1
        foreach ($callbacks as &$task) {
69
            if (!is_array($task)) {
70
                $task = explode("::", $task);
71
            } elseif (str_starts_with($task[0], "@")) {
72
                $className = substr($task[0], 1);
73
                $this->initialization->addBody(
74
                    '$runner->' . $eventName . '[] = [$this->getService(?), ?];',
75
                    [$className, $task[1]]
76
                );
77
                continue;
78
            }
79
            $this->initialization->addBody('$runner->' . $eventName . '[] = [?, ?];', [$task[0], $task[1]]);
80
        }
81
    }
82
}
83