Completed
Push — master ( 5a9d2e...4895be )
by Oleg
04:31
created

BuilderTest::testInsertExceptionHasNot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 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->make(Builder::class, [
25
            'activeAttributes' => $this->app->make(Attributes::class, ['attributes' => ['class' => 'active']]),
26
            'attributes' => $this->app->make(Attributes::class, ['attributes' => ['class' => 'menu']]),
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
134
        $this->assertAttributeEquals(['index' => $item], 'elements', $builder);
135
        $this->assertAttributeEquals(['index' => 0], 'indexes', $builder);
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);
148
        $builder->create('index', SubMenu::class); // Duplicate
149
    }
150
    
151 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...
152
    {
153
        $builder = $this->builderFactory();
154
        
155
        $item = $builder->create('test', Link::class);
156
        
157
        $this->assertEquals($item, $builder->get('test'));
158
        $this->assertEquals(null, $builder->get('notFound'));
159
        $this->assertEquals($item, $builder['test']);
160
        $this->assertEquals(null, $builder['notFound']);
161
    }
162
163 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...
164
    {
165
        $builder = $this->builderFactory();
166
167
        $item = $builder->create('test', Link::class);
168
169
        $this->assertEquals($item, $builder->getByIndex(0));
170
        $this->assertEquals(null, $builder->getByIndex(1));
171
        $this->assertEquals($item, $builder[0]);
172
        $this->assertEquals(null, $builder[1]);
173
    }
174
    
175
    public function testHas()
176
    {
177
        $builder = $this->builderFactory();
178
179
        $this->assertFalse($builder->has('test'));
180
        $this->assertFalse(isset($builder['test']));
181
    }
182
    
183
    public function testType()
184
    {
185
        $builder = $this->builderFactory();
186
        
187
        $this->assertEquals(Builder::UL, $builder->getType());
188
        $builder->setType(Builder::OL);
189
        $this->assertAttributeEquals(Builder::OL, 'type', $builder);
190
    }
191
    
192
    public function testAll()
193
    {
194
        $builder = $this->builderFactory();
195
        
196
        $this->assertEquals([], $builder->all());
197
        $item = $builder->create('test', Link::class);
198
        $this->assertEquals(['test' => $item], $builder->all());
199
    }
200
    
201
    public function testForget()
202
    {
203
        $builder = $this->builderFactory();
204
205
        $builder->create('test', Link::class);
206
        $builder->create('another', Text::class);
207
        
208
        $this->assertTrue($builder->has('test'));
209
        $builder->forget('test');
210
        $this->assertFalse($builder->has('test'));
211
        
212
        $this->assertTrue($builder->has('another'));
213
        unset($builder['another']);
214
        $this->assertFalse($builder->has('another'));
215
    }
216
    
217
    public function testActiveAttributes()
218
    {
219
        $builder = $this->builderFactory();
220
        $activeAttributes = $builder->getActiveAttributes();
221
        
222
        $this->assertInstanceOf(Attributes::class, $activeAttributes);
223
224
        $result = $builder->getActiveAttributes(function(Attributes $attributes) {
225
            $this->assertInstanceOf(Attributes::class, $attributes);
226
            
227
            return $attributes->get('class');
228
        });
229
        
230
        $this->assertEquals('active', $result);
231
    }
232
233
    public function testRender()
234
    {
235
        $builder = $this->builderFactory();
236
237
        $builder->create('index', Link::class, function(LinkFactory $factory) {
238
            $factory->title = 'Index Page';
239
            $factory->url = url('/');
240
            $factory->linkAttributes->push(['class' => 'menu-link']);
241
        });
242
        
243 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...
244
            $factory->attributes->push(['class' => 'child-menu']);
245
            $factory->title = 'Orders';
246
            $factory->url = 'javascript:;';
247
            
248
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
249
                $factory->title = 'All';
250
                $factory->url = url('/orders/all');
251
            });
252
            $factory->builder->create('type_1', Link::class, function(LinkFactory $factory) {
253
                $factory->title = 'Type 1';
254
                $factory->url = url('/orders/1');
255
                $factory->linkAttributes->push(['class' => 'text-color-red']);
256
            });
257
            $factory->builder->create('type_2', Link::class, function(LinkFactory $factory) {
258
                $factory->title = 'Type 2';
259
                $factory->url = url('/orders/2');
260
                $factory->linkAttributes->push(['data-attribute' => 'value']);
261
            });
262
        });
263
        
264
        $html = $builder->render();
265
        
266
        $this->assertEquals($this->getStub('menu.html'), $html);
267
    }
268
    
269
    public function testDisplayRules()
270
    {
271
        $builder = $this->builderFactory();
272
273
        $builder->create('index', Link::class, function(LinkFactory $factory) {
274
            $factory->title = 'Index Page';
275
            $factory->url = url('/');
276
        });
277
        $builder->create('login', Link::class, function(LinkFactory $factory) {
278
            $factory->title = 'Login';
279
            $factory->url = url('/login');
280
            $factory->displayRule = function() {
281
                return true;
282
            };
283
        });
284
        $builder->create('admin', Link::class, function(LinkFactory $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...
285
            $factory->title = 'Admin';
286
            $factory->url = url('/admin');
287
            $factory->displayRule = false;
288
        });
289
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
290
            $factory->title = 'Logout';
291
            $factory->url = url('/logout');
292
            $factory->displayRule = null;
293
        });
294
295
        $html = $builder->render();
296
297
        $this->assertEquals($this->getStub('display_rules.html'), $html);
298
    }
299
300
    public function testAnotherViewRender()
301
    {
302
        view()->addLocation(__DIR__ . '/stub');
303
        $this->app['config']->prepend('menu.paths', __DIR__ . '/stub');
304
        
305
        $builder = $this->builderFactory();
306
        $builder->create('index', Link::class, function(LinkFactory $factory) {
307
            $factory->title = 'Index Page';
308
            $factory->url = url('/');
309
        });
310 View Code Duplication
        $builder->create('group', 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...
311
            $factory->builder->create('one', Link::class, function(LinkFactory $factory) {
312
                $factory->title = 'One';
313
                $factory->url = url('/one');
314
            });
315
        });
316
        
317
        $this->assertEquals($this->getStub('another_menu.html'), $builder->render('another'));
318
319
        $builder->get('group')->getBuilder()->setView('another');
320
        $this->assertEquals($this->getStub('another_sub_menu.html'), $builder->render());
321
322
        $builder->setView('another');
323
        $builder->get('group')->getBuilder()->setView('menu::view');
324
        $this->assertEquals($this->getStub('another_set_view_menu.html'), $builder->render());
325
    }
326
    
327
    public function testInsert()
328
    {
329
        $builder = $this->builderFactory();
330
        $builder->create('index', Link::class, function(LinkFactory $factory) {
331
            $factory->title = 'Index Page';
332
            $factory->url = url('/');
333
        });
334
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
335
            $factory->title = 'Logout';
336
            $factory->url = url('logout');
337
        });
338
        
339
        $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...
340
            $builder->create('users', Link::class, function(LinkFactory $factory) {
341
                $factory->title = 'Users';
342
                $factory->url = url('users');
343
            });
344
        });
345
        
346
        $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...
347
            $builder->create('profile', Link::class, function(LinkFactory $factory) {
348
                $factory->title = 'Profile';
349
                $factory->url = url('profile');
350
            });
351
        });
352
353
        $this->assertEquals($this->getStub('insert.html'), $builder->render('another'));
354
    }
355
356
    public function testInsertExceptionHasNot()
357
    {
358
        $this->expectException(\RuntimeException::class);
359
360
        $builder = $this->builderFactory();
361
        $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...
362
    }
363
364
    public function testInsertExceptionDuplicate()
365
    {
366
        $this->expectException(\RuntimeException::class);
367
368
        $builder = $this->builderFactory();
369
        $builder->create('home', Link::class, function(LinkFactory $factory) {
370
            $factory->title = 'Home';
371
            $factory->url = '/';
372
        });
373
        $builder->create('some', Link::class, function(LinkFactory $factory) {
374
            $factory->title = 'Some';
375
            $factory->url = '/';
376
        });
377
        $builder->insertAfter('home', function (Builder $builder) {
378
            $builder->create('some', Text::class, function(TextFactory $factory) {
379
                $factory->text = 'Duplicate some';
380
            });
381
        });
382
    }
383
    
384
    public function testSerialization()
385
    {
386
        $builder = $this->builderFactory();
387
        $builder->create('index', Link::class, function(LinkFactory $factory) {
388
            $factory->title = 'Index';
389
            $factory->url = url('/');
390
        });
391
        $builder->create('users', SubMenu::class, function(SubMenuFactory $factory) {
392
            $factory->title = 'Users';
393
            $factory->builder->getAttributes()->put('class', 'menu');
394
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
395
                $factory->title = 'All';
396
                $factory->url = url('/users');
397
            });
398
            $factory->builder->create('admins', Link::class, function(LinkFactory $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...
399
                $factory->title = 'Admins';
400
                $factory->url = url('/users', ['role' => 'admin']);
401
                $factory->displayRule = false;
402
            });
403
            $factory->builder->create('create', SubMenu::class, function(SubMenuFactory $factory) {
404
                $factory->title = 'Create';
405
                $factory->builder->create('user', Link::class, function(LinkFactory $factory) {
406
                    $factory->title = 'User';
407
                    $factory->url = url('/users/create/user');
408
                });
409
                $factory->builder->create('role', Link::class, function(LinkFactory $factory) {
410
                    $factory->title = 'Role';
411
                    $factory->url = url('/users/create/role');
412
                });
413
            });
414
        });
415
        $builder->create('settings', Link::class, function(LinkFactory $factory) {
416
            $factory->displayRule = function () {return false;};
417
            $factory->title = 'Settings';
418
            $factory->url = url('/settings');
419
        });
420
        $builder->create('deliver', Text::class, function(TextFactory $factory) {
421
            $factory->text = '-';
422
        });
423
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
424
            $factory->title = 'Logout';
425
            $factory->url = url('/logout');
426
        });
427
428
        $this->assertEquals($this->serializeStub(), serialize($builder));
429
        $this->assertEquals($builder, unserialize($this->serializeStub()));
430
    }
431
    
432
    public function testArray()
433
    {
434
        $builder = $this->builderFactory();
435
        $builder->create('index', Link::class, function(LinkFactory $factory) {
436
            $factory->title = 'Index';
437
            $factory->url = url('/');
438
        });
439
        $builder->create('submenu', SubMenu::class, function(SubMenuFactory $factory) {
440
            for ($i = 1; $i <= 3; ++$i) {
441
                $factory->builder->create('item_' . $i, Link::class, function(LinkFactory $factory) use ($i) {
442
                    $factory->title = 'Item ' . $i;
443
                    $factory->url = url('/item', ['id' => $i]);
444
                });
445
            }
446
        });
447
        
448
        $this->assertEquals($this->toArrayStub(), $builder->toArray());
449
450
        $builderFormArray = $builder->fromArray($builder->toArray());
451
        $this->assertEquals($builder, $builderFormArray);
452
    }
453
    
454
    public function testSet()
455
    {
456
        $builder = $this->builderFactory();
457
        $element = (new TextFactory($this->app))->build([
458
            'text' => 'Text',
459
        ]);
460
        $notElement = [];
461
        
462
        $builder['element'] = $element;
463
        $builder['notElement'] = $notElement;
464
        
465
        $this->assertTrue($builder->has('element'));
466
        $this->assertFalse($builder->has('notElement'));
467
    }
468
}