Completed
Branch master (db83f9)
by Arnold
03:38
created

TypeFunctionsTest   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 66
dl 0
loc 224
rs 10
c 0
b 0
f 0
wmc 14

13 Methods

Rating   Name   Duplication   Size   Complexity  
A testExpectTypeExplicitMessage() 0 3 1
A testExpectType() 0 10 2
A testIsAssociativeArray() 0 3 1
A testObjectifyCircularReference() 0 3 1
A circularReferenceProvider() 0 10 1
A testIsNumericArray() 0 3 1
A varProvider() 0 11 1
A testArrayify() 0 3 1
A arrayifyProvider() 0 26 1
A objectifyProvider() 0 34 1
A testObjectify() 0 3 1
A testArrayifyCircularReference() 0 3 1
A expectTypeProvider() 0 11 1
1
<?php
2
3
namespace Jasny\Tests;
4
5
use PHPStan\Testing\TestCase;
6
7
use function Jasny\expect_type;
8
use function Jasny\is_associative_array;
9
use function Jasny\is_numeric_array;
10
use function Jasny\objectify;
11
use function Jasny\arrayify;
12
13
/**
14
 * Test type functions
15
 * @coversNothing
16
 */
17
class TypeFunctionsTest extends TestCase
18
{
19
    const NONE = 0;
20
    const NUMERIC = 1;
21
    const ASSOC = 2;
22
    
23
    public function varProvider()
24
    {
25
        return [
26
            [['foo', 'bar'], self::NUMERIC],
27
            [['a' => 'foo', 'b' => 'bar'], self::ASSOC],
28
            [[1 => 'foo', 'bar'], self::ASSOC],
29
            [['foo', 'b' => 'bar'], self::ASSOC],
30
            [['foo', 2 => 'bar'], self::ASSOC],
31
            [[], self::NUMERIC],
32
            ['foo', self::NONE],
33
            [(object)['a' => 'b'], self::NONE]
34
        ];
35
    }
36
    
37
    /**
38
     * @covers Jasny\is_associative_array
39
     * @dataProvider varProvider
40
     * 
41
     * @param mixed $var
42
     * @param int   $type
43
     */
44
    public function testIsAssociativeArray($var, $type)
45
    {
46
        $this->assertEquals($type === self::ASSOC, is_associative_array($var));
47
    }
48
    
49
    /**
50
     * @covers Jasny\is_numeric_array
51
     * @dataProvider varProvider
52
     * 
53
     * @param mixed $var
54
     * @param int   $type
55
     */
56
    public function testIsNumericArray($var, $type)
57
    {
58
        $this->assertEquals($type === self::NUMERIC, is_numeric_array($var));
59
    }
60
    
61
    
62
    public function objectifyProvider()
63
    {
64
        return [
65
            [
66
                'foo',
67
                'foo'
68
            ],
69
            [
70
                ['a' => 'foo'],
71
                (object)['a' => 'foo']
72
            ],
73
            [
74
                ['foo', 'bar', 'zoo'],
75
                ['foo', 'bar', 'zoo']
76
            ],
77
            [
78
                ['a' => ['b' => ['c' => 'foo']]],
79
                (object)['a' => (object)['b' => (object)['c' => 'foo']]]
80
            ],
81
            [
82
                (object)['a' => ['b' => ['c' => 'foo']]],
83
                (object)['a' => (object)['b' => (object)['c' => 'foo']]]
84
            ],
85
            [
86
                ['a' => 'foo', 'b' => ['bar', 'zoo'], 'c' => true],
87
                (object)['a' => 'foo', 'b' => ['bar', 'zoo'], 'c' => true]
88
            ],
89
            [
90
                [1 => 'a', 'b'],
91
                (object)['1' => 'a', '2' => 'b']
92
            ],
93
            [
94
                [],
95
                []
96
            ]
97
        ];
98
    }
99
    
100
    /**
101
     * @covers Jasny\objectify
102
     * @dataProvider objectifyProvider
103
     * 
104
     * @param mixed $var
105
     * @param mixed $expect
106
     */
107
    public function testObjectify($var, $expect)
108
    {
109
        $this->assertEquals($expect, objectify($var));
110
    }
111
    
112
    
113
    public function arrayifyProvider()
114
    {
115
        return [
116
            [
117
                'foo',
118
                'foo'
119
            ],
120
            [
121
                (object)['a' => 'foo'],
122
                ['a' => 'foo']
123
            ],
124
            [
125
                (object)['a' => (object)['b' => (object)['c' => 'foo']]],
126
                ['a' => ['b' => ['c' => 'foo']]],
127
            ],
128
            [
129
                ['a' => (object)['b' => (object)['c' => 'foo']]],
130
                ['a' => ['b' => ['c' => 'foo']]]
131
            ],
132
            [
133
                (object)['date' => new \DateTime('2000-01-01')],
134
                ['date' => new \DateTime('2000-01-01')]
135
            ],
136
            [
137
                new \stdClass(),
138
                []
139
            ]
140
        ];
141
    }
142
    
143
    /**
144
     * @covers Jasny\arrayify
145
     * @dataProvider arrayifyProvider
146
     * 
147
     * @param mixed $var
148
     * @param mixed $expect
149
     */
150
    public function testArrayify($var, $expect)
151
    {
152
        $this->assertEquals($expect, arrayify($var));
153
    }
154
155
    
156
    public function circularReferenceProvider()
157
    {
158
        $object = new \stdClass();
159
        $object->items = [
160
            'foo',
161
            $object
162
        ];
163
        
164
        return [
165
            [$object]
166
        ];
167
    }
168
    
169
    /**
170
     * @covers Jasny\objectify
171
     * @dataProvider circularReferenceProvider
172
     * 
173
     * @expectedException \OverflowException
174
     * @expectedExceptionMessage Maximum recursion depth reached. Possible circular reference.
175
     * 
176
     * @param stdClass $object
0 ignored issues
show
Bug introduced by
The type Jasny\Tests\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
177
     */
178
    public function testObjectifyCircularReference(\stdClass $object)
179
    {
180
        objectify($object);
181
    }
182
    
183
    /**
184
     * @covers Jasny\arrayify
185
     * @dataProvider circularReferenceProvider
186
     * 
187
     * @expectedException \OverflowException
188
     * @expectedExceptionMessage Maximum recursion depth reached. Possible circular reference.
189
     * 
190
     * @param stdClass $object
191
     */
192
    public function testArrayifyCircularReference(\stdClass $object)
193
    {
194
        arrayify($object);
195
    }
196
197
    
198
    public function expectTypeProvider()
199
    {
200
        return [
201
            [10, 'int'],
202
            [true, 'bool'],
203
            [[], 'array'],
204
            [(object)[], 'stdClass'],
205
            [10, ['int', 'boolean']],
206
            ['foo', 'int', "Expected int, string given"],
207
            ['foo', ['int', 'boolean'], "Expected int or boolean, string given"],
208
            [(object)[], 'Foo', "Expected Foo object, stdClass object given"],
209
        ];
210
    }
211
    
212
    /**
213
     * @covers Jasny\expect_type
214
     * @dataProvider expectTypeProvider
215
     * 
216
     * @param mixed           $var
217
     * @param string|string[] $type
218
     * @param string|false    $error
219
     */
220
    public function testExpectType($var, $type, $error = false)
221
    {
222
        if ($error) {
223
            $this->expectException(\InvalidArgumentException::class);
224
            $this->expectExceptionMessage($error);
225
        }
226
        
227
        expect_type($var, $type, \InvalidArgumentException::class);
228
229
        $this->assertTrue(true); // No warnings
230
    }
231
    
232
    /**
233
     * @covers Jasny\expect_type
234
     * 
235
     * @expectedException Exception
236
     * @expectedExceptionMessage Lorem ipsum string black
237
     */
238
    public function testExpectTypeExplicitMessage()
239
    {
240
        expect_type('foo', 'int', \Exception::class, "Lorem ipsum %s black");
241
    }
242
}
243