Test Failed
Push — master ( 614ce5...540a9b )
by Hannes
02:11
created

ExampleFactory::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace hanneskod\readmetester\Example;
6
7
use hanneskod\readmetester\Expectation\ExpectationFactory;
8
use hanneskod\readmetester\Parser\Annotation;
9
use hanneskod\readmetester\Parser\Definition;
10
11
/**
12
 * Create Examples objects from Definitions
13
 */
14
class ExampleFactory
15
{
16
    /**
17
     * @var ExpectationFactory
18
     */
19
    private $expectationFactory;
20
21
    /**
22
     * @var FilterInterface
23
     */
24
    private $filter;
25
26
    public function __construct(ExpectationFactory $expectationFactory, FilterInterface $filter = null)
27
    {
28
        $this->expectationFactory = $expectationFactory;
29
        $this->filter = $filter ?: new NullFilter;
30
    }
31
32
    /**
33
     * Create examples from definitions
34
     *
35
     * @return Example[]
36
     */
37
    public function createExamples(Definition ...$defs): array
38
    {
39
        $examples = [];
40
        $context = null;
41
42
        foreach ($defs as $index => $def) {
43
            $name = '';
44
            $code = $def->getCodeBlock();
45
            $expectations = [];
46
            $ignoreExample = false;
47
48
            if ($context) {
49
                $code = $code->prepend($context);
50
            }
51
52
            foreach ($def->getAnnotations() as $annotation) {
53
                if ($annotation->isNamed('ignore')) {
54
                    $ignoreExample = true;
55
                    continue;
56
                }
57
58
                if ($annotation->isNamed('example')) {
59
                    $name = $annotation->getArgument();
60
                    continue;
61
                }
62
63
                if ($annotation->isNamed('include')) {
64
                    $toInclude = $annotation->getArgument();
65
66
                    if (!isset($examples[$toInclude])) {
67
                        throw new \RuntimeException(
68
                            "Example '$toInclude' does not exist and can not be included in definition ".($index + 1)
69
                        );
70
                    }
71
72
                    $code = $code->prepend($examples[$toInclude]->getCodeBlock());
73
                    continue;
74
                }
75
76
                if ($expectation = $this->expectationFactory->createExpectation($annotation)) {
77
                    $expectations[] = $expectation;
78
                    continue;
79
                }
80
81
                if ($annotation->isNamed('exampleContext')) {
82
                    $context = $code;
83
                    continue;
84
                }
85
86
                throw new \RuntimeException("Unknown annotation @{$annotation->getName()}");
87
            }
88
89
            if (isset($examples[$name])) {
90
                throw new \RuntimeException("Example '$name' already exists in definition ".($index + 1));
91
            }
92
93
            if (!$this->filter->isValid($name)) {
94
                $ignoreExample = true;
95
            }
96
97
            if (!$name) {
98
                $name = (string)($index + 1);
99
            }
100
101
            $examples[$name] = $ignoreExample
102
                ? new IgnoredExample($name, $code, $expectations)
103
                : new Example($name, $code, $expectations);
104
        }
105
106
        return $examples;
107
    }
108
}
109