Completed
Pull Request — master (#150)
by Matt
02:45
created

ArrayLoader::loadFeatureHash()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 44
ccs 28
cts 28
cp 1
rs 8.2826
c 0
b 0
f 0
cc 7
nc 24
nop 2
crap 7
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\ExampleNode;
15
use Behat\Gherkin\Node\ExampleTableNode;
16
use Behat\Gherkin\Node\FeatureNode;
17
use Behat\Gherkin\Node\OutlineNode;
18
use Behat\Gherkin\Node\PyStringNode;
19
use Behat\Gherkin\Node\RuleNode;
20
use Behat\Gherkin\Node\ScenarioNode;
21
use Behat\Gherkin\Node\StepNode;
22
use Behat\Gherkin\Node\TableNode;
23
24
/**
25
 * From-array loader.
26
 *
27
 * @author Konstantin Kudryashov <[email protected]>
28
 */
29
class ArrayLoader implements LoaderInterface
30
{
31
    /**
32
     * Checks if current loader supports provided resource.
33
     *
34
     * @param mixed $resource Resource to load
35
     *
36
     * @return Boolean
37
     */
38 1
    public function supports($resource)
39
    {
40 1
        return is_array($resource) && (isset($resource['features']) || isset($resource['feature']));
41
    }
42
43
    /**
44
     * Loads features from provided resource.
45
     *
46
     * @param mixed $resource Resource to load
47
     *
48
     * @return FeatureNode[]
49
     */
50 45
    public function load($resource)
51
    {
52 45
        $features = array();
53
54 45
        if (isset($resource['features'])) {
55 9
            foreach ($resource['features'] as $iterator => $hash) {
56 8
                $feature = $this->loadFeatureHash($hash, $iterator);
57 9
                $features[] = $feature;
58
            }
59 36
        } elseif (isset($resource['feature'])) {
60 36
            $feature = $this->loadFeatureHash($resource['feature']);
61 36
            $features[] = $feature;
62
        }
63
64 45
        return $features;
65
    }
66
67
    /**
68
     * Loads feature from provided feature hash.
69
     *
70
     * @param array   $hash Feature hash
71
     * @param integer $line
72
     *
73
     * @return FeatureNode
74
     */
75 44
    protected function loadFeatureHash(array $hash, $line = 0)
76
    {
77 44
        $hash = array_merge(
78
            array(
79 44
                'title' => null,
80
                'description' => null,
81
                'tags' => array(),
82 44
                'keyword' => 'Feature',
83 44
                'language' => 'en',
84 44
                'line' => $line,
85
                'scenarios' => array(),
86
            ),
87 44
            $hash
88
        );
89 44
        $background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null;
90
91 44
        $rules = array();
92 44
        $givenRules = isset($hash['rules']) ? (array) $hash['rules'] : array();
93 44
        foreach ($givenRules as $ruleIterator => $ruleHash) {
94 2
            $rules[] = $this->loadRuleHash($ruleHash, $ruleIterator);
95
        }
96
97 44
        $scenarios = array();
98 44
        foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) {
99 35
            if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) {
100 12
                $scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator);
101
            } else {
102 35
                $scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator);
103
            }
104
        }
105
106 44
        return new FeatureNode(
107 44
            $hash['title'],
108 44
            $hash['description'],
109 44
            $hash['tags'],
110 44
            $background,
111 44
            $scenarios,
112 44
            $hash['keyword'],
113 44
            $hash['language'],
114 44
            null,
115 44
            $hash['line'],
116 44
            $rules
117
        );
118
    }
119
120
    /**
121
     * Loads background from provided hash.
122
     *
123
     * @param array $hash Background hash
124
     *
125
     * @return BackgroundNode
126
     */
127 10
    protected function loadBackgroundHash(array $hash)
128
    {
129 10
        $hash = array_merge(
130
            array(
131 10
                'title' => null,
132
                'keyword' => 'Background',
133
                'line' => 0,
134
                'steps' => array(),
135
            ),
136 10
            $hash
137
        );
138
139 10
        $steps = $this->loadStepsHash($hash['steps']);
140
141 10
        return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
142
    }
143
144
    /**
145
     * Loads rule from provided hash.
146
     *
147
     * @param array $hash Background hash
148
     * @param integer $line Background definition line
149
     *
150
     * @return RuleNode
151
     */
152 2
    protected function loadRuleHash(array $hash, $line = 0)
153
    {
154 2
        $hash = array_merge(
155
            array(
156 2
                'title'         =>  null,
157 2
                'line'          =>  $line,
158
                'background'    =>  null,
159
                'examples'      =>  array(),
160
            ),
161 2
            $hash
162
        );
163
164
        $background = (
165 2
            is_array($hash['background'])
166 2
            ? $this->loadBackgroundHash($hash['background'])
167 2
            : null
168
        );
169
        $examples = (
170 2
            is_array($hash['examples'])
171 2
            ? array_map(array($this, 'loadExampleHash'), $hash['examples'], array_keys($hash['examples']))
172 2
            : null
173
        );
174
175 2
        return new RuleNode($hash['title'], $hash['line'], $background, $examples);
0 ignored issues
show
Documentation introduced by
$examples is of type array|null, but the function expects a array<integer,object<Beh...rkin\Node\ExampleNode>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
176
    }
177
178
    /**
179
     * Loads example from provided examplehash.
180
     *
181
     * @param array   $hash Example hash
182
     * @param integer $line Example definition line
183
     *
184
     * @return ExampleNode
185
     */
186 2 View Code Duplication
    protected function loadExampleHash(array $hash, $line = 0)
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...
187
    {
188 2
        $hash = array_merge(
189
            array(
190 2
                'title'         =>  null,
191
                'tags'          =>  array(),
192 2
                'keyword'       =>  'Example',
193 2
                'line'          =>  $line,
194
                'outline_steps' =>  array(),
195
            ),
196 2
            $hash
197
        );
198
199 2
        $steps = $this->loadStepsHash($hash['outline_steps']);
200
201 2
        return new ExampleNode($hash['title'], $hash['tags'], $steps, array(), $hash['line']);
202
    }
203
204
    /**
205
     * Loads scenario from provided scenario hash.
206
     *
207
     * @param array   $hash Scenario hash
208
     * @param integer $line Scenario definition line
209
     *
210
     * @return ScenarioNode
211
     */
212 28 View Code Duplication
    protected function loadScenarioHash(array $hash, $line = 0)
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...
213
    {
214 28
        $hash = array_merge(
215
            array(
216 28
                'title' => null,
217
                'tags' => array(),
218 28
                'keyword' => 'Scenario',
219 28
                'line' => $line,
220
                'steps' => array(),
221
            ),
222 28
            $hash
223
        );
224
225 28
        $steps = $this->loadStepsHash($hash['steps']);
226
227 28
        return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
228
    }
229
230
    /**
231
     * Loads outline from provided outline hash.
232
     *
233
     * @param array   $hash Outline hash
234
     * @param integer $line Outline definition line
235
     *
236
     * @return OutlineNode
237
     */
238 12
    protected function loadOutlineHash(array $hash, $line = 0)
239
    {
240 12
        $hash = array_merge(
241
            array(
242 12
                'title' => null,
243
                'tags' => array(),
244 12
                'keyword' => 'Scenario Outline',
245 12
                'line' => $line,
246
                'steps' => array(),
247
                'examples' => array(),
248
            ),
249 12
            $hash
250
        );
251
252 12
        $steps = $this->loadStepsHash($hash['steps']);
253
254 12
        if (isset($hash['examples']['keyword'])) {
255 1
            $examplesKeyword = $hash['examples']['keyword'];
256 1
            unset($hash['examples']['keyword']);
257
        } else {
258 11
            $examplesKeyword = 'Examples';
259
        }
260
261 12
        $examples = new ExampleTableNode($hash['examples'], $examplesKeyword);
262
263 12
        return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
264
    }
265
266
    /**
267
     * Loads steps from provided hash.
268
     *
269
     * @param array $hash
270
     *
271
     * @return StepNode[]
272
     */
273 39
    private function loadStepsHash(array $hash)
274
    {
275 39
        $steps = array();
276 39
        foreach ($hash as $stepIterator => $stepHash) {
277 32
            $steps[] = $this->loadStepHash($stepHash, $stepIterator);
278
        }
279
280 39
        return $steps;
281
    }
282
283
    /**
284
     * Loads step from provided hash.
285
     *
286
     * @param array   $hash Step hash
287
     * @param integer $line Step definition line
288
     *
289
     * @return StepNode
290
     */
291 32
    protected function loadStepHash(array $hash, $line = 0)
292
    {
293 32
        $hash = array_merge(
294
            array(
295 32
                'keyword_type' => 'Given',
296 32
                'type' => 'Given',
297
                'text' => null,
298 32
                'keyword' => 'Scenario',
299 32
                'line' => $line,
300
                'arguments' => array(),
301
            ),
302 32
            $hash
303
        );
304
305 32
        $arguments = array();
306 32
        foreach ($hash['arguments'] as $argumentHash) {
307 9
            if ('table' === $argumentHash['type']) {
308 4
                $arguments[] = $this->loadTableHash($argumentHash['rows']);
309 7
            } elseif ('pystring' === $argumentHash['type']) {
310 9
                $arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1);
311
            }
312
        }
313
314 32
        return new StepNode($hash['type'], $hash['text'], $arguments, $hash['line'], $hash['keyword_type']);
315
    }
316
317
    /**
318
     * Loads table from provided hash.
319
     *
320
     * @param array $hash Table hash
321
     *
322
     * @return TableNode
323
     */
324 4
    protected function loadTableHash(array $hash)
325
    {
326 4
        return new TableNode($hash);
327
    }
328
329
    /**
330
     * Loads PyString from provided hash.
331
     *
332
     * @param array   $hash PyString hash
333
     * @param integer $line
334
     *
335
     * @return PyStringNode
336
     */
337 7
    protected function loadPyStringHash(array $hash, $line = 0)
338
    {
339 7
        $line = isset($hash['line']) ? $hash['line'] : $line;
340
341 7
        $strings = array();
342 7
        foreach (explode("\n", $hash['text']) as $string) {
343 7
            $strings[] = $string;
344
        }
345
346 7
        return new PyStringNode($strings, $line);
347
    }
348
}
349