1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* PHP: Nelson Martell Library file |
5
|
|
|
* |
6
|
|
|
* Copyright © 2016-2021 Nelson Martell (http://nelson6e65.github.io) |
7
|
|
|
* |
8
|
|
|
* Licensed under The MIT License (MIT) |
9
|
|
|
* For full copyright and license information, please see the LICENSE |
10
|
|
|
* Redistributions of files must retain the above copyright notice. |
11
|
|
|
* |
12
|
|
|
* @copyright 2016-2021 Nelson Martell |
13
|
|
|
* @link http://nelson6e65.github.io/php_nml/ |
14
|
|
|
* @since v0.6.0 |
15
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT) |
16
|
|
|
* */ |
17
|
|
|
|
18
|
|
|
declare(strict_types=1); |
19
|
|
|
|
20
|
|
|
namespace NelsonMartell\Test\TestCase; |
21
|
|
|
|
22
|
|
|
use stdClass; |
23
|
|
|
use NelsonMartell\Test\DataProviders\TypeTestProvider; |
24
|
|
|
use NelsonMartell\Type; |
25
|
|
|
use PHPUnit\Framework\TestCase; |
26
|
|
|
use SebastianBergmann\Exporter\Exporter; |
27
|
|
|
|
28
|
|
|
use function NelsonMartell\typeof; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @coversDefaultClass NelsonMartell\Type |
32
|
|
|
* |
33
|
|
|
* @author Nelson Martell <[email protected]> |
34
|
|
|
* @internal |
35
|
|
|
* */ |
36
|
|
|
class TypeTest extends TestCase |
37
|
|
|
{ |
38
|
|
|
use TypeTestProvider; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* |
42
|
|
|
* @var Exporter |
43
|
|
|
*/ |
44
|
|
|
public $exporter = null; |
45
|
|
|
|
46
|
|
|
public function setUp(): void |
47
|
|
|
{ |
48
|
|
|
$this->exporter = new Exporter(); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
public function getTargetClassName(): string |
52
|
|
|
{ |
53
|
|
|
return Type::class; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @covers ::hasMethod |
58
|
|
|
* |
59
|
|
|
* @dataProvider hasMethodProvider |
60
|
|
|
* |
61
|
|
|
* @param mixed $obj |
62
|
|
|
* @param string $name Method name. |
63
|
|
|
*/ |
64
|
|
|
public function testCanCheckIfAClassHasAMethod($obj, string $name): void |
65
|
|
|
{ |
66
|
|
|
$type = new Type($obj); |
67
|
|
|
|
68
|
|
|
$this->assertTrue($type->hasMethod($name)); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @covers ::hasMethod |
73
|
|
|
* |
74
|
|
|
* @dataProvider hasNotMethodProvider |
75
|
|
|
* |
76
|
|
|
* @param mixed $obj |
77
|
|
|
* @param string $name Method name. |
78
|
|
|
*/ |
79
|
|
|
public function testCanCheckIfAClassHasNotAMethod($obj, string $name): void |
80
|
|
|
{ |
81
|
|
|
$type = new Type($obj); |
82
|
|
|
|
83
|
|
|
$this->assertFalse($type->hasMethod($name)); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @covers ::isNull |
89
|
|
|
* @covers ::isNotNull |
90
|
|
|
* @dataProvider goodConstructorArgumentsProvider |
91
|
|
|
* |
92
|
|
|
* @param mixed $obj |
93
|
|
|
*/ |
94
|
|
|
public function testCanCheckIfTypeIsNull($obj): void |
95
|
|
|
{ |
96
|
|
|
if (is_null($obj)) { |
97
|
|
|
$actual = (new Type($obj))->isNull(); |
98
|
|
|
} else { |
99
|
|
|
$actual = (new Type($obj))->isNotNull(); |
|
|
|
|
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$this->assertTrue($actual); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @dataProvider goodConstructorArgumentsProvider |
107
|
|
|
* |
108
|
|
|
* @param mixed $obj |
109
|
|
|
*/ |
110
|
|
|
public function testCanCheckIfTypeIsCustom($obj): void |
111
|
|
|
{ |
112
|
|
|
$actual = (new Type($obj))->isCustom(); |
113
|
|
|
|
114
|
|
|
if (gettype($obj) == 'object') { |
115
|
|
|
$this->assertTrue($actual); |
116
|
|
|
} else { |
117
|
|
|
$this->assertFalse($actual); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @dataProvider canBeStringProvider |
123
|
|
|
* |
124
|
|
|
* @param array $args Arguments of constructor |
125
|
|
|
*/ |
126
|
|
|
public function testCanCheckIfTypeCanBeConvertedToString(...$args): void |
127
|
|
|
{ |
128
|
|
|
$type = new Type(...$args); |
|
|
|
|
129
|
|
|
|
130
|
|
|
$actual = $type->canBeString(); |
131
|
|
|
|
132
|
|
|
$this->assertTrue($actual); |
133
|
|
|
} |
134
|
|
|
/** |
135
|
|
|
* @dataProvider canNotBeStringProvider |
136
|
|
|
* |
137
|
|
|
* @param array $args Arguments of constructor |
138
|
|
|
*/ |
139
|
|
|
public function testCanCheckIfTypeCanNotBeConvertedToString(...$args): void |
140
|
|
|
{ |
141
|
|
|
$type = new Type(...$args); |
|
|
|
|
142
|
|
|
|
143
|
|
|
$actual = $type->canBeString(); |
144
|
|
|
|
145
|
|
|
$this->assertFalse($actual); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @dataProvider goodConstructorArgumentsProvider |
150
|
|
|
* |
151
|
|
|
* @param mixed $obj |
152
|
|
|
* |
153
|
|
|
* @since 1.0.0 |
154
|
|
|
*/ |
155
|
|
|
public function testTypesEquality($obj): void |
156
|
|
|
{ |
157
|
|
|
$t1 = new Type($obj); |
158
|
|
|
$t2 = new Type($obj); |
159
|
|
|
|
160
|
|
|
$this->assertTrue($t1->equals($t2)); |
161
|
|
|
$this->assertTrue($t2->equals($t1)); |
162
|
|
|
$this->assertFalse($t1->equals($obj)); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* |
167
|
|
|
* @depends testTypesEquality |
168
|
|
|
* @since 1.0.0 |
169
|
|
|
*/ |
170
|
|
|
public function testTypesInequality(): void |
171
|
|
|
{ |
172
|
|
|
$t1 = new Type(new stdClass()); |
173
|
|
|
$t2 = new Type(new stdClass()); |
174
|
|
|
|
175
|
|
|
$this->assertTrue($t1->equals($t2)); |
176
|
|
|
$this->assertTrue($t2->equals($t1)); |
177
|
|
|
|
178
|
|
|
|
179
|
|
|
$t1 = new Type('1'); |
180
|
|
|
$t2 = new Type(1); |
181
|
|
|
|
182
|
|
|
$this->assertFalse($t1->equals($t2)); |
183
|
|
|
$this->assertFalse($t2->equals($t1)); |
184
|
|
|
|
185
|
|
|
$t1 = new Type(2.0); |
186
|
|
|
$t2 = new Type(2); |
187
|
|
|
|
188
|
|
|
$this->assertFalse($t1->equals($t2)); |
189
|
|
|
$this->assertFalse($t2->equals($t1)); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Pruebas para Type::is() |
194
|
|
|
* |
195
|
|
|
* @dataProvider methodIsProvider |
196
|
|
|
* |
197
|
|
|
* @param bool $expected |
198
|
|
|
* @param mixed $type |
199
|
|
|
* @param array $args |
200
|
|
|
* @return void |
201
|
|
|
*/ |
202
|
|
|
public function testIsMethod(bool $expected, $type, array $args): void |
203
|
|
|
{ |
204
|
|
|
$this->assertEquals($expected, typeof($type)->is(...$args)); |
205
|
|
|
$this->assertNotEquals(!$expected, typeof($type)->is(...$args)); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Pruebas para Type::isIn() |
210
|
|
|
* |
211
|
|
|
* @dataProvider methodIsInProvider |
212
|
|
|
* |
213
|
|
|
* @param bool $expected |
214
|
|
|
* @param mixed $type |
215
|
|
|
* @param array $args |
216
|
|
|
* @return void |
217
|
|
|
*/ |
218
|
|
|
public function testIsInMethod(bool $expected, $type, array $args): void |
219
|
|
|
{ |
220
|
|
|
$this->assertEquals($expected, typeof($type)->isIn(...$args)); |
221
|
|
|
$this->assertNotEquals(!$expected, typeof($type)->isIn(...$args)); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* @dataProvider getInterfacesProvider |
226
|
|
|
* |
227
|
|
|
* @param mixed $obj |
228
|
|
|
* @param array $interfaces |
229
|
|
|
*/ |
230
|
|
|
public function testGetInterfaces($obj, array $interfaces): void |
231
|
|
|
{ |
232
|
|
|
$type = new Type($obj); |
233
|
|
|
|
234
|
|
|
$reflections = $type->getInterfaces(true); |
235
|
|
|
$strings = $type->getInterfaces(); |
236
|
|
|
|
237
|
|
|
$this->assertIsArray($reflections); |
238
|
|
|
$this->assertIsArray($strings); |
239
|
|
|
|
240
|
|
|
$this->assertCount(count($interfaces), $reflections); |
241
|
|
|
$this->assertCount(count($interfaces), $strings); |
242
|
|
|
|
243
|
|
|
if (count($interfaces) > 0) { |
244
|
|
|
sort($interfaces); |
245
|
|
|
sort($strings); |
246
|
|
|
ksort($reflections); |
247
|
|
|
|
248
|
|
|
$this->assertEquals($interfaces, $strings); |
249
|
|
|
$this->assertEquals($strings, array_keys($reflections)); |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* @dataProvider getTraitsProvider |
255
|
|
|
* |
256
|
|
|
* @param mixed $obj |
257
|
|
|
* @param array $traits |
258
|
|
|
*/ |
259
|
|
|
public function testGetExplicitTraitsInClass($obj, array $traits): void |
260
|
|
|
{ |
261
|
|
|
if ($obj instanceof Type) { |
262
|
|
|
$type = $obj; |
263
|
|
|
} else { |
264
|
|
|
$type = new Type($obj); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$reflections = $type->getTraits(true); |
268
|
|
|
$strings = $type->getTraits(); |
269
|
|
|
|
270
|
|
|
$this->assertIsArray($reflections); |
271
|
|
|
$this->assertIsArray($strings); |
272
|
|
|
|
273
|
|
|
$this->assertCount(count($strings), $reflections, 'Not same count for strings and reflections'); |
274
|
|
|
$this->assertCount(count($traits), $reflections); |
275
|
|
|
$this->assertCount(count($traits), $strings); |
276
|
|
|
|
277
|
|
|
if (count($traits) > 0) { |
278
|
|
|
sort($traits); |
279
|
|
|
sort($strings); |
280
|
|
|
ksort($reflections); |
281
|
|
|
|
282
|
|
|
$this->assertEquals($traits, $strings); |
283
|
|
|
$this->assertEquals($strings, array_keys($reflections)); |
284
|
|
|
} |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* @dataProvider getRecursiveTraitsProvider |
289
|
|
|
* |
290
|
|
|
* @param Type|mixed $obj |
291
|
|
|
* @param array $traits |
292
|
|
|
*/ |
293
|
|
|
public function testGetAllRecursiveTraitsInClass($obj, array $traits): void |
294
|
|
|
{ |
295
|
|
|
if ($obj instanceof Type) { |
296
|
|
|
$type = $obj; |
297
|
|
|
} else { |
298
|
|
|
$type = new Type($obj); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
$reflections = $type->getTraits(true, true); |
302
|
|
|
$strings = $type->getTraits(false, true); |
303
|
|
|
|
304
|
|
|
$this->assertIsArray($reflections); |
305
|
|
|
$this->assertIsArray($strings); |
306
|
|
|
|
307
|
|
|
$this->assertCount(count($strings), $reflections, 'Not same count for strings and reflections'); |
308
|
|
|
$this->assertCount(count($traits), $reflections); |
309
|
|
|
$this->assertCount(count($traits), $strings); |
310
|
|
|
|
311
|
|
|
if (count($traits) > 0) { |
312
|
|
|
sort($traits); |
313
|
|
|
sort($strings); |
314
|
|
|
ksort($reflections); |
315
|
|
|
|
316
|
|
|
$this->assertEquals($traits, $strings); |
317
|
|
|
$this->assertEquals($strings, array_keys($reflections)); |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* @dataProvider hasPropertyProvider |
323
|
|
|
* |
324
|
|
|
* @param mixed $obj |
325
|
|
|
* @param string $name |
326
|
|
|
*/ |
327
|
|
|
public function testCanCheckIfTypeHasProperty( |
328
|
|
|
$obj, |
329
|
|
|
string $name, |
330
|
|
|
bool $recursive = true, |
331
|
|
|
bool $includeMagic = false |
332
|
|
|
): void { |
333
|
|
|
/** |
334
|
|
|
* @var Type |
335
|
|
|
*/ |
336
|
|
|
$type = $obj; |
337
|
|
|
|
338
|
|
|
if (!($obj instanceof Type)) { |
339
|
|
|
$type = new Type($obj); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
$actual = $type->hasProperty($name, $recursive, $includeMagic); |
343
|
|
|
|
344
|
|
|
$this->assertIsBool($actual, 'This method must return a boolean'); |
345
|
|
|
|
346
|
|
|
$this->assertTrue($actual); |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
/** |
350
|
|
|
* @dataProvider hasNotPropertyProvider |
351
|
|
|
* |
352
|
|
|
* @param mixed $obj |
353
|
|
|
* @param string $name |
354
|
|
|
*/ |
355
|
|
|
public function testCanCheckIfTypeHasNotProperty( |
356
|
|
|
$obj, |
357
|
|
|
string $name, |
358
|
|
|
bool $recursive = true, |
359
|
|
|
bool $includeMagic = false |
360
|
|
|
): void { |
361
|
|
|
/** |
362
|
|
|
* @var Type |
363
|
|
|
*/ |
364
|
|
|
$type = $obj; |
365
|
|
|
|
366
|
|
|
if (!($obj instanceof Type)) { |
367
|
|
|
$type = new Type($obj); |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
$actual = $type->hasProperty($name, $recursive, $includeMagic); |
371
|
|
|
|
372
|
|
|
$this->assertIsBool($actual, 'This method must return a boolean'); |
373
|
|
|
|
374
|
|
|
$this->assertFalse($actual); |
375
|
|
|
} |
376
|
|
|
} |
377
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.