Completed
Push — master ( 94304e...b7ad07 )
by Hannes
02:10
created

ExampleFactory::shouldIgnoreExample()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace hanneskod\readmetester;
6
7
use hanneskod\readmetester\Expectation\ExpectationFactory;
8
9
/**
10
 * Create examples from definitions created by Parser
11
 */
12
class ExampleFactory
13
{
14
    /**
15
     * @var ExpectationFactory
16
     */
17
    private $expectationFactory;
18
19
    public function __construct(ExpectationFactory $expectationFactory = null)
20
    {
21
        $this->expectationFactory = $expectationFactory ?: new ExpectationFactory;
22
    }
23
24
    /**
25
     * Create examples from definitions
26
     *
27
     * @param  array $defenitions Example definitions as created by Parser
28
     * @return Example[]
29
     */
30
    public function createExamples(array $defenitions): array
31
    {
32
        $examples = [];
33
        $context = null;
34
35
        foreach ($defenitions as $index => $def) {
36
            if ($this->isAnnotatedWith('ignore', $def['annotations'])) {
37
                continue;
38
            }
39
40
            $name = $this->readAnnotation('example', $def['annotations']) ?: (string)($index + 1);
41
42
            if (isset($examples[$name])) {
43
                throw new \RuntimeException("Example '$name' already exists in definition ".($index + 1));
44
            }
45
46
            $codeBlock = new CodeBlock($def['code']);
47
48
            if ($context) {
49
                $codeBlock->prepend($context);
50
            }
51
52
            if ($extends = $this->readAnnotation('extends', $def['annotations'])) {
53
                if (!isset($examples[$extends])) {
54
                    throw new \RuntimeException(
55
                        "Example '$extends' does not exist and can not be extended in definition ".($index + 1)
56
                    );
57
                }
58
59
                $codeBlock->prepend($examples[$extends]->getCodeBlock());
60
            }
61
62
            $expectations = $this->createExpectations($def['annotations']);
63
64
            if (empty($expectations)) {
65
                $expectations[] = $this->expectationFactory->createExpectation('expectnothing', []);
66
            }
67
68
            $examples[$name] = new Example($name, $codeBlock, $expectations);
69
70
            if ($this->isAnnotatedWith('exampleContext', $def['annotations'])) {
71
                $context = $examples[$name]->getCodeBlock();
72
            }
73
        }
74
75
        return $examples;
76
    }
77
78
    /**
79
     * Read the first argument from annotation $needle
80
     */
81
    private function readAnnotation(string $needle, array $annotations): string
82
    {
83
        foreach ($annotations as list($name, $args)) {
84
            if (strcasecmp($name, $needle) == 0) {
85
                return isset($args[0]) ? $args[0] : '';
86
            }
87
        }
88
89
        return '';
90
    }
91
92
    /**
93
     * Check if this example is marked as ignored
94
     */
95
    private function isAnnotatedWith(string $annotationName, array $annotations): bool
96
    {
97
        foreach ($annotations as list($name, $args)) {
98
            if (strcasecmp($name, $annotationName) == 0) {
99
                return true;
100
            }
101
        }
102
103
        return false;
104
    }
105
106
    /**
107
     * Create expectation from definition data
108
     *
109
     * @return Expectation\ExpectationInterface[]
110
     */
111
    private function createExpectations(array $annotations): array
112
    {
113
        $expectations = [];
114
115
        foreach ($annotations as list($name, $args)) {
116
            $expectations[] = $this->expectationFactory->createExpectation($name, $args);
117
        }
118
119
        return array_filter($expectations);
120
    }
121
}
122