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

ArrayLoaderTest::testLoadRules()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 106

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 106
rs 8
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Tests\Behat\Gherkin\Loader;
4
5
use Behat\Gherkin\Loader\ArrayLoader;
6
7
class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
8
{
9
    private $loader;
10
11
    protected function setUp()
12
    {
13
        $this->loader = new ArrayLoader();
14
    }
15
16
    public function testSupports()
17
    {
18
        $this->assertFalse($this->loader->supports(__DIR__));
19
        $this->assertFalse($this->loader->supports(__FILE__));
20
        $this->assertFalse($this->loader->supports('string'));
21
        $this->assertFalse($this->loader->supports(array('wrong_root')));
22
        $this->assertFalse($this->loader->supports(array('features')));
23
        $this->assertTrue($this->loader->supports(array('features' => array())));
24
        $this->assertTrue($this->loader->supports(array('feature' => array())));
25
    }
26
27
    public function testLoadEmpty()
28
    {
29
        $this->assertEquals(array(), $this->loader->load(array('features' => array())));
30
    }
31
32
    public function testLoadFeatures()
33
    {
34
        $features = $this->loader->load(array(
35
            'features' => array(
36
                array(
37
                    'title'         => 'First feature',
38
                    'line'          => 3,
39
                ),
40
                array(
41
                    'description'   => 'Second feature description',
42
                    'language'      => 'ru',
43
                    'tags'          => array('some', 'tags')
44
                )
45
            ),
46
        ));
47
48
        $this->assertEquals(2, count($features));
49
50
        $this->assertEquals(3, $features[0]->getLine());
51
        $this->assertEquals('First feature', $features[0]->getTitle());
52
        $this->assertNull($features[0]->getDescription());
53
        $this->assertNull($features[0]->getFile());
54
        $this->assertEquals('en', $features[0]->getLanguage());
55
        $this->assertFalse($features[0]->hasTags());
56
57
        $this->assertEquals(1, $features[1]->getLine());
58
        $this->assertNull($features[1]->getTitle());
59
        $this->assertEquals('Second feature description', $features[1]->getDescription());
60
        $this->assertNull($features[1]->getFile());
61
        $this->assertEquals('ru', $features[1]->getLanguage());
62
        $this->assertEquals(array('some', 'tags'), $features[1]->getTags());
63
    }
64
65
    public function testLoadScenarios()
66
    {
67
        $features = $this->loader->load(array(
68
            'features' => array(
69
                array(
70
                    'title'     => 'Feature',
71
                    'scenarios' => array(
72
                        array(
73
                            'title' => 'First scenario',
74
                            'line'  => 2
75
                        ),
76
                        array(
77
                            'tags'  => array('second', 'scenario', 'tags')
78
                        ),
79
                        array(
80
                            'tags'  => array('third', 'scenario'),
81
                            'line'  => 3
82
                        )
83
                    )
84
                )
85
            ),
86
        ));
87
88
        $this->assertEquals(1, count($features));
89
90
        $scenarios = $features[0]->getScenarios();
91
92
        $this->assertEquals(3, count($scenarios));
93
94
        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[0]);
95
        $this->assertEquals('First scenario', $scenarios[0]->getTitle());
96
        $this->assertFalse($scenarios[0]->hasTags());
97
        $this->assertEquals(2, $scenarios[0]->getLine());
98
99
        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]);
100
        $this->assertNull($scenarios[1]->getTitle());
101
        $this->assertEquals(array('second', 'scenario', 'tags'), $scenarios[1]->getTags());
102
        $this->assertEquals(1, $scenarios[1]->getLine());
103
104
        $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[2]);
105
        $this->assertNull($scenarios[2]->getTitle());
106
        $this->assertEquals(array('third', 'scenario'), $scenarios[2]->getTags());
107
        $this->assertEquals(3, $scenarios[2]->getLine());
108
    }
109
110
    public function testLoadRules()
111
    {
112
        $features = $this->loader->load(array(
113
            'features'  =>  array(
114
                array(
115
                    'title'     =>  'Highlander - the short version',
116
                    'language'  =>  'en',
117
                    'line'      =>  1,
118
                    'rules' =>  array(
119
                        array(
120
                            'title'         =>  'There can be only One',
121
                            'line'          =>  3,
122
                            'background'    =>  array(
123
                                'line'          =>  4,
124
                                'steps'         =>  array(
125
                                    array(
126
                                        'keyword_type'  => 'Given',
127
                                        'type'          => 'Given',
128
                                        'text'          => 'there are 3 ninjas, line: 5',
129
                                    ),
130
                                ),
131
                            ),
132
                            'examples'       => array(
133
                                array(
134
                                    'title'         =>  'Only One -- More than one alive',
135
                                    'line'          =>  8,
136
                                    'outline_steps' =>  array(
137
                                        array(
138
                                            'keyword_type'  =>  'Given',
139
                                            'type'          =>  'Given',
140
                                            'text'          =>  'there are more than one ninjas alive',
141
                                            'line'          =>  9
142
                                        ),
143
                                        array(
144
                                            'keyword_type'  =>  'When',
145
                                            'type'          =>  'When',
146
                                            'text'          =>  '2 ninjas meet, they will fight',
147
                                            'line'          =>  10
148
                                        ),
149
                                        array(
150
                                            'keyword_type'  =>  'Then',
151
                                            'type'          =>  'Then',
152
                                            'text'          =>  'Then one ninja dies (but not me)',
153
                                            'line'          =>  11
154
                                        ),
155
                                        array(
156
                                            'keyword_type'  =>  'Then',
157
                                            'type'          =>  'And',
158
                                            'text'          =>  'And there is one ninja less alive',
159
                                            'line'          =>  12
160
                                        ),
161
                                    ),
162
                                )
163
                            )
164
                        )
165
                    )
166
                )
167
            )
168
        ));
169
170
        $this->assertCount(1, $features);
171
172
        $this->assertSame('Highlander - the short version', $features[0]->getTitle());
173
        $this->assertSame('en', $features[0]->getLanguage());
174
        $this->assertSame(1, $features[0]->getLine());
175
176
        $rules = $features[0]->getRules();
177
        $this->assertCount(1, $rules);
178
179
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\RuleNode', $rules[0]);
180
        $this->assertSame('There can be only One', $rules[0]->getTitle());
181
        $this->assertSame(3, $rules[0]->getLine());
182
183
        $examples = $rules[0]->getExamples();
184
        $this->assertCount(1, $examples);
185
186
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\ExampleNode', $examples[0]);
187
        $this->assertSame('Only One -- More than one alive', $examples[0]->getTitle());
188
189
        $steps = $examples[0]->getSteps();
190
        $this->assertCount(4, $steps);
191
192
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\StepNode', $steps[0]);
193
        $this->assertSame('Given', $steps[0]->getKeywordType());
194
        $this->assertSame('Given', $steps[0]->getKeyword());
195
        $this->assertSame('there are more than one ninjas alive', $steps[0]->getText());
196
        $this->assertSame(9, $steps[0]->getLine());
197
198
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\StepNode', $steps[1]);
199
        $this->assertSame('When', $steps[1]->getKeywordType());
200
        $this->assertSame('When', $steps[1]->getKeyword());
201
        $this->assertSame('2 ninjas meet, they will fight', $steps[1]->getText());
202
        $this->assertSame(10, $steps[1]->getLine());
203
204
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\StepNode', $steps[2]);
205
        $this->assertSame('Then', $steps[2]->getKeywordType());
206
        $this->assertSame('Then', $steps[2]->getKeyword());
207
        $this->assertSame('Then one ninja dies (but not me)', $steps[2]->getText());
208
        $this->assertSame(11, $steps[2]->getLine());
209
210
        $this->assertInstanceOf('\\Behat\\Gherkin\\Node\\StepNode', $steps[3]);
211
        $this->assertSame('Then', $steps[3]->getKeywordType());
212
        $this->assertSame('And', $steps[3]->getKeyword());
213
        $this->assertSame('And there is one ninja less alive', $steps[3]->getText());
214
        $this->assertSame(12, $steps[3]->getLine());
215
    }
216
217
    public function testLoadOutline()
218
    {
219
        $features = $this->loader->load(array(
220
            'features' => array(
221
                array(
222
                    'title'     => 'Feature',
223
                    'scenarios' => array(
224
                        array(
225
                            'type'  => 'outline',
226
                            'title' => 'First outline',
227
                            'line'  => 2
228
                        ),
229
                        array(
230
                            'type'  => 'outline',
231
                            'tags'  => array('second', 'outline', 'tags')
232
                        )
233
                    )
234
                )
235
            ),
236
        ));
237
238
        $this->assertEquals(1, count($features));
239
240
        $outlines = $features[0]->getScenarios();
241
242
        $this->assertEquals(2, count($outlines));
243
244
        $this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[0]);
245
        $this->assertEquals('First outline', $outlines[0]->getTitle());
246
        $this->assertFalse($outlines[0]->hasTags());
247
        $this->assertEquals(2, $outlines[0]->getLine());
248
249
        $this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[1]);
250
        $this->assertNull($outlines[1]->getTitle());
251
        $this->assertEquals(array('second', 'outline', 'tags'), $outlines[1]->getTags());
252
        $this->assertEquals(1, $outlines[1]->getLine());
253
    }
254
255
    public function testOutlineExamples()
256
    {
257
        $features = $this->loader->load(array(
258
            'features' => array(
259
                array(
260
                    'title'     => 'Feature',
261
                    'scenarios' => array(
262
                        array(
263
                            'type'      => 'outline',
264
                            'title'     => 'First outline',
265
                            'line'      => 2,
266
                            'examples'  => array(
267
                                array('user', 'pass'),
268
                                array('ever', 'sdsd'),
269
                                array('anto', 'fdfd')
270
                            )
271
                        ),
272
                        array(
273
                            'type'  => 'outline',
274
                            'tags'  => array('second', 'outline', 'tags')
275
                        )
276
                    )
277
                )
278
            ),
279
        ));
280
281
        $this->assertEquals(1, count($features));
282
283
        $scenarios = $features[0]->getScenarios();
284
        $scenario  = $scenarios[0];
285
286
        $this->assertEquals(
287
            array(array('user' => 'ever', 'pass' => 'sdsd'), array('user' => 'anto', 'pass' => 'fdfd')),
288
            $scenario->getExampleTable()->getHash()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Gherkin\Node\ScenarioInterface as the method getExampleTable() does only exist in the following implementations of said interface: Behat\Gherkin\Node\OutlineNode.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
289
        );
290
    }
291
292
    public function testLoadBackground()
293
    {
294
        $features = $this->loader->load(array(
295
            'features' => array(
296
                array(
297
                ),
298
                array(
299
                    'background' => array()
300
                ),
301
                array(
302
                    'background' => array(
303
                        'line' => 2
304
                    )
305
                ),
306
            )
307
        ));
308
309
        $this->assertEquals(3, count($features));
310
311
        $this->assertFalse($features[0]->hasBackground());
312
        $this->assertTrue($features[1]->hasBackground());
313
        $this->assertEquals(0, $features[1]->getBackground()->getLine());
314
        $this->assertTrue($features[2]->hasBackground());
315
        $this->assertEquals(2, $features[2]->getBackground()->getLine());
316
    }
317
318
    public function testLoadSteps()
319
    {
320
        $features = $this->loader->load(array(
321
            'features' => array(
322
                array(
323
                    'background' => array(
324
                        'steps' => array(
325
                            array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3),
326
                            array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2')
327
                        )
328
                    ),
329
                    'scenarios' => array(
330
                        array(
331
                            'title' => 'Scenario',
332
                            'steps' => array(
333
                                array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'sc step 1'),
334
                                array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'sc step 2')
335
                            )
336
                        ),
337
                        array(
338
                            'title' => 'Outline',
339
                            'type'  => 'outline',
340
                            'steps' => array(
341
                                array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'out step 1'),
342
                                array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'out step 2')
343
                            )
344
                        )
345
                    )
346
                )
347
            )
348
        ));
349
350
        $background = $features[0]->getBackground();
351
        $this->assertTrue($background->hasSteps());
352
        $this->assertEquals(2, count($background->getSteps()));
353
        $steps = $background->getSteps();
354
        $this->assertEquals('Gangway!', $steps[0]->getType());
355
        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
356
        $this->assertEquals('Given', $steps[0]->getKeywordType());
357
        $this->assertEquals('bg step 1', $steps[0]->getText());
358
        $this->assertEquals(3, $steps[0]->getLine());
359
        $this->assertEquals('Blimey!', $steps[1]->getType());
360
        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
361
        $this->assertEquals('When', $steps[1]->getKeywordType());
362
        $this->assertEquals('bg step 2', $steps[1]->getText());
363
        $this->assertEquals(1, $steps[1]->getLine());
364
365
        $scenarios  = $features[0]->getScenarios();
366
367
        $scenario = $scenarios[0];
368
        $this->assertTrue($scenario->hasSteps());
369
        $this->assertEquals(2, count($scenario->getSteps()));
370
        $steps = $scenario->getSteps();
371
        $this->assertEquals('Gangway!', $steps[0]->getType());
0 ignored issues
show
Deprecated Code introduced by
The method Behat\Gherkin\Node\StepNode::getType() has been deprecated with message: use getKeyword() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
372
        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
373
        $this->assertEquals('Given', $steps[0]->getKeywordType());
374
        $this->assertEquals('sc step 1', $steps[0]->getText());
375
        $this->assertEquals(0, $steps[0]->getLine());
376
        $this->assertEquals('Blimey!', $steps[1]->getType());
0 ignored issues
show
Deprecated Code introduced by
The method Behat\Gherkin\Node\StepNode::getType() has been deprecated with message: use getKeyword() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
377
        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
378
        $this->assertEquals('When', $steps[1]->getKeywordType());
379
        $this->assertEquals('sc step 2', $steps[1]->getText());
380
        $this->assertEquals(1, $steps[1]->getLine());
381
382
        $outline = $scenarios[1];
383
        $this->assertTrue($outline->hasSteps());
384
        $this->assertEquals(2, count($outline->getSteps()));
385
        $steps = $outline->getSteps();
386
        $this->assertEquals('Gangway!', $steps[0]->getType());
0 ignored issues
show
Deprecated Code introduced by
The method Behat\Gherkin\Node\StepNode::getType() has been deprecated with message: use getKeyword() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
387
        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
388
        $this->assertEquals('Given', $steps[0]->getKeywordType());
389
        $this->assertEquals('out step 1', $steps[0]->getText());
390
        $this->assertEquals(0, $steps[0]->getLine());
391
        $this->assertEquals('Blimey!', $steps[1]->getType());
0 ignored issues
show
Deprecated Code introduced by
The method Behat\Gherkin\Node\StepNode::getType() has been deprecated with message: use getKeyword() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
392
        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
393
        $this->assertEquals('When', $steps[1]->getKeywordType());
394
        $this->assertEquals('out step 2', $steps[1]->getText());
395
        $this->assertEquals(1, $steps[1]->getLine());
396
    }
397
398
    public function testLoadStepArguments()
399
    {
400
        $features = $this->loader->load(array(
401
            'features' => array(
402
                array(
403
                    'background' => array(
404
                        'steps' => array(
405
                            array(
406
                                'type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'step with table argument',
407
                                'arguments' => array(
408
                                    array(
409
                                        'type'  => 'table',
410
                                        'rows'  => array(
411
                                            array('key', 'val'),
412
                                            array(1, 2),
413
                                            array(3, 4)
414
                                        )
415
                                    )
416
                                )
417
                            ),
418
                            array(
419
                                'type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'step with pystring argument',
420
                                'arguments' => array(
421
                                    array(
422
                                        'type'      => 'pystring',
423
                                        'text'      => '    some text',
424
                                    )
425
                                )
426
                            ),
427
                            array(
428
                                'type' => 'Let go and haul', 'keyword_type' => 'Then', 'text' => '2nd step with pystring argument',
429
                                'arguments' => array(
430
                                    array(
431
                                        'type'      => 'pystring',
432
                                        'text'      => 'some text',
433
                                    )
434
                                )
435
                            )
436
                        )
437
                    )
438
                )
439
            )
440
        ));
441
442
        $background = $features[0]->getBackground();
443
444
        $this->assertTrue($background->hasSteps());
445
446
        $steps = $background->getSteps();
447
448
        $this->assertEquals(3, count($steps));
449
450
        $arguments = $steps[0]->getArguments();
451
        $this->assertEquals('Gangway!', $steps[0]->getType());
452
        $this->assertEquals('Gangway!', $steps[0]->getKeyword());
453
        $this->assertEquals('Given', $steps[0]->getKeywordType());
454
        $this->assertEquals('step with table argument', $steps[0]->getText());
455
        $this->assertInstanceOf('Behat\Gherkin\Node\TableNode', $arguments[0]);
456
        $this->assertEquals(array(array('key'=>1, 'val'=>2), array('key'=>3,'val'=>4)), $arguments[0]->getHash());
457
458
        $arguments = $steps[1]->getArguments();
459
        $this->assertEquals('Blimey!', $steps[1]->getType());
460
        $this->assertEquals('Blimey!', $steps[1]->getKeyword());
461
        $this->assertEquals('When', $steps[1]->getKeywordType());
462
        $this->assertEquals('step with pystring argument', $steps[1]->getText());
463
        $this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
464
        $this->assertEquals('    some text', (string) $arguments[0]);
465
466
        $arguments = $steps[2]->getArguments();
467
        $this->assertEquals('Let go and haul', $steps[2]->getType());
468
        $this->assertEquals('Let go and haul', $steps[2]->getKeyword());
469
        $this->assertEquals('Then', $steps[2]->getKeywordType());
470
        $this->assertEquals('2nd step with pystring argument', $steps[2]->getText());
471
        $this->assertInstanceOf('Behat\Gherkin\Node\PyStringNode', $arguments[0]);
472
        $this->assertEquals('some text', (string) $arguments[0]);
473
    }
474
475
    public function testSingleFeatureArray()
476
    {
477
        $features = $this->loader->load(array(
478
            'feature' => array(
479
                'title' => 'Some feature'
480
            )
481
        ));
482
483
        $this->assertEquals(1, count($features));
484
        $this->assertEquals('Some feature', $features[0]->getTitle());
485
    }
486
}
487