Test Failed
Push — master ( a52ae2...22d245 )
by Hannes
01:58
created

ExampleFactory::readExample()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 2
dl 0
loc 9
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\Annotations;
8
use hanneskod\readmetester\Expectation\ExpectationFactory;
9
use hanneskod\readmetester\Expectation\ExpectationInterface;
10
use hanneskod\readmetester\Name\AnonymousName;
11
use hanneskod\readmetester\Name\ExampleName;
12
use hanneskod\readmetester\Name\NameInterface;
13
use hanneskod\readmetester\Parser\Annotation;
14
use hanneskod\readmetester\Parser\Definition;
15
16
class ExampleFactory
17
{
18
    /** @var ExpectationFactory */
19
    private $expectationFactory;
20
21
    /** @var ProcessorInterface */
22
    private $processor;
23
24
    /** @var bool */
25
    private $ignoreUnknownAnnotations;
26
27
    public function __construct(
28
        ExpectationFactory $expectationFactory,
29
        ProcessorInterface $processor,
30
        bool $ignoreUnknownAnnotations = false
31
    ) {
32
        $this->expectationFactory = $expectationFactory;
33
        $this->processor = $processor;
34
        $this->ignoreUnknownAnnotations = $ignoreUnknownAnnotations;
35
    }
36
37
    public function createExamples(Definition ...$defs): RegistryInterface
38
    {
39
        $registry = new ExampleRegistry;
40
        $context = null;
41
42
        foreach ($defs as $index => $def) {
43
            $name = new AnonymousName('');
44
            $code = $def->getCodeBlock();
45
            $expectations = [];
46
            $active = true;
47
48
            if ($context) {
49
                $code = $code->prepend($context);
0 ignored issues
show
Bug introduced by
$context of type void is incompatible with the type hanneskod\readmetester\Parser\CodeBlock expected by parameter $codeBlock of hanneskod\readmetester\Parser\CodeBlock::prepend(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
                $code = $code->prepend(/** @scrutinizer ignore-type */ $context);
Loading history...
50
            }
51
52
            foreach ($def->getAnnotations() as $annotation) {
53
                if ($annotation->isNamed(Annotations::ANNOTATION_IGNORE)) {
54
                    $active = false;
55
                    continue;
56
                }
57
58
                if ($annotation->isNamed(Annotations::ANNOTATION_EXAMPLE)) {
59
                    if ($annotation->getArgument()) {
60
                        $name = new ExampleName($annotation->getArgument(), $name->getNamespaceName());
61
                    }
62
                    continue;
63
                }
64
65
                if ($annotation->isNamed(Annotations::ANNOTATION_INCLUDE)) {
66
                    $nameToInclude = new ExampleName($annotation->getArgument(), '');
67
68
                    if (!$registry->hasExample($nameToInclude)) {
69
                        throw new \RuntimeException(
70
                            "Example '{$annotation->getArgument()}' can not be included in {$name->getShortName()}"
71
                        );
72
                    }
73
74
                    $code = $code->prepend($registry->getExample($nameToInclude)->getCodeBlock());
75
                    continue;
76
                }
77
78
                if ($expectation = $this->expectationFactory->createExpectation($annotation)) {
79
                    if ($expectation instanceof ExpectationInterface) {
80
                        $expectations[] = $expectation;
81
                        continue;
82
                    }
83
                }
84
85
                if ($annotation->isNamed(Annotations::ANNOTATION_CONTEXT)) {
86
                    $context = $code;
87
                    continue;
88
                }
89
90
                if (!$this->ignoreUnknownAnnotations) {
91
                    throw new \RuntimeException("Unknown annotation @{$annotation->getName()}");
92
                }
93
            }
94
95
            if ($registry->hasExample($name)) {
96
                throw new \RuntimeException("Example '{$name->getShortName()}' already exists");
97
            }
98
99
            $registry->setExample(
100
                $this->processor->process(
101
                    (new Example($name, $code, $expectations))->withActive($active)
102
                )
103
            );
104
        }
105
106
        return $registry;
107
    }
108
}
109