Completed
Push — master ( abec3a...7e1653 )
by Hannes
02:00
created

ExampleFactory::createExpectations()   A

Complexity

Conditions 2
Paths 2

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 2
eloc 5
nc 2
nop 1
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->readName($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->shouldExtendExample($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 (!$expectations) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $expectations of type hanneskod\readmetester\E...\ExpectationInterface[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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 name from example annotation
77
     *
78
     * @return string
79
     */
80 View Code Duplication
    private function readName(array $annotations)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        foreach ($annotations as list($name, $args)) {
83
            if (strcasecmp($name, 'example') == 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
     * Get name of example this example should extend
109
     *
110
     * @return string
111
     */
112 View Code Duplication
    private function shouldExtendExample(array $annotations)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
    {
114
        foreach ($annotations as list($name, $args)) {
115
            if (strcasecmp($name, 'extends') == 0) {
116
                return isset($args[0]) ? $args[0] : '';
117
            }
118
        }
119
120
        return '';
121
    }
122
123
    /**
124
     * Create expectation from definition data
125
     *
126
     * @return Expectation\ExpectationInterface[]
127
     */
128
    private function createExpectations(array $annotations)
129
    {
130
        $expectations = [];
131
132
        foreach ($annotations as list($name, $args)) {
133
            $expectations[] = $this->expectationFactory->createExpectation($name, $args);
134
        }
135
136
        return array_filter($expectations);
137
    }
138
}
139