Completed
Push — master ( 7e1653...d668ce )
by Hannes
02:01
created

ExampleFactory::readAnnotation()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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