ArrayLoader   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 286
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 8
dl 0
loc 286
ccs 93
cts 93
cp 1
rs 9.84
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A supports() 0 4 3
A load() 0 16 4
A loadFeatureHash() 0 27 5
A loadBackgroundHash() 0 16 1
A loadScenarioHash() 0 17 1
A loadOutlineHash() 0 35 3
A loadStepsHash() 0 9 2
A loadStepHash() 0 25 4
A loadTableHash() 0 4 1
A loadPyStringHash() 0 11 3
A examplesAreInArray() 0 4 1
A processExamplesArray() 0 15 4
1
<?php
2
3
/*
4
 * This file is part of the Behat Gherkin.
5
 * (c) Konstantin Kudryashov <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Behat\Gherkin\Loader;
12
13
use Behat\Gherkin\Node\BackgroundNode;
14
use Behat\Gherkin\Node\ExampleTableNode;
15
use Behat\Gherkin\Node\FeatureNode;
16
use Behat\Gherkin\Node\OutlineNode;
17
use Behat\Gherkin\Node\PyStringNode;
18
use Behat\Gherkin\Node\ScenarioNode;
19
use Behat\Gherkin\Node\StepNode;
20
use Behat\Gherkin\Node\TableNode;
21
22
/**
23
 * From-array loader.
24
 *
25
 * @author Konstantin Kudryashov <[email protected]>
26
 */
27
class ArrayLoader implements LoaderInterface
28
{
29
    /**
30
     * Checks if current loader supports provided resource.
31
     *
32
     * @param mixed $resource Resource to load
33
     *
34
     * @return Boolean
35
     */
36 1
    public function supports($resource)
37
    {
38 1
        return is_array($resource) && (isset($resource['features']) || isset($resource['feature']));
39
    }
40
41
    /**
42
     * Loads features from provided resource.
43
     *
44
     * @param mixed $resource Resource to load
45
     *
46
     * @return FeatureNode[]
47
     */
48 44
    public function load($resource)
49
    {
50 44
        $features = array();
51
52 44
        if (isset($resource['features'])) {
53 8
            foreach ($resource['features'] as $iterator => $hash) {
54 7
                $feature = $this->loadFeatureHash($hash, $iterator);
55 7
                $features[] = $feature;
56
            }
57 36
        } elseif (isset($resource['feature'])) {
58 36
            $feature = $this->loadFeatureHash($resource['feature']);
59 36
            $features[] = $feature;
60
        }
61
62 44
        return $features;
63
    }
64
65
    /**
66
     * Loads feature from provided feature hash.
67
     *
68
     * @param array   $hash Feature hash
69
     * @param integer $line
70
     *
71
     * @return FeatureNode
72
     */
73 43
    protected function loadFeatureHash(array $hash, $line = 0)
74
    {
75 43
        $hash = array_merge(
76
            array(
77 43
                'title' => null,
78
                'description' => null,
79
                'tags' => array(),
80 43
                'keyword' => 'Feature',
81 43
                'language' => 'en',
82 43
                'line' => $line,
83
                'scenarios' => array(),
84
            ),
85 43
            $hash
86
        );
87 43
        $background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null;
88
89 43
        $scenarios = array();
90 43
        foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) {
91 36
            if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) {
92 13
                $scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator);
93
            } else {
94 28
                $scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator);
95
            }
96
        }
97
98 43
        return new FeatureNode($hash['title'], $hash['description'], $hash['tags'], $background, $scenarios, $hash['keyword'], $hash['language'], null, $hash['line']);
99
    }
100
101
    /**
102
     * Loads background from provided hash.
103
     *
104
     * @param array $hash Background hash
105
     *
106
     * @return BackgroundNode
107
     */
108 8
    protected function loadBackgroundHash(array $hash)
109
    {
110 8
        $hash = array_merge(
111
            array(
112 8
                'title' => null,
113
                'keyword' => 'Background',
114
                'line' => 0,
115
                'steps' => array(),
116
            ),
117 8
            $hash
118
        );
119
120 8
        $steps = $this->loadStepsHash($hash['steps']);
121
122 8
        return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
123
    }
124
125
    /**
126
     * Loads scenario from provided scenario hash.
127
     *
128
     * @param array   $hash Scenario hash
129
     * @param integer $line Scenario definition line
130
     *
131
     * @return ScenarioNode
132
     */
133 28
    protected function loadScenarioHash(array $hash, $line = 0)
134
    {
135 28
        $hash = array_merge(
136
            array(
137 28
                'title' => null,
138
                'tags' => array(),
139 28
                'keyword' => 'Scenario',
140 28
                'line' => $line,
141
                'steps' => array(),
142
            ),
143 28
            $hash
144
        );
145
146 28
        $steps = $this->loadStepsHash($hash['steps']);
147
148 28
        return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
149
    }
150
151
    /**
152
     * Loads outline from provided outline hash.
153
     *
154
     * @param array   $hash Outline hash
155
     * @param integer $line Outline definition line
156
     *
157
     * @return OutlineNode
158
     */
159 13
    protected function loadOutlineHash(array $hash, $line = 0)
160
    {
161 13
        $hash = array_merge(
162
            array(
163 13
                'title' => null,
164
                'tags' => array(),
165 13
                'keyword' => 'Scenario Outline',
166 13
                'line' => $line,
167
                'steps' => array(),
168
                'examples' => array(),
169
            ),
170 13
            $hash
171
        );
172
173 13
        $steps = $this->loadStepsHash($hash['steps']);
174
175 13
        if (isset($hash['examples']['keyword'])) {
176 1
            $examplesKeyword = $hash['examples']['keyword'];
177 1
            unset($hash['examples']['keyword']);
178
        } else {
179 12
            $examplesKeyword = 'Examples';
180
        }
181
182 13
        $exHash = $hash['examples'];
183 13
        $examples = array();
184
185 13
        if ($this->examplesAreInArray($exHash)) {
186 2
            $examples = $this->processExamplesArray($exHash, $examplesKeyword, $examples);
187
        } else {
188
            // examples as a single table - we create an array with the only one element
189 12
            $examples[] = new ExampleTableNode($exHash, $examplesKeyword);;
190
        }
191
192 13
        return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
193
    }
194
195
    /**
196
     * Loads steps from provided hash.
197
     *
198
     * @param array $hash
199
     *
200
     * @return StepNode[]
201
     */
202 38
    private function loadStepsHash(array $hash)
203
    {
204 38
        $steps = array();
205 38
        foreach ($hash as $stepIterator => $stepHash) {
206 31
            $steps[] = $this->loadStepHash($stepHash, $stepIterator);
207
        }
208
209 38
        return $steps;
210
    }
211
212
    /**
213
     * Loads step from provided hash.
214
     *
215
     * @param array   $hash Step hash
216
     * @param integer $line Step definition line
217
     *
218
     * @return StepNode
219
     */
220 31
    protected function loadStepHash(array $hash, $line = 0)
221
    {
222 31
        $hash = array_merge(
223
            array(
224 31
                'keyword_type' => 'Given',
225 31
                'type' => 'Given',
226
                'text' => null,
227 31
                'keyword' => 'Scenario',
228 31
                'line' => $line,
229
                'arguments' => array(),
230
            ),
231 31
            $hash
232
        );
233
234 31
        $arguments = array();
235 31
        foreach ($hash['arguments'] as $argumentHash) {
236 9
            if ('table' === $argumentHash['type']) {
237 4
                $arguments[] = $this->loadTableHash($argumentHash['rows']);
238 7
            } elseif ('pystring' === $argumentHash['type']) {
239 7
                $arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1);
240
            }
241
        }
242
243 31
        return new StepNode($hash['type'], $hash['text'], $arguments, $hash['line'], $hash['keyword_type']);
244
    }
245
246
    /**
247
     * Loads table from provided hash.
248
     *
249
     * @param array $hash Table hash
250
     *
251
     * @return TableNode
252
     */
253 4
    protected function loadTableHash(array $hash)
254
    {
255 4
        return new TableNode($hash);
256
    }
257
258
    /**
259
     * Loads PyString from provided hash.
260
     *
261
     * @param array   $hash PyString hash
262
     * @param integer $line
263
     *
264
     * @return PyStringNode
265
     */
266 7
    protected function loadPyStringHash(array $hash, $line = 0)
267
    {
268 7
        $line = isset($hash['line']) ? $hash['line'] : $line;
269
270 7
        $strings = array();
271 7
        foreach (explode("\n", $hash['text']) as $string) {
272 7
            $strings[] = $string;
273
        }
274
275 7
        return new PyStringNode($strings, $line);
276
    }
277
278
    /**
279
     * Checks if examples node is an array
280
     * @param $exHash object hash
281
     * @return bool
282
     */
283 13
    private function examplesAreInArray($exHash)
284
    {
285 13
        return isset($exHash[0]);
286
    }
287
288
    /**
289
     * Processes cases when examples are in the form of array of arrays
290
     * OR in the form of array of objects
291
     *
292
     * @param $exHash array hash
293
     * @param $examplesKeyword string
294
     * @param $examples array
295
     * @return array
296
     */
297 2
    private function processExamplesArray($exHash, $examplesKeyword, $examples)
298
    {
299 2
        for ($i = 0; $i < count($exHash); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
300 2
            if (isset($exHash[$i]['table'])) {
301
                // we have examples as objects, hence there could be tags
302 2
                $exHashTags = isset($exHash[$i]['tags']) ? $exHash[$i]['tags'] : array();
303 2
                $examples[] = new ExampleTableNode($exHash[$i]['table'], $examplesKeyword, $exHashTags);
304
            } else {
305
                // we have examples as arrays
306 1
                $examples[] = new ExampleTableNode($exHash[$i], $examplesKeyword);
307
            }
308
        }
309
310 2
        return $examples;
311
    }
312
}
313