Completed
Push — master ( e84808...5a9d2e )
by Oleg
07:58
created

BuilderTest::testDisplayRules()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 20

Duplication

Lines 5
Ratio 16.67 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
c 6
b 0
f 1
dl 5
loc 30
rs 8.8571
cc 1
eloc 20
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
    }
160
161 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...
162
    {
163
        $builder = $this->builderFactory();
164
165
        $item = $builder->create('test', Link::class);
166
167
        $this->assertEquals($item, $builder->getByIndex(0));
168
        $this->assertEquals(null, $builder->getByIndex(1));
169
    }
170
    
171
    public function testHas()
172
    {
173
        $builder = $this->builderFactory();
174
175
        $this->assertFalse($builder->has('test'));
176
    }
177
    
178
    public function testType()
179
    {
180
        $builder = $this->builderFactory();
181
        
182
        $this->assertEquals(Builder::UL, $builder->getType());
183
        $builder->setType(Builder::OL);
184
        $this->assertAttributeEquals(Builder::OL, 'type', $builder);
185
    }
186
    
187 View Code Duplication
    public function testAll()
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...
188
    {
189
        $builder = $this->builderFactory();
190
        
191
        $this->assertEquals([], $builder->all());
192
        $item = $builder->create('test', Link::class);
193
        $this->assertEquals(['test' => $item], $builder->all());
194
    }
195
    
196
    public function testForget()
197
    {
198
        $builder = $this->builderFactory();
199
200
        $builder->create('test', Link::class);
201
        $this->assertTrue($builder->has('test'));
202
        $builder->forget('test');
203
        $this->assertFalse($builder->has('test'));
204
    }
205
    
206
    public function testActiveAttributes()
207
    {
208
        $builder = $this->builderFactory();
209
        $activeAttributes = $builder->getActiveAttributes();
210
        
211
        $this->assertInstanceOf(Attributes::class, $activeAttributes);
212
213
        $result = $builder->getActiveAttributes(function(Attributes $attributes) {
214
            $this->assertInstanceOf(Attributes::class, $attributes);
215
            
216
            return $attributes->get('class');
217
        });
218
        
219
        $this->assertEquals('active', $result);
220
    }
221
222
    public function testRender()
223
    {
224
        $builder = $this->builderFactory();
225
226
        $builder->create('index', Link::class, function(LinkFactory $factory) {
227
            $factory->title = 'Index Page';
228
            $factory->url = url('/');
229
            $factory->linkAttributes->push(['class' => 'menu-link']);
230
        });
231
        
232 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...
233
            $factory->attributes->push(['class' => 'child-menu']);
234
            $factory->title = 'Orders';
235
            $factory->url = 'javascript:;';
236
            
237
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
238
                $factory->title = 'All';
239
                $factory->url = url('/orders/all');
240
            });
241
            $factory->builder->create('type_1', Link::class, function(LinkFactory $factory) {
242
                $factory->title = 'Type 1';
243
                $factory->url = url('/orders/1');
244
                $factory->linkAttributes->push(['class' => 'text-color-red']);
245
            });
246
            $factory->builder->create('type_2', Link::class, function(LinkFactory $factory) {
247
                $factory->title = 'Type 2';
248
                $factory->url = url('/orders/2');
249
                $factory->linkAttributes->push(['data-attribute' => 'value']);
250
            });
251
        });
252
        
253
        $html = $builder->render();
254
        
255
        $this->assertEquals($this->getStub('menu.html'), $html);
256
    }
257
    
258
    public function testDisplayRules()
259
    {
260
        $builder = $this->builderFactory();
261
262
        $builder->create('index', Link::class, function(LinkFactory $factory) {
263
            $factory->title = 'Index Page';
264
            $factory->url = url('/');
265
        });
266
        $builder->create('login', Link::class, function(LinkFactory $factory) {
267
            $factory->title = 'Login';
268
            $factory->url = url('/login');
269
            $factory->displayRule = function() {
270
                return true;
271
            };
272
        });
273 View Code Duplication
        $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...
274
            $factory->title = 'Admin';
275
            $factory->url = url('/admin');
276
            $factory->displayRule = false;
277
        });
278
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
279
            $factory->title = 'Logout';
280
            $factory->url = url('/logout');
281
            $factory->displayRule = null;
282
        });
283
284
        $html = $builder->render();
285
286
        $this->assertEquals($this->getStub('display_rules.html'), $html);
287
    }
288
289
    public function testAnotherViewRender()
290
    {
291
        view()->addLocation(__DIR__ . '/stub');
292
        $this->app['config']->prepend('menu.paths', __DIR__ . '/stub');
293
        
294
        $builder = $this->builderFactory();
295
        $builder->create('index', Link::class, function(LinkFactory $factory) {
296
            $factory->title = 'Index Page';
297
            $factory->url = url('/');
298
        });
299 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...
300
            $factory->builder->create('one', Link::class, function(LinkFactory $factory) {
301
                $factory->title = 'One';
302
                $factory->url = url('/one');
303
            });
304
        });
305
        
306
        $this->assertEquals($this->getStub('another_menu.html'), $builder->render('another'));
307
308
        $builder->get('group')->getBuilder()->setView('another');
309
        $this->assertEquals($this->getStub('another_sub_menu.html'), $builder->render());
310
311
        $builder->setView('another');
312
        $builder->get('group')->getBuilder()->setView('menu::view');
313
        $this->assertEquals($this->getStub('another_set_view_menu.html'), $builder->render());
314
    }
315
    
316
    public function testInsert()
317
    {
318
        $builder = $this->builderFactory();
319
        $builder->create('index', Link::class, function(LinkFactory $factory) {
320
            $factory->title = 'Index Page';
321
            $factory->url = url('/');
322
        });
323
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
324
            $factory->title = 'Logout';
325
            $factory->url = url('logout');
326
        });
327
        
328 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...
329
            $builder->create('users', Link::class, function(LinkFactory $factory) {
330
                $factory->title = 'Users';
331
                $factory->url = url('users');
332
            });
333
        });
334
        
335 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...
336
            $builder->create('profile', Link::class, function(LinkFactory $factory) {
337
                $factory->title = 'Profile';
338
                $factory->url = url('profile');
339
            });
340
        });
341
342
        $this->assertEquals($this->getStub('insert.html'), $builder->render('another'));
343
    }
344
    
345
    public function testSerialization()
346
    {
347
        $builder = $this->builderFactory();
348
        $builder->create('index', Link::class, function(LinkFactory $factory) {
349
            $factory->title = 'Index';
350
            $factory->url = url('/');
351
        });
352
        $builder->create('users', SubMenu::class, function(SubMenuFactory $factory) {
353
            $factory->title = 'Users';
354
            $factory->builder->getAttributes()->put('class', 'menu');
355
            $factory->builder->create('all', Link::class, function(LinkFactory $factory) {
356
                $factory->title = 'All';
357
                $factory->url = url('/users');
358
            });
359 View Code Duplication
            $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...
360
                $factory->title = 'Admins';
361
                $factory->url = url('/users', ['role' => 'admin']);
362
                $factory->displayRule = false;
363
            });
364
            $factory->builder->create('create', SubMenu::class, function(SubMenuFactory $factory) {
365
                $factory->title = 'Create';
366
                $factory->builder->create('user', Link::class, function(LinkFactory $factory) {
367
                    $factory->title = 'User';
368
                    $factory->url = url('/users/create/user');
369
                });
370
                $factory->builder->create('role', Link::class, function(LinkFactory $factory) {
371
                    $factory->title = 'Role';
372
                    $factory->url = url('/users/create/role');
373
                });
374
            });
375
        });
376
        $builder->create('settings', Link::class, function(LinkFactory $factory) {
377
            $factory->displayRule = function () {return false;};
378
            $factory->title = 'Settings';
379
            $factory->url = url('/settings');
380
        });
381
        $builder->create('deliver', Text::class, function(TextFactory $factory) {
382
            $factory->text = '-';
383
        });
384
        $builder->create('logout', Link::class, function(LinkFactory $factory) {
385
            $factory->title = 'Logout';
386
            $factory->url = url('/logout');
387
        });
388
389
        $this->assertEquals($this->serializeStub(), serialize($builder));
390
        // $this->assertEquals($builder, $this->serializeStub()); # TODO
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
391
        // Error: 'C:20:"Malezha\Menu\Builder":4...;}}}}}' does not match expected type "object". 
392
    }
393
    
394
    public function testArray()
395
    {
396
        $builder = $this->builderFactory();
397
        $builder->create('index', Link::class, function(LinkFactory $factory) {
398
            $factory->title = 'Index';
399
            $factory->url = url('/');
400
        });
401
        $builder->create('submenu', SubMenu::class, function(SubMenuFactory $factory) {
402
            for ($i = 1; $i <= 3; ++$i) {
403
                $factory->builder->create('item_' . $i, Link::class, function(LinkFactory $factory) use ($i) {
404
                    $factory->title = 'Item ' . $i;
405
                    $factory->url = url('/item', ['id' => $i]);
406
                });
407
            }
408
        });
409
        
410
        $this->assertEquals($this->toArrayStub(), $builder->toArray());
411
412
        $builderFormArray = $builder->fromArray($builder->toArray());
413
        $this->assertEquals($builder, $builderFormArray);
414
    }
415
}