Completed
Push — master ( 3afbe4...79027c )
by Oleg
07:17
created

BuilderTest::testCreateTypeWrongException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Malezha\Menu\Tests;
3
4
use Malezha\Menu\Contracts\Attributes;
5
use Malezha\Menu\Contracts\Builder;
6
use Malezha\Menu\Element\Link;
7
use Malezha\Menu\Element\SubMenu;
8
use Malezha\Menu\Element\Text;
9
use Malezha\Menu\Factory\LinkFactory;
10
use Malezha\Menu\Factory\SubMenuFactory;
11
use Malezha\Menu\Factory\TextFactory;
12
13
/**
14
 * Class BuilderTest
15
 * @package Malezha\Menu\Tests
16
 */
17
class BuilderTest extends TestCase
18
{
19
    /**
20
     * @return Builder
21
     */
22
    protected function builderFactory()
23
    {
24
        return $this->app->makeWith(Builder::class, [
0 ignored issues
show
Bug introduced by
The method makeWith() does not seem to exist on object<Illuminate\Foundation\Application>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
25
            'activeAttributes' => $this->app->makeWith(Attributes::class, ['attributes' => ['class' => 'active']]),
0 ignored issues
show
Bug introduced by
The method makeWith() does not seem to exist on object<Illuminate\Foundation\Application>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
26
            'attributes' => $this->app->makeWith(Attributes::class, ['attributes' => ['class' => 'menu']]),
0 ignored issues
show
Bug introduced by
The method makeWith() does not seem to exist on object<Illuminate\Foundation\Application>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
27
        ]);
28
    }
29
    
30
    protected function serializeStub()
31
    {
32
        return $this->getStub('serialized/builder.txt');
33
    }
34
    
35
    protected function toArrayStub()
36
    {
37
        return [
38
            'type' => 'ul',
39
            'view' => 'menu::view',
40
            'attributes' => [
41
                'class' => 'menu',
42
            ],
43
            'activeAttributes' => [
44
                'class' => 'active',
45
            ],
46
            'elements' => [
47
                'index' => [
48
                    'view' => 'menu::elements.link',
49
                    'title' => 'Index',
50
                    'url' => 'http://localhost',
51
                    'attributes' => [],
52
                    'activeAttributes' => [
53
                        'class' => 'active',
54
                    ],
55
                    'linkAttributes' => [],
56
                    'displayRule' => true,
57
                    'type' => 'link',
58
                ],
59
                'submenu' => [
60
                    'view' => 'menu::elements.submenu',
61
                    'title' => '',
62
                    'url' => '#',
63
                    'attributes' => [],
64
                    'activeAttributes' => [
65
                        'class' => 'active',
66
                    ],
67
                    'linkAttributes' => [],
68
                    'displayRule' => true,
69
                    'builder' => [
70
                        'type' => 'ul',
71
                        'view' => 'menu::view',
72
                        'attributes' => [],
73
                        'activeAttributes' => [],
74
                        'elements' => [
75
                            'item_1' => [
76
                                'view' => 'menu::elements.link',
77
                                'title' => 'Item 1',
78
                                'url' => 'http://localhost/item/1',
79
                                'attributes' => [],
80
                                'activeAttributes' => [],
81
                                'linkAttributes' => [],
82
                                'displayRule' => true,
83
                                'type' => 'link',
84
                            ],
85
                            'item_2' => [
86
                                'view' => 'menu::elements.link',
87
                                'title' => 'Item 2',
88
                                'url' => 'http://localhost/item/2',
89
                                'attributes' => [],
90
                                'activeAttributes' => [],
91
                                'linkAttributes' => [],
92
                                'displayRule' => true,
93
                                'type' => 'link',
94
                            ],
95
                            'item_3' => [
96
                                'view' => 'menu::elements.link',
97
                                'title' => 'Item 3',
98
                                'url' => 'http://localhost/item/3',
99
                                'attributes' => [],
100
                                'activeAttributes' => [],
101
                                'linkAttributes' => [],
102
                                'displayRule' => true,
103
                                'type' => 'link',
104
                            ],
105
                        ],
106
                    ],
107
                    'type' => 'submenu',
108
                ],
109
            ],
110
        ];
111
    }
112
    
113
    public function testConstructor()
114
    {
115
        $builder = $this->builderFactory();
116
117
        $this->assertAttributeEquals($this->app, 'app', $builder);
118
        $this->assertAttributeEquals(Builder::UL, 'type', $builder);
119
        $this->assertAttributeInstanceOf(Attributes::class, 'attributes', $builder);
120
        $this->assertAttributeInternalType('array', 'elements', $builder);
121
        $this->assertAttributeInstanceOf(Attributes::class, 'activeAttributes', $builder);
122
    }
123
124
    public function testCreate()
125
    {
126
        $builder = $this->builderFactory();
127
128
        /** @var Link $item */
129
        $item = $builder->create('index', Link::class, function(LinkFactory $factory) {
130
            $factory->title = 'Home';
131
            $factory->url = '/';
132
133
            return $factory->build();
134
        });
135
136
        $this->assertInstanceOf(Link::class, $item);
137
        $this->assertAttributeEquals('Home', 'title', $item);
138
        $this->assertAttributeEquals('/', 'url', $item);
139
    }
140
141
    public function testCreateIfExists()
142
    {
143
        $this->expectException(\RuntimeException::class);
144
        
145
        $builder = $this->builderFactory();
146
147
        $builder->create('index', Link::class, function (LinkFactory $factory) {
148
            return $factory->build();
149
        });
150
151
        $builder->create('index', SubMenu::class, function (SubMenuFactory $factory) {
152
            return $factory->build();
153
        }); // Duplicate
154
    }
155
    
156 View Code Duplication
    public function testGet()
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...
157
    {
158
        $builder = $this->builderFactory();
159
        
160
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
161
            return $factory->build();
162
        });
163
        
164
        $this->assertEquals($item, $builder->get('test'));
165
        $this->assertEquals(null, $builder->get('notFound'));
166
        $this->assertEquals($item, $builder['test']);
167
        $this->assertEquals(null, $builder['notFound']);
168
    }
169
170 View Code Duplication
    public function testGetByIndex()
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...
171
    {
172
        $builder = $this->builderFactory();
173
174
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
175
            return $factory->build();
176
        });
177
178
        $this->assertEquals($item, $builder->getByIndex(0));
179
        $this->assertEquals(null, $builder->getByIndex(1));
180
        $this->assertEquals($item, $builder[0]);
181
        $this->assertEquals(null, $builder[1]);
182
    }
183
    
184
    public function testHas()
185
    {
186
        $builder = $this->builderFactory();
187
188
        $this->assertFalse($builder->has('test'));
189
        $this->assertFalse(isset($builder['test']));
190
    }
191
    
192
    public function testType()
193
    {
194
        $builder = $this->builderFactory();
195
        
196
        $this->assertEquals(Builder::UL, $builder->getType());
197
        $builder->setType(Builder::OL);
198
        $this->assertAttributeEquals(Builder::OL, 'type', $builder);
199
    }
200
    
201
    public function testAll()
202
    {
203
        $builder = $this->builderFactory();
204
        
205
        $this->assertEquals([], $builder->all());
206
207
        $item = $builder->create('test', Link::class, function (LinkFactory $factory) {
208
            return $factory->build();
209
        });
210
211
        $this->assertEquals(['test' => $item], $builder->all());
212
    }
213
    
214
    public function testForget()
215
    {
216
        $builder = $this->builderFactory();
217
218
        $builder->create('test', Link::class, function (LinkFactory $factory) {
219
            return $factory->build();
220
        });
221
        $builder->create('another', Text::class, function (TextFactory $factory) {
222
            return $factory->build();
223
        });
224
        
225
        $this->assertTrue($builder->has('test'));
226
        $builder->forget('test');
227
        $this->assertFalse($builder->has('test'));
228
        
229
        $this->assertTrue($builder->has('another'));
230
        unset($builder['another']);
231
        $this->assertFalse($builder->has('another'));
232
    }
233
    
234
    public function testActiveAttributes()
235
    {
236
        $builder = $this->builderFactory();
237
        $activeAttributes = $builder->getActiveAttributes();
238
        
239
        $this->assertInstanceOf(Attributes::class, $activeAttributes);
240
241
        $result = $builder->getActiveAttributes(function(Attributes $attributes) {
242
            $this->assertInstanceOf(Attributes::class, $attributes);
243
            
244
            return $attributes->get('class');
245
        });
246
        
247
        $this->assertEquals('active', $result);
248
    }
249
250
    public function testRender()
251
    {
252
        $builder = $this->builderFactory();
253
254
        $builder->create('index', Link::class, function(LinkFactory $factory) {
255
            $factory->title = 'Index Page';
256
            $factory->url = url('/');
257
            $factory->linkAttributes->push(['class' => 'menu-link']);
258
259
            return $factory->build();
260
        });
261
        
262 View Code Duplication
        $builder->create('orders', SubMenu::class, function(SubMenuFactory $factory) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
263
            $factory->attributes->push(['class' => 'child-menu']);
264
            $factory->title = 'Orders';
265
            $factory->url = 'javascript:;';
266
            
267
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
268
                $factory->title = 'All';
269
                $factory->url = url('/orders/all');
270
271
                return $factory->build();
272
            });
273
274
            $factory->builder->create('type_1', Link::class, function(LinkFactory $factory) {
275
                $factory->title = 'Type 1';
276
                $factory->url = url('/orders/1');
277
                $factory->linkAttributes->push(['class' => 'text-color-red']);
278
279
                return $factory->build();
280
            });
281
282
            $factory->builder->create('type_2', Link::class, function(LinkFactory $factory) {
283
                $factory->title = 'Type 2';
284
                $factory->url = url('/orders/2');
285
                $factory->linkAttributes->push(['data-attribute' => 'value']);
286
287
                return $factory->build();
288
            });
289
290
            return $factory->build();
291
        });
292
        
293
        $html = $builder->render();
294
        
295
        $this->assertEquals($this->getStub('menu.html'), $html);
296
    }
297
    
298
    public function testDisplayRules()
299
    {
300
        $builder = $this->builderFactory();
301
302
        $builder->create('index', Link::class, function(LinkFactory $factory) {
303
            $factory->title = 'Index Page';
304
            $factory->url = url('/');
305
306
            return $factory->build();
307
        });
308
309
        $builder->create('login', Link::class, function(LinkFactory $factory) {
310
            $factory->title = 'Login';
311
            $factory->url = url('/login');
312
            $factory->displayRule = function() {
313
                return true;
314
            };
315
316
            return $factory->build();
317
        });
318
319
        $builder->create('admin', Link::class, function(LinkFactory $factory) {
320
            $factory->title = 'Admin';
321
            $factory->url = url('/admin');
322
            $factory->displayRule = false;
323
324
            return $factory->build();
325
        });
326
327
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
328
            $factory->title = 'Logout';
329
            $factory->url = url('/logout');
330
            $factory->displayRule = null;
331
332
            return $factory->build();
333
        });
334
335
        $html = $builder->render();
336
337
        $this->assertEquals($this->getStub('display_rules.html'), $html);
338
    }
339
340
    public function testAnotherViewRender()
341
    {
342
        view()->addLocation(__DIR__ . '/stub');
343
        $this->app['config']->prepend('menu.paths', __DIR__ . '/stub');
344
        
345
        $builder = $this->builderFactory();
346
        $builder->create('index', Link::class, function(LinkFactory $factory) {
347
            $factory->title = 'Index Page';
348
            $factory->url = url('/');
349
350
            return $factory->build();
351
        });
352
353
        $builder->create('group', SubMenu::class, function(SubMenuFactory $factory) {
354
            $factory->builder->create('one', Link::class, function(LinkFactory $factory) {
355
                $factory->title = 'One';
356
                $factory->url = url('/one');
357
358
                return $factory->build();
359
            });
360
361
            return $factory->build();
362
        });
363
        
364
        $this->assertEquals($this->getStub('another_menu.html'), $builder->render('another'));
365
366
        $builder->get('group')->getBuilder()->setView('another');
367
        $this->assertEquals($this->getStub('another_sub_menu.html'), $builder->render());
368
369
        $builder->setView('another');
370
        $builder->get('group')->getBuilder()->setView('menu::view');
371
        $this->assertEquals($this->getStub('another_set_view_menu.html'), $builder->render());
372
    }
373
    
374
    public function testInsert()
375
    {
376
        $builder = $this->builderFactory();
377
378
        $builder->create('index', Link::class, function(LinkFactory $factory) {
379
            $factory->title = 'Index Page';
380
            $factory->url = url('/');
381
382
            return $factory->build();
383
        });
384
385
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
386
            $factory->title = 'Logout';
387
            $factory->url = url('logout');
388
389
            return $factory->build();
390
        });
391
        
392 View Code Duplication
        $builder->insertAfter('index', function (Builder $builder) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
393
            $builder->create('users', Link::class, function(LinkFactory $factory) {
394
                $factory->title = 'Users';
395
                $factory->url = url('users');
396
397
                return $factory->build();
398
            });
399
        });
400
        
401 View Code Duplication
        $builder->insertBefore('users', function (Builder $builder) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
402
            $builder->create('profile', Link::class, function(LinkFactory $factory) {
403
                $factory->title = 'Profile';
404
                $factory->url = url('profile');
405
406
                return $factory->build();
407
            });
408
        });
409
410
        $this->assertEquals($this->getStub('insert.html'), $builder->render('another'));
411
    }
412
413
    public function testInsertExceptionHasNot()
414
    {
415
        $this->expectException(\RuntimeException::class);
416
417
        $builder = $this->builderFactory();
418
        $builder->insertBefore('not_exist', function (Builder $builder) {});
0 ignored issues
show
Unused Code introduced by
The parameter $builder is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
419
    }
420
421
    public function testInsertExceptionDuplicate()
422
    {
423
        $this->expectException(\RuntimeException::class);
424
425
        $builder = $this->builderFactory();
426
427
        $builder->create('home', Link::class, function(LinkFactory $factory) {
428
            $factory->title = 'Home';
429
            $factory->url = '/';
430
431
            return $factory->build();
432
        });
433
434
        $builder->create('some', Link::class, function(LinkFactory $factory) {
435
            $factory->title = 'Some';
436
            $factory->url = '/';
437
438
            return $factory->build();
439
        });
440
441
        $builder->insertAfter('home', function (Builder $builder) {
442
            $builder->create('some', Text::class, function(TextFactory $factory) {
443
                $factory->text = 'Duplicate some';
444
445
                return $factory->build();
446
            });
447
        });
448
    }
449
450
    public function testArray()
451
    {
452
        $builder = $this->builderFactory();
453
        $builder->create('index', Link::class, function(LinkFactory $factory) {
454
            $factory->title = 'Index';
455
            $factory->url = url('/');
456
457
            return $factory->build();
458
        });
459
460
        $builder->create('submenu', SubMenu::class, function(SubMenuFactory $factory) {
461
            for ($i = 1; $i <= 3; ++$i) {
462
                $factory->builder->create('item_' . $i, Link::class, function(LinkFactory $factory) use ($i) {
463
                    $factory->title = 'Item ' . $i;
464
                    $factory->url = url('/item', ['id' => $i]);
465
466
                    return $factory->build();
467
                });
468
            }
469
470
            return $factory->build();
471
        });
472
        
473
        $this->assertEquals($this->toArrayStub(), $builder->toArray());
474
475
        $builderFormArray = $builder->fromArray($builder->toArray());
476
        $this->assertEquals($builder->render(), $builderFormArray->render());
477
    }
478
    
479
    public function testSet()
480
    {
481
        $builder = $this->builderFactory();
482
        $element = (new TextFactory($this->app))->build([
483
            'text' => 'Text',
484
        ]);
485
        $notElement = [];
486
        
487
        $builder['element'] = $element;
488
        $builder['notElement'] = $notElement;
489
        
490
        $this->assertTrue($builder->has('element'));
491
        $this->assertFalse($builder->has('notElement'));
492
    }
493
494
    public function testCreateCallbackException()
495
    {
496
        $this->expectException(\RuntimeException::class);
497
498
        $builder = $this->builderFactory();
499
        $builder->create('test', Link::class, function(LinkFactory $factory) {
0 ignored issues
show
Unused Code introduced by
The parameter $factory is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
500
            return 'string';
501
        });
502
    }
503
504
    public function testCreateTypeWrongException()
505
    {
506
        $this->expectException(\RuntimeException::class);
507
508
        $builder = $this->builderFactory();
509
        $builder->create('test', \Exception::class);
510
    }
511
}