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

ArrayLoader::loadExampleHash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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