Completed
Push — master ( 39d639...38e886 )
by Oleg
04:40
created

BuilderTest::testAnotherViewRender()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 25
rs 8.8571
cc 1
eloc 18
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\Contracts\Item;
7
8
/**
9
 * Class BuilderTest
10
 * @package Malezha\Menu\Tests
11
 */
12
class BuilderTest extends TestCase
13
{
14
    /**
15
     * @return Builder
16
     */
17
    protected function builderFactory()
18
    {
19
        return $this->app->make(Builder::class, [
20
            'name' => 'test', 
21
            'activeAttributes' => $this->app->make(Attributes::class, ['attributes' => ['class' => 'active']]),
22
            'attributes' => $this->app->make(Attributes::class, ['attributes' => ['class' => 'menu']]),
23
        ]);
24
    }
25
    
26
    public function testConstructor()
27
    {
28
        $builder = $this->builderFactory();
29
30
        $this->assertAttributeEquals($this->app, 'container', $builder);
31
        $this->assertAttributeEquals('test', 'name', $builder);
32
        $this->assertAttributeEquals(Builder::UL, 'type', $builder);
33
        $this->assertAttributeInstanceOf(Attributes::class, 'attributes', $builder);
34
        $this->assertAttributeInternalType('array', 'items', $builder);
35
        $this->assertAttributeInstanceOf(Attributes::class, 'activeAttributes', $builder);
36
    }
37
38
    public function testAdd()
39
    {
40
        $builder = $this->builderFactory();
41
42
        $item = $builder->add('index', 'Index', '/', ['class' => 'main-menu'], ['class' => 'link'],
43
            function(Item $item) {
44
                $this->assertAttributeEquals('Index', 'title', $item->getLink());
45
                $item->getLink()->setTitle('Home');
46
            });
47
48
        $this->assertAttributeEquals($builder, 'builder', $item);
49
        $this->assertAttributeInstanceOf(Attributes::class, 'attributes', $item);
50
51
        $link = $item->getLink();
52
        $this->assertAttributeEquals('Home', 'title', $link);
53
        $this->assertAttributeEquals('/', 'url', $link);
54
    }
55
    
56
    public function testGet()
57
    {
58
        $builder = $this->builderFactory();
59
        
60
        $item = $builder->add('test', 'Test', '/test');
61
        
62
        $this->assertEquals($item, $builder->get('test'));
63
    }
64
    
65
    public function testHas()
66
    {
67
        $builder = $this->builderFactory();
68
69
        $this->assertFalse($builder->has('test'));
70
    }
71
    
72
    public function testType()
73
    {
74
        $builder = $this->builderFactory();
75
        
76
        $this->assertEquals(Builder::UL, $builder->getType());
77
        $builder->setType(Builder::OL);
78
        $this->assertAttributeEquals(Builder::OL, 'type', $builder);
79
    }
80
    
81
    public function testAll()
82
    {
83
        $builder = $this->builderFactory();
84
        
85
        $this->assertEquals([], $builder->all());
86
        $item = $builder->add('test', 'Test', '/test');
87
        $this->assertEquals(['test' => $item], $builder->all());
88
    }
89
    
90
    public function testForget()
91
    {
92
        $builder = $this->builderFactory();
93
94
        $builder->add('test', 'Test', '/test');
95
        $this->assertTrue($builder->has('test'));
96
        $builder->forget('test');
97
        $this->assertFalse($builder->has('test'));
98
    }
99
    
100
    public function testActiveAttributes()
101
    {
102
        $builder = $this->builderFactory();
103
        $activeAttributes = $builder->activeAttributes();
104
        
105
        $this->assertInstanceOf(Attributes::class, $activeAttributes);
106
107
        $result = $builder->activeAttributes(function(Attributes $attributes) {
108
            $this->assertInstanceOf(Attributes::class, $attributes);
109
            
110
            return $attributes->get('class');
111
        });
112
        
113
        $this->assertEquals('active', $result);
114
    }
115
    
116
    public function testGroup()
117
    {
118
        $builder = $this->builderFactory();
119
        
120
        $group = $builder->group('test', function(Item $item) use ($builder) {
121
            $this->assertAttributeEquals($builder, 'builder', $item);
122
        }, function(Builder $menu) use ($builder) {
123
            $this->assertEquals($builder->activeAttributes()->all(), $menu->activeAttributes()->all());
124
        });
125
126
        $this->assertEquals($group, $builder->get('test'));
127
    }
128
129
    public function testRender()
130
    {
131
        $builder = $this->builderFactory();
132
133
        $index = $builder->add('index', 'Index Page', url('/'));
1 ignored issue
show
Bug introduced by
It seems like url('/') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
134
        $index->getLink()->getAttributes()->push(['class' => 'menu-link']);
135
136
        $builder->group('orders', function(Item $item) {
137
            $item->getAttributes()->push(['class' => 'child-menu']);
138
            
139
            $link = $item->getLink();
140
            $link->setTitle('Orders');
141
            $link->setUrl('javascript:;');
142
143
        }, function(Builder $menu) {
144
            $menu->add('all', 'All', url('/orders/all'));
0 ignored issues
show
Bug introduced by
It seems like url('/orders/all') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
145
            $menu->add('type_1', 'Type 1', url('/orders/1'), [], ['class' => 'text-color-red']);
0 ignored issues
show
Bug introduced by
It seems like url('/orders/1') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
146
147
            $menu->add('type_2', 'Type 2', url('/orders/2'), [], [], function(Item $item) {
0 ignored issues
show
Bug introduced by
It seems like url('/orders/2') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
148
                $item->getLink()->getAttributes()->push(['data-attribute' => 'value']);
149
            });
150
        });
151
        
152
        $html = $builder->render();
153
        $file = file_get_contents(__DIR__ . '/stub/menu.html');
154
        
155
        $this->assertEquals($file, $html);
156
    }
157
    
158
    public function testDisplayRules()
159
    {
160
        $builder = $this->builderFactory();
161
162
        $builder->add('index', 'Index Page', url('/'));
1 ignored issue
show
Bug introduced by
It seems like url('/') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
163
        $builder->add('login', 'Login', url('/login'))->setDisplayRule(function() {
0 ignored issues
show
Bug introduced by
It seems like url('/login') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
164
            return true;
165
        });
166
        $builder->add('admin', 'Admin', url('/admin'))->setDisplayRule(false);
0 ignored issues
show
Bug introduced by
It seems like url('/admin') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
167
        $builder->add('logout', 'Logout', url('/logout'))->setDisplayRule(null);
0 ignored issues
show
Bug introduced by
It seems like url('/logout') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
168
169
        $html = $builder->render();
170
        $file = file_get_contents(__DIR__ . '/stub/display_rules.html');
171
172
        $this->assertEquals($file, $html);
173
    }
174
175
    public function testAnotherViewRender()
176
    {
177
        view()->addLocation(__DIR__ . '/stub');
178
        
179
        $builder = $this->builderFactory();
180
        $builder->add('index', 'Index Page', url('/'));
1 ignored issue
show
Bug introduced by
It seems like url('/') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
181
        $builder->group('group', function(Item $item){}, function(Builder $menu) {
0 ignored issues
show
Unused Code introduced by
The parameter $item 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...
182
            $menu->add('one', 'One', url('/one'));
1 ignored issue
show
Bug introduced by
It seems like url('/one') targeting url() can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Malezha\Menu\Contracts\Builder::add() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
183
        });
184
185
        $html = $builder->render('another');
186
        $file = file_get_contents(__DIR__ . '/stub/another_menu.html');
187
        $this->assertEquals($file, $html);
188
189
        $builder->get('group')->getMenu()->setView('another');
0 ignored issues
show
Bug introduced by
The method getMenu does only exist in Malezha\Menu\Contracts\Group, but not in Malezha\Menu\Contracts\Item.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
190
        $html = $builder->render();
191
        $file = file_get_contents(__DIR__ . '/stub/another_sub_menu.html');
192
        $this->assertEquals($file, $html);
193
194
        $builder->setView('another');
195
        $builder->get('group')->getMenu()->setView('menu::view');
196
        $html = $builder->render();
197
        $file = file_get_contents(__DIR__ . '/stub/another_set_view_menu.html');
198
        $this->assertEquals($file, $html);
199
    }
200
}