1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Kint\Test\Parser; |
4
|
|
|
|
5
|
|
|
use Exception; |
6
|
|
|
use Kint\Object\BasicObject; |
7
|
|
|
use Kint\Object\BlobObject; |
8
|
|
|
use Kint\Object\InstanceObject; |
9
|
|
|
use Kint\Object\Representation\Representation; |
10
|
|
|
use Kint\Object\ResourceObject; |
11
|
|
|
use Kint\Parser\Parser; |
12
|
|
|
use Kint\Parser\ProxyPlugin; |
13
|
|
|
use Kint\Test\Fixtures\ChildTestClass; |
14
|
|
|
use PHPUnit_Framework_TestCase; |
15
|
|
|
use ReflectionMethod; |
16
|
|
|
use ReflectionProperty; |
17
|
|
|
use stdClass; |
18
|
|
|
|
19
|
|
|
class ParserTest extends PHPUnit_Framework_TestCase |
20
|
|
|
{ |
21
|
|
|
public function testTriggerComplete() |
22
|
|
|
{ |
23
|
|
|
$this->assertEquals( |
24
|
|
|
Parser::TRIGGER_SUCCESS | |
25
|
|
|
Parser::TRIGGER_DEPTH_LIMIT | |
26
|
|
|
Parser::TRIGGER_RECURSION, |
27
|
|
|
Parser::TRIGGER_COMPLETE |
28
|
|
|
); |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @covers \Kint\Parser\Parser::__construct |
33
|
|
|
* @covers \Kint\Parser\Parser::getDepthLimit |
34
|
|
|
* @covers \Kint\Parser\Parser::getCallerClass |
35
|
|
|
*/ |
36
|
|
|
public function testConstruct() |
37
|
|
|
{ |
38
|
|
|
$marker = new ReflectionProperty('Kint\\Parser\\Parser', 'marker'); |
39
|
|
|
|
40
|
|
|
$marker->setAccessible(true); |
41
|
|
|
|
42
|
|
|
$p1 = new Parser(); |
|
|
|
|
43
|
|
|
|
44
|
|
|
$this->assertFalse($p1->getDepthLimit()); |
45
|
|
|
$this->assertNull($p1->getCallerClass()); |
46
|
|
|
|
47
|
|
|
$p2 = new Parser(123, 'asdf'); |
|
|
|
|
48
|
|
|
|
49
|
|
|
$this->assertSame(123, $p2->getDepthLimit()); |
50
|
|
|
$this->assertSame('asdf', $p2->getCallerClass()); |
51
|
|
|
$this->assertNotEquals($marker->getValue($p1), $marker->getValue($p2)); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @covers \Kint\Parser\Parser::parse |
56
|
|
|
* @covers \Kint\Parser\Parser::parseGeneric |
57
|
|
|
*/ |
58
|
|
|
public function testParseInteger() |
59
|
|
|
{ |
60
|
|
|
$p = new Parser(); |
|
|
|
|
61
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
62
|
|
|
$v = 1234; |
|
|
|
|
63
|
|
|
|
64
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
65
|
|
|
|
66
|
|
|
$this->assertEquals('$v', $o->access_path); |
67
|
|
|
$this->assertEquals('$v', $o->name); |
68
|
|
|
$this->assertEquals('integer', $o->type); |
69
|
|
|
$this->assertEquals('Kint\\Object\\BasicObject', get_class($o)); |
70
|
|
|
$this->assertEquals('Kint\\Object\\Representation\\Representation', get_class($o->value)); |
71
|
|
|
$this->assertEquals(1234, $o->value->contents); |
72
|
|
|
$this->assertEquals(1234, $v); |
73
|
|
|
$this->assertEquals(0, $o->depth); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* @covers \Kint\Parser\Parser::parse |
78
|
|
|
* @covers \Kint\Parser\Parser::parseGeneric |
79
|
|
|
*/ |
80
|
|
|
public function testParseBoolean() |
81
|
|
|
{ |
82
|
|
|
$p = new Parser(); |
|
|
|
|
83
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
84
|
|
|
$v = true; |
|
|
|
|
85
|
|
|
|
86
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
87
|
|
|
|
88
|
|
|
$this->assertEquals('boolean', $o->type); |
89
|
|
|
$this->assertEquals(true, $o->value->contents); |
90
|
|
|
|
91
|
|
|
$v = false; |
92
|
|
|
|
93
|
|
|
$o = $p->parse($v, clone $b); |
94
|
|
|
|
95
|
|
|
$this->assertEquals(false, $o->value->contents); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @covers \Kint\Parser\Parser::parse |
100
|
|
|
* @covers \Kint\Parser\Parser::parseGeneric |
101
|
|
|
*/ |
102
|
|
|
public function testParseDouble() |
103
|
|
|
{ |
104
|
|
|
$p = new Parser(); |
|
|
|
|
105
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
106
|
|
|
$v = 1234.5678; |
|
|
|
|
107
|
|
|
|
108
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
109
|
|
|
|
110
|
|
|
$this->assertEquals('double', $o->type); |
111
|
|
|
$this->assertEquals(1234.5678, $o->value->contents); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @covers \Kint\Parser\Parser::parse |
116
|
|
|
* @covers \Kint\Parser\Parser::parseGeneric |
117
|
|
|
*/ |
118
|
|
|
public function testParseNull() |
119
|
|
|
{ |
120
|
|
|
$p = new Parser(); |
|
|
|
|
121
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
122
|
|
|
$v = null; |
|
|
|
|
123
|
|
|
|
124
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
125
|
|
|
|
126
|
|
|
$this->assertEquals('null', $o->type); |
127
|
|
|
$this->assertEquals(null, $o->value->contents); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @covers \Kint\Parser\Parser::parse |
132
|
|
|
* @covers \Kint\Parser\Parser::parseString |
133
|
|
|
*/ |
134
|
|
|
public function testParseString() |
135
|
|
|
{ |
136
|
|
|
$p = new Parser(); |
|
|
|
|
137
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
138
|
|
|
$v = 'The quick brown fox jumps over the lazy dog'; |
|
|
|
|
139
|
|
|
|
140
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
141
|
|
|
|
142
|
|
|
$this->assertInstanceOf('Kint\\Object\\BlobObject', $o); |
143
|
|
|
if (!$o instanceof BlobObject) { |
144
|
|
|
return; // phpstan |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$this->assertEquals('string', $o->type); |
148
|
|
|
$this->assertEquals($v, $o->value->contents); |
149
|
|
|
$this->assertEquals(true, $o->value->implicit_label); |
150
|
|
|
$this->assertEquals('ASCII', $o->encoding); |
151
|
|
|
$this->assertEquals(strlen($v), $o->size); |
152
|
|
|
$this->assertContains('string', $o->hints); |
153
|
|
|
|
154
|
|
|
// Apologies to Spanish programmers, Google made this sentence. |
155
|
|
|
$v = 'El zorro marrón rápido salta sobre el perro perezoso'; |
156
|
|
|
|
157
|
|
|
$o = $p->parse($v, clone $b); |
158
|
|
|
|
159
|
|
|
$this->assertInstanceOf('Kint\\Object\\BlobObject', $o); |
160
|
|
|
if (!$o instanceof BlobObject) { |
161
|
|
|
return; // phpstan |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
$this->assertEquals($v, $o->value->contents); |
165
|
|
|
$this->assertEquals('UTF-8', $o->encoding); |
166
|
|
|
$this->assertEquals(mb_strlen($v, 'UTF-8'), $o->size); |
167
|
|
|
$this->assertNotEquals(strlen($v), $o->size); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @covers \Kint\Parser\Parser::parse |
172
|
|
|
* @covers \Kint\Parser\Parser::parseResource |
173
|
|
|
*/ |
174
|
|
|
public function testParseResource() |
175
|
|
|
{ |
176
|
|
|
$p = new Parser(); |
|
|
|
|
177
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
178
|
|
|
$v = imagecreate(1, 1); |
|
|
|
|
179
|
|
|
|
180
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
181
|
|
|
|
182
|
|
|
$this->assertInstanceOf('Kint\\Object\\ResourceObject', $o); |
183
|
|
|
if (!$o instanceof ResourceObject) { |
184
|
|
|
return; // phpstan |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
$this->assertEquals('resource', $o->type); |
188
|
|
|
$this->assertEquals(null, $o->value); |
189
|
|
|
$this->assertEquals('gd', $o->resource_type); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @covers \Kint\Parser\Parser::parse |
194
|
|
|
* @covers \Kint\Parser\Parser::parseArray |
195
|
|
|
*/ |
196
|
|
|
public function testParseArray() |
197
|
|
|
{ |
198
|
|
|
$p = new Parser(); |
|
|
|
|
199
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
200
|
|
|
$v = array( |
|
|
|
|
201
|
|
|
1234, |
202
|
|
|
'key' => 'value', |
203
|
|
|
1234 => 5678, |
204
|
|
|
); |
205
|
|
|
|
206
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
207
|
|
|
|
208
|
|
|
$this->assertEquals('array', $o->type); |
209
|
|
|
|
210
|
|
|
$val = array_values($o->value->contents); |
211
|
|
|
|
212
|
|
|
$this->assertEquals(0, $val[0]->name); |
213
|
|
|
$this->assertEquals(1234, $val[0]->value->contents); |
214
|
|
|
$this->assertEquals('$v[0]', $val[0]->access_path); |
215
|
|
|
$this->assertEquals(BasicObject::OPERATOR_ARRAY, $val[0]->operator); |
216
|
|
|
$this->assertEquals('key', $val[1]->name); |
217
|
|
|
$this->assertEquals('value', $val[1]->value->contents); |
218
|
|
|
$this->assertEquals('$v[\'key\']', $val[1]->access_path); |
219
|
|
|
$this->assertEquals(BasicObject::OPERATOR_ARRAY, $val[1]->operator); |
220
|
|
|
$this->assertEquals(1234, $val[2]->name); |
221
|
|
|
$this->assertEquals(5678, $val[2]->value->contents); |
222
|
|
|
$this->assertEquals('$v[1234]', $val[2]->access_path); |
223
|
|
|
$this->assertEquals(BasicObject::OPERATOR_ARRAY, $val[2]->operator); |
224
|
|
|
|
225
|
|
|
$v = array(); |
226
|
|
|
|
227
|
|
|
$o = $p->parse($v, clone $b); |
228
|
|
|
|
229
|
|
|
$this->assertInstanceOf('Kint\\Object\\Representation\\Representation', $o->value); |
230
|
|
|
$this->assertCount(0, $o->value->contents); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @covers \Kint\Parser\Parser::parse |
235
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
236
|
|
|
*/ |
237
|
|
|
public function testParseObject() |
238
|
|
|
{ |
239
|
|
|
$p = new Parser(); |
|
|
|
|
240
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
241
|
|
|
$v = new ChildTestClass(); |
|
|
|
|
242
|
|
|
|
243
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
244
|
|
|
|
245
|
|
|
$this->assertInstanceOf('Kint\\Object\\InstanceObject', $o); |
246
|
|
|
if (!$o instanceof InstanceObject) { |
247
|
|
|
return; // phpstan |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
$this->assertEquals('object', $o->type); |
251
|
|
|
$this->assertEquals('Kint\\Test\\Fixtures\\ChildTestClass', $o->classname); |
252
|
|
|
$this->assertEquals(spl_object_hash($v), $o->hash); |
253
|
|
|
$this->assertContains('object', $o->hints); |
254
|
|
|
|
255
|
|
|
$val = array_values($o->value->contents); |
256
|
|
|
|
257
|
|
|
$this->assertEquals('pub', $val[0]->name); |
258
|
|
|
$this->assertEquals('array', $val[0]->type); |
259
|
|
|
$this->assertEquals(BasicObject::OPERATOR_OBJECT, $val[0]->operator); |
260
|
|
|
$this->assertEquals('$v->pub', $val[0]->access_path); |
261
|
|
|
$this->assertEquals('pro', $val[1]->name); |
262
|
|
|
$this->assertEquals('array', $val[1]->type); |
263
|
|
|
$this->assertEquals(BasicObject::OPERATOR_OBJECT, $val[1]->operator); |
264
|
|
|
$this->assertNull($val[1]->access_path); |
265
|
|
|
$this->assertEquals('pri', $val[2]->name); |
266
|
|
|
$this->assertEquals('array', $val[2]->type); |
267
|
|
|
$this->assertEquals(BasicObject::OPERATOR_OBJECT, $val[2]->operator); |
268
|
|
|
$this->assertNull($val[2]->access_path); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* @covers \Kint\Parser\Parser::parse |
273
|
|
|
* @covers \Kint\Parser\Parser::parseUnknown |
274
|
|
|
*/ |
275
|
|
|
public function testParseUnknown() |
276
|
|
|
{ |
277
|
|
|
$p = new Parser(); |
|
|
|
|
278
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
279
|
|
|
$v = imagecreate(1, 1); |
|
|
|
|
280
|
|
|
imagedestroy($v); |
281
|
|
|
|
282
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
283
|
|
|
|
284
|
|
|
$this->assertEquals('unknown', $o->type); |
285
|
|
|
$this->assertNull($o->value); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* @covers \Kint\Parser\Parser::parseArray |
290
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
291
|
|
|
*/ |
292
|
|
|
public function testParseReferences() |
293
|
|
|
{ |
294
|
|
|
$p = new Parser(); |
|
|
|
|
295
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
296
|
|
|
$r = 1234; |
|
|
|
|
297
|
|
|
$v = array(&$r, 1234); |
|
|
|
|
298
|
|
|
|
299
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
300
|
|
|
|
301
|
|
|
$this->assertEquals(true, $o->value->contents[0]->reference); |
302
|
|
|
$this->assertEquals(false, $o->value->contents[1]->reference); |
303
|
|
|
|
304
|
|
|
$v = new stdClass(); |
305
|
|
|
$v->v1 = &$r; |
306
|
|
|
$v->v2 = 1234; |
307
|
|
|
|
308
|
|
|
$o = $p->parse($v, clone $b); |
309
|
|
|
|
310
|
|
|
$this->assertEquals(true, $o->value->contents[0]->reference); |
311
|
|
|
$this->assertEquals(false, $o->value->contents[1]->reference); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* @covers \Kint\Parser\Parser::parseArray |
316
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
317
|
|
|
*/ |
318
|
|
|
public function testParseRecursion() |
319
|
|
|
{ |
320
|
|
|
$p = new Parser(); |
|
|
|
|
321
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
322
|
|
|
$v = array(); |
|
|
|
|
323
|
|
|
$v[] = &$v; |
324
|
|
|
|
325
|
|
|
$recursed = false; |
326
|
|
|
|
327
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
328
|
|
|
array('array', 'object'), |
329
|
|
|
Parser::TRIGGER_RECURSION, |
330
|
|
|
function () use (&$recursed) { |
331
|
|
|
$recursed = true; |
332
|
|
|
} |
333
|
|
|
); |
334
|
|
|
$p->addPlugin($pl); |
335
|
|
|
|
336
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
337
|
|
|
|
338
|
|
|
$this->assertContains('recursion', $o->value->contents[0]->hints); |
339
|
|
|
$this->assertEquals(true, $recursed); |
340
|
|
|
|
341
|
|
|
$v = new stdClass(); |
342
|
|
|
$v->v = $v; |
343
|
|
|
|
344
|
|
|
$recursed = false; |
345
|
|
|
|
346
|
|
|
$o = $p->parse($v, clone $b); |
347
|
|
|
|
348
|
|
|
$this->assertContains('recursion', $o->value->contents[0]->hints); |
349
|
|
|
$this->assertEquals(true, $recursed); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* @covers \Kint\Parser\Parser::parseDeep |
354
|
|
|
* @covers \Kint\Parser\Parser::parseArray |
355
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
356
|
|
|
*/ |
357
|
|
|
public function testParseDepthLimit() |
358
|
|
|
{ |
359
|
|
|
$p = new Parser(1); |
|
|
|
|
360
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
361
|
|
|
$v = array(array(1234)); |
|
|
|
|
362
|
|
|
|
363
|
|
|
$limit = false; |
364
|
|
|
|
365
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
366
|
|
|
array('array', 'object'), |
367
|
|
|
Parser::TRIGGER_DEPTH_LIMIT, |
368
|
|
|
function () use (&$limit) { |
369
|
|
|
$limit = true; |
370
|
|
|
} |
371
|
|
|
); |
372
|
|
|
$p->addPlugin($pl); |
373
|
|
|
|
374
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
375
|
|
|
|
376
|
|
|
$this->assertContains('depth_limit', $o->value->contents[0]->hints); |
377
|
|
|
$this->assertTrue($limit); |
378
|
|
|
|
379
|
|
|
$limit = false; |
380
|
|
|
|
381
|
|
|
$v = new stdClass(); |
382
|
|
|
$v->v = 1234; |
383
|
|
|
$v = array($v); |
384
|
|
|
|
385
|
|
|
$o = $p->parse($v, clone $b); |
386
|
|
|
|
387
|
|
|
$this->assertContains('depth_limit', $o->value->contents[0]->hints); |
388
|
|
|
$this->assertTrue($limit); |
389
|
|
|
|
390
|
|
|
$limit = false; |
391
|
|
|
|
392
|
|
|
$o = $p->parseDeep($v, clone $b); |
393
|
|
|
|
394
|
|
|
$this->assertNotContains('depth_limit', $o->value->contents[0]->hints); |
395
|
|
|
$this->assertFalse($limit); |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
/** |
399
|
|
|
* @covers \Kint\Parser\Parser::parseArray |
400
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
401
|
|
|
*/ |
402
|
|
|
public function testParseCastKeys() |
403
|
|
|
{ |
404
|
|
|
$p = new Parser(); |
|
|
|
|
405
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
406
|
|
|
|
407
|
|
|
// Object from array |
408
|
|
|
$v1 = (object) array('value'); |
|
|
|
|
409
|
|
|
$o1 = $p->parse($v1, clone $b); |
|
|
|
|
410
|
|
|
|
411
|
|
|
// Normal object |
412
|
|
|
$v2 = new stdClass(); |
|
|
|
|
413
|
|
|
$v2->{0} = 'value'; |
414
|
|
|
$o2 = $p->parse($v2, clone $b); |
|
|
|
|
415
|
|
|
|
416
|
|
|
// Array from object |
417
|
|
|
$v3 = new stdClass(); |
|
|
|
|
418
|
|
|
$v3->{0} = 'value'; |
419
|
|
|
$v3 = (array) $v3; |
420
|
|
|
$o3 = $p->parse($v3, clone $b); |
|
|
|
|
421
|
|
|
|
422
|
|
|
// Normal array |
423
|
|
|
$v4 = array('value'); |
|
|
|
|
424
|
|
|
$o4 = $p->parse($v4, clone $b); |
|
|
|
|
425
|
|
|
|
426
|
|
|
// Object with both |
427
|
|
|
$v5 = (object) array('value'); |
|
|
|
|
428
|
|
|
$v5->{0} = 'value2'; |
429
|
|
|
$o5 = $p->parse($v5, clone $b); |
|
|
|
|
430
|
|
|
|
431
|
|
|
// Array with both |
432
|
|
|
$v6 = new stdClass(); |
|
|
|
|
433
|
|
|
$v6->{0} = 'value'; |
434
|
|
|
$v6 = (array) $v6; |
435
|
|
|
$v6['0'] = 'value2'; |
436
|
|
|
$o6 = $p->parse($v6, clone $b); |
|
|
|
|
437
|
|
|
|
438
|
|
|
if (version_compare(PHP_VERSION, '7.2') >= 0) { |
439
|
|
|
// Object from array |
440
|
|
|
$this->assertEquals(1, $o1->size); |
441
|
|
|
$this->assertEquals('value', $o1->value->contents[0]->value->contents); |
442
|
|
|
$this->assertEquals('$v->{\'0\'}', $o1->value->contents[0]->access_path); |
443
|
|
|
$this->assertTrue(isset($v1->{'0'})); |
444
|
|
|
$this->assertSame('0', $o1->value->contents[0]->name); |
445
|
|
|
|
446
|
|
|
// Normal object |
447
|
|
|
$this->assertEquals(1, $o2->size); |
448
|
|
|
$this->assertEquals('value', $o2->value->contents[0]->value->contents); |
449
|
|
|
$this->assertEquals('$v->{\'0\'}', $o2->value->contents[0]->access_path); |
450
|
|
|
$this->assertTrue(isset($v2->{'0'})); |
451
|
|
|
$this->assertSame('0', $o2->value->contents[0]->name); |
452
|
|
|
|
453
|
|
|
// Array from object |
454
|
|
|
$this->assertEquals(1, $o3->size); |
455
|
|
|
$this->assertEquals('value', $o3->value->contents[0]->value->contents); |
456
|
|
|
$this->assertEquals('$v[0]', $o3->value->contents[0]->access_path); |
457
|
|
|
$this->assertTrue(isset($v3['0'])); |
458
|
|
|
$this->assertSame(0, $o3->value->contents[0]->name); |
459
|
|
|
|
460
|
|
|
// Normal array |
461
|
|
|
$this->assertEquals(1, $o4->size); |
462
|
|
|
$this->assertEquals('value', $o4->value->contents[0]->value->contents); |
463
|
|
|
$this->assertEquals('$v[0]', $o4->value->contents[0]->access_path); |
464
|
|
|
$this->assertTrue(isset($v4['0'])); |
465
|
|
|
$this->assertSame(0, $o4->value->contents[0]->name); |
466
|
|
|
|
467
|
|
|
// Object with both |
468
|
|
|
$this->assertEquals(1, $o5->size); |
469
|
|
|
$this->assertEquals('value2', $o5->value->contents[0]->value->contents); |
470
|
|
|
$this->assertEquals('$v->{\'0\'}', $o5->value->contents[0]->access_path); |
471
|
|
|
$this->assertSame('0', $o5->value->contents[0]->name); |
472
|
|
|
|
473
|
|
|
// Array with both |
474
|
|
|
$this->assertEquals(1, $o6->size); |
475
|
|
|
$this->assertEquals('value2', $o6->value->contents[0]->value->contents); |
476
|
|
|
$this->assertEquals('$v[0]', $o6->value->contents[0]->access_path); |
477
|
|
|
$this->assertSame(0, $o6->value->contents[0]->name); |
478
|
|
|
|
479
|
|
|
// Object with both and weak equality (As of PHP 7.2) |
480
|
|
|
$v7 = (object) array('value'); |
|
|
|
|
481
|
|
|
$v7->{'0'} = 'value2'; |
482
|
|
|
$v7->{''} = 'value3'; |
483
|
|
|
$o7 = $p->parse($v7, clone $b); |
|
|
|
|
484
|
|
|
|
485
|
|
|
// Object with both and weak equality |
486
|
|
|
$this->assertEquals(2, $o7->size); |
487
|
|
View Code Duplication |
foreach ($o7->value->contents as $o) { |
|
|
|
|
488
|
|
|
$this->assertContains($o->value->contents, array('value2', 'value3')); |
489
|
|
|
|
490
|
|
|
if ($o->value->contents === 'value2') { |
491
|
|
|
$this->assertEquals('$v->{\'0\'}', $o->access_path); |
492
|
|
|
$this->assertSame('0', $o->name); |
493
|
|
|
} elseif ($o->value->contents === 'value3') { |
494
|
|
|
$this->assertEquals('$v->{\'\'}', $o->access_path); |
495
|
|
|
$this->assertSame('', $o->name); |
496
|
|
|
} |
497
|
|
|
} |
498
|
|
|
} else { |
499
|
|
|
// Object from array |
500
|
|
|
$this->assertEquals(1, $o1->size); |
501
|
|
|
$this->assertEquals('value', $o1->value->contents[0]->value->contents); |
502
|
|
|
$this->assertEquals('array_values((array) $v)[0]', $o1->value->contents[0]->access_path); |
503
|
|
|
$this->assertFalse(isset($v1->{'0'})); |
504
|
|
|
$this->assertSame(0, $o1->value->contents[0]->name); |
505
|
|
|
|
506
|
|
|
// Normal object |
507
|
|
|
$this->assertEquals(1, $o2->size); |
508
|
|
|
$this->assertEquals('value', $o2->value->contents[0]->value->contents); |
509
|
|
|
$this->assertEquals('$v->{\'0\'}', $o2->value->contents[0]->access_path); |
510
|
|
|
$this->assertTrue(isset($v2->{'0'})); |
511
|
|
|
$this->assertSame('0', $o2->value->contents[0]->name); |
512
|
|
|
|
513
|
|
|
// Array from object |
514
|
|
|
$this->assertEquals(1, $o3->size); |
515
|
|
|
$this->assertEquals('value', $o3->value->contents[0]->value->contents); |
516
|
|
|
$this->assertEquals('array_values($v)[0]', $o3->value->contents[0]->access_path); |
517
|
|
|
$this->assertFalse(isset($v3['0'])); |
518
|
|
|
$this->assertSame('0', $o3->value->contents[0]->name); |
519
|
|
|
|
520
|
|
|
// Normal array |
521
|
|
|
$this->assertEquals(1, $o4->size); |
522
|
|
|
$this->assertEquals('value', $o4->value->contents[0]->value->contents); |
523
|
|
|
$this->assertEquals('$v[0]', $o4->value->contents[0]->access_path); |
524
|
|
|
$this->assertTrue(isset($v4['0'])); |
525
|
|
|
$this->assertSame(0, $o4->value->contents[0]->name); |
526
|
|
|
|
527
|
|
|
// Object with both |
528
|
|
|
$this->assertEquals(2, $o5->size); |
529
|
|
View Code Duplication |
foreach ($o5->value->contents as $o) { |
|
|
|
|
530
|
|
|
$this->assertContains($o->value->contents, array('value', 'value2')); |
531
|
|
|
|
532
|
|
|
if ($o->value->contents === 'value') { |
533
|
|
|
$this->assertEquals('array_values((array) $v)[0]', $o->access_path); |
534
|
|
|
$this->assertSame(0, $o->name); |
535
|
|
|
} elseif ($o->value->contents === 'value2') { |
536
|
|
|
$this->assertEquals('$v->{\'0\'}', $o->access_path); |
537
|
|
|
$this->assertSame('0', $o->name); |
538
|
|
|
} |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
// Array with both |
542
|
|
|
$this->assertEquals(2, $o6->size); |
543
|
|
View Code Duplication |
foreach ($o6->value->contents as $o) { |
|
|
|
|
544
|
|
|
$this->assertContains($o->value->contents, array('value', 'value2')); |
545
|
|
|
|
546
|
|
|
if ($o->value->contents === 'value') { |
547
|
|
|
$this->assertEquals('array_values($v)[0]', $o->access_path); |
548
|
|
|
$this->assertSame('0', $o->name); |
549
|
|
|
} elseif ($o->value->contents === 'value2') { |
550
|
|
|
$this->assertEquals('$v[0]', $o->access_path); |
551
|
|
|
$this->assertSame(0, $o->name); |
552
|
|
|
} |
553
|
|
|
} |
554
|
|
|
} |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
/** |
558
|
|
|
* @covers \Kint\Parser\Parser::parseObject |
559
|
|
|
* @covers \Kint\Parser\Parser::childHasPath |
560
|
|
|
*/ |
561
|
|
|
public function testParseAccessPathAvailability() |
562
|
|
|
{ |
563
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
564
|
|
|
$v = new ChildTestClass(); |
|
|
|
|
565
|
|
|
|
566
|
|
|
$p = new Parser(); |
|
|
|
|
567
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
568
|
|
|
$properties = array(); |
569
|
|
|
foreach ($o->value->contents as $prop) { |
570
|
|
|
$properties[$prop->name] = $prop; |
571
|
|
|
} |
572
|
|
|
$this->assertEquals('$v->pub', $properties['pub']->access_path); |
573
|
|
|
$this->assertNull($properties['pro']->access_path); |
574
|
|
|
$this->assertNull($properties['pri']->access_path); |
575
|
|
|
|
576
|
|
|
$p = new Parser(false, 'Kint\\Test\\Fixtures\\ChildTestClass'); |
577
|
|
|
$o = $p->parse($v, clone $b); |
578
|
|
|
$properties = array(); |
579
|
|
|
foreach ($o->value->contents as $prop) { |
580
|
|
|
$properties[$prop->name] = $prop; |
581
|
|
|
} |
582
|
|
|
$this->assertEquals('$v->pub', $properties['pub']->access_path); |
583
|
|
|
$this->assertEquals('$v->pro', $properties['pro']->access_path); |
584
|
|
|
$this->assertNull($properties['pri']->access_path); |
585
|
|
|
|
586
|
|
|
$p = new Parser(false, 'Kint\\Test\\Fixtures\\TestClass'); |
587
|
|
|
$o = $p->parse($v, clone $b); |
588
|
|
|
$properties = array(); |
589
|
|
|
foreach ($o->value->contents as $prop) { |
590
|
|
|
$properties[$prop->name] = $prop; |
591
|
|
|
} |
592
|
|
|
$this->assertEquals('$v->pub', $properties['pub']->access_path); |
593
|
|
|
$this->assertEquals('$v->pro', $properties['pro']->access_path); |
594
|
|
|
$this->assertEquals('$v->pri', $properties['pri']->access_path); |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
/** |
598
|
|
|
* @covers \Kint\Parser\Parser::applyPlugins |
599
|
|
|
* @covers \Kint\Parser\Parser::addPlugin |
600
|
|
|
* @covers \Kint\Parser\Parser::clearPlugins |
601
|
|
|
*/ |
602
|
|
|
public function testPlugins() |
603
|
|
|
{ |
604
|
|
|
$p = new Parser(); |
|
|
|
|
605
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
606
|
|
|
$v = 1234; |
|
|
|
|
607
|
|
|
|
608
|
|
|
$o = $p->parse($v, clone $b); |
609
|
|
|
|
610
|
|
|
$this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); |
611
|
|
|
|
612
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
613
|
|
|
array('integer'), |
614
|
|
|
Parser::TRIGGER_SUCCESS, |
615
|
|
|
function (&$var, &$o) { |
|
|
|
|
616
|
|
|
$o->testPluginCorrectlyActivated = true; |
617
|
|
|
} |
618
|
|
|
); |
619
|
|
|
$p->addPlugin($pl); |
620
|
|
|
|
621
|
|
|
$o = $p->parse($v, clone $b); |
622
|
|
|
|
623
|
|
|
$this->assertObjectHasAttribute('testPluginCorrectlyActivated', $o); |
624
|
|
|
|
625
|
|
|
$p->clearPlugins(); |
626
|
|
|
|
627
|
|
|
$o = $p->parse($v, clone $b); |
628
|
|
|
|
629
|
|
|
$this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); |
630
|
|
|
|
631
|
|
|
$pl = new ProxyPlugin( |
632
|
|
|
array(), |
633
|
|
|
Parser::TRIGGER_SUCCESS, |
634
|
|
|
function () {} |
635
|
|
|
); |
636
|
|
|
$this->assertFalse($p->addPlugin($pl)); |
637
|
|
|
|
638
|
|
|
$pl = new ProxyPlugin( |
639
|
|
|
array('integer'), |
640
|
|
|
Parser::TRIGGER_NONE, |
641
|
|
|
function () {} |
642
|
|
|
); |
643
|
|
|
$this->assertFalse($p->addPlugin($pl)); |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* @covers \Kint\Parser\Parser::applyPlugins |
648
|
|
|
* @covers \Kint\Parser\Parser::addPlugin |
649
|
|
|
*/ |
650
|
|
|
public function testTriggers() |
651
|
|
|
{ |
652
|
|
|
$p = new Parser(1); |
|
|
|
|
653
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
654
|
|
|
$v = array(1234, array(1234)); |
|
|
|
|
655
|
|
|
$v[] = &$v; |
656
|
|
|
|
657
|
|
|
$triggers = array(); |
658
|
|
|
|
659
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
660
|
|
|
array('integer', 'array'), |
661
|
|
|
Parser::TRIGGER_BEGIN | Parser::TRIGGER_COMPLETE, |
662
|
|
|
function (&$var, &$o, $trig) use (&$triggers) { |
|
|
|
|
663
|
|
|
$triggers[] = $trig; |
664
|
|
|
} |
665
|
|
|
); |
666
|
|
|
$p->addPlugin($pl); |
667
|
|
|
|
668
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
669
|
|
|
|
670
|
|
|
$this->assertEquals( |
671
|
|
|
array( |
672
|
|
|
Parser::TRIGGER_BEGIN, |
673
|
|
|
Parser::TRIGGER_BEGIN, |
674
|
|
|
Parser::TRIGGER_SUCCESS, |
675
|
|
|
Parser::TRIGGER_BEGIN, |
676
|
|
|
Parser::TRIGGER_DEPTH_LIMIT, |
677
|
|
|
Parser::TRIGGER_BEGIN, |
678
|
|
|
Parser::TRIGGER_RECURSION, |
679
|
|
|
Parser::TRIGGER_SUCCESS, |
680
|
|
|
), |
681
|
|
|
$triggers |
682
|
|
|
); |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
/** |
686
|
|
|
* @covers \Kint\Parser\Parser::parse |
687
|
|
|
* @covers \Kint\Parser\Parser::applyPlugins |
688
|
|
|
* @covers \Kint\Parser\Parser::haltParse |
689
|
|
|
*/ |
690
|
|
|
public function testHaltParse() |
691
|
|
|
{ |
692
|
|
|
$p = new Parser(); |
|
|
|
|
693
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
694
|
|
|
$t = clone $b; |
|
|
|
|
695
|
|
|
$t->type = 'integer'; |
696
|
|
|
$v = 1234; |
|
|
|
|
697
|
|
|
|
698
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
699
|
|
|
array('integer'), |
700
|
|
|
Parser::TRIGGER_BEGIN, |
701
|
|
|
function (&$var, &$o, $trig, $parser) { |
|
|
|
|
702
|
|
|
$parser->haltParse(); |
703
|
|
|
} |
704
|
|
|
); |
705
|
|
|
$p->addPlugin($pl); |
706
|
|
|
|
707
|
|
|
$o = $p->parse($v, $t); |
708
|
|
|
|
709
|
|
|
$this->assertSame($t, $o); |
710
|
|
|
|
711
|
|
|
$p->clearPlugins(); |
712
|
|
|
|
713
|
|
|
$pl = new ProxyPlugin( |
714
|
|
|
array('integer'), |
715
|
|
|
Parser::TRIGGER_SUCCESS, |
716
|
|
|
function (&$var, &$o, $trig, $parser) { |
717
|
|
|
$parser->haltParse(); |
718
|
|
|
} |
719
|
|
|
); |
720
|
|
|
$p->addPlugin($pl); |
721
|
|
|
|
722
|
|
|
$pl = new ProxyPlugin( |
723
|
|
|
array('integer'), |
724
|
|
|
Parser::TRIGGER_SUCCESS, |
725
|
|
|
function (&$var, &$o) { |
726
|
|
|
$o->testPluginCorrectlyActivated = true; |
727
|
|
|
} |
728
|
|
|
); |
729
|
|
|
$p->addPlugin($pl); |
730
|
|
|
|
731
|
|
|
$o = $p->parse($v, clone $b); |
732
|
|
|
|
733
|
|
|
$this->assertObjectNotHasAttribute('testPluginCorrectlyActivated', $o); |
734
|
|
|
} |
735
|
|
|
|
736
|
|
|
/** |
737
|
|
|
* @expectedException \PHPUnit_Framework_Error_Warning |
738
|
|
|
* @covers \Kint\Parser\Parser::applyPlugins |
739
|
|
|
*/ |
740
|
|
|
public function testPluginExceptionBecomesWarning() |
741
|
|
|
{ |
742
|
|
|
$p = new Parser(); |
|
|
|
|
743
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
744
|
|
|
$t = clone $b; |
|
|
|
|
745
|
|
|
$t->type = 'integer'; |
746
|
|
|
$v = 1234; |
|
|
|
|
747
|
|
|
|
748
|
|
|
$message = __FUNCTION__; |
749
|
|
|
|
750
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
751
|
|
|
array('integer'), |
752
|
|
|
Parser::TRIGGER_BEGIN, |
753
|
|
|
function (&$var, &$o, $trig, $parser) use ($message) { |
|
|
|
|
754
|
|
|
throw new Exception($message); |
755
|
|
|
} |
756
|
|
|
); |
757
|
|
|
$p->addPlugin($pl); |
758
|
|
|
|
759
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
760
|
|
|
} |
761
|
|
|
|
762
|
|
|
public function childHasPathProvider() |
763
|
|
|
{ |
764
|
|
|
$data = array(); |
765
|
|
|
|
766
|
|
|
$expected = array( |
767
|
|
|
'public parser' => array( |
768
|
|
|
new Parser(), |
769
|
|
|
array( |
770
|
|
|
'props' => array('$v', false, true, false, false), |
771
|
|
|
'statics' => array('$v', true, true, false, false), |
772
|
|
|
'props without path' => array(null, false, false, false, false), |
773
|
|
|
'statics without path' => array(null, true, true, false, false), |
774
|
|
|
), |
775
|
|
|
), |
776
|
|
|
'protected parser' => array( |
777
|
|
|
new Parser(false, 'Kint\\Test\\Fixtures\\ChildTestClass'), |
778
|
|
|
array( |
779
|
|
|
'props' => array('$v', false, true, true, false), |
780
|
|
|
'statics' => array('$v', true, true, true, false), |
781
|
|
|
'props without path' => array(null, false, false, false, false), |
782
|
|
|
'statics without path' => array(null, true, true, true, false), |
783
|
|
|
), |
784
|
|
|
), |
785
|
|
|
'private parser' => array( |
786
|
|
|
new Parser(false, 'Kint\\Test\\Fixtures\\TestClass'), |
787
|
|
|
array( |
788
|
|
|
'props' => array('$v', false, true, true, true), |
789
|
|
|
'statics' => array('$v', true, true, true, true), |
790
|
|
|
'props without path' => array(null, false, false, false, false), |
791
|
|
|
'statics without path' => array(null, true, true, true, true), |
792
|
|
|
), |
793
|
|
|
), |
794
|
|
|
); |
795
|
|
|
|
796
|
|
|
foreach ($expected as $parser_name => $params) { |
|
|
|
|
797
|
|
|
list($parser, $opts) = $params; |
798
|
|
|
|
799
|
|
|
foreach ($opts as $name => $set) { |
800
|
|
|
list($path, $static, $pub, $pro, $pri) = $set; |
801
|
|
|
|
802
|
|
|
$visibilities = array( |
803
|
|
|
BasicObject::ACCESS_PUBLIC => $pub, |
804
|
|
|
BasicObject::ACCESS_PROTECTED => $pro, |
805
|
|
|
BasicObject::ACCESS_PRIVATE => $pri, |
806
|
|
|
); |
807
|
|
|
|
808
|
|
|
foreach ($visibilities as $visibility => $expect) { |
809
|
|
|
$parent = BasicObject::blank(); |
810
|
|
|
$parent = $parent->transplant(new InstanceObject()); |
811
|
|
|
$parent->classname = 'Kint\\Test\\Fixtures\\ChildTestClass'; |
|
|
|
|
812
|
|
|
$parent->type = 'object'; |
813
|
|
|
|
814
|
|
|
$r = new Representation('Contents'); |
815
|
|
|
$parent->addRepresentation($r); |
816
|
|
|
|
817
|
|
|
$prop = BasicObject::blank(); |
818
|
|
|
$r->contents = array($prop); |
819
|
|
|
$prop->owner_class = 'Kint\\Test\\Fixtures\\TestClass'; |
820
|
|
|
|
821
|
|
|
$parent->access_path = $path; |
822
|
|
|
$prop->static = $static; |
823
|
|
|
$prop->access = $visibility; |
824
|
|
|
|
825
|
|
|
$data[$parser_name.', '.$visibility.' '.$name] = array($parser, $parent, $prop, $expect); |
|
|
|
|
826
|
|
|
} |
827
|
|
|
} |
828
|
|
|
} |
829
|
|
|
|
830
|
|
|
return $data; |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
/** |
834
|
|
|
* @dataProvider childHasPathProvider |
835
|
|
|
* @covers \Kint\Parser\Parser::childHasPath |
836
|
|
|
*/ |
837
|
|
|
public function testChildHasPath($parser, $parent, $child, $expected) |
838
|
|
|
{ |
839
|
|
|
$this->assertEquals($expected, $parser->childHasPath($parent, $child)); |
840
|
|
|
} |
841
|
|
|
|
842
|
|
|
/** |
843
|
|
|
* @covers \Kint\Parser\Parser::sortObjectProperties |
844
|
|
|
*/ |
845
|
|
|
public function testSortObjectProperties() |
846
|
|
|
{ |
847
|
|
|
$p = new Parser(); |
|
|
|
|
848
|
|
|
|
849
|
|
|
$ctc = new ChildTestClass(); |
850
|
|
|
|
851
|
|
|
$o = $p->parse($ctc, BasicObject::blank('$ctc')); |
|
|
|
|
852
|
|
|
|
853
|
|
|
$pub = $o->value->contents[0]; |
854
|
|
|
$pro = $o->value->contents[1]; |
855
|
|
|
|
856
|
|
|
$rm = new ReflectionMethod('Kint\\Parser\\Parser', 'sortObjectProperties'); |
|
|
|
|
857
|
|
|
$rm->setAccessible(true); |
858
|
|
|
|
859
|
|
|
$this->assertEquals(0, $rm->invoke($p, $pub, $pub)); |
860
|
|
|
|
861
|
|
|
// Sort by access first |
862
|
|
|
$this->assertEquals(-1, $rm->invoke($p, $pub, $pro)); |
863
|
|
|
$this->assertEquals(1, $rm->invoke($p, $pro, $pub)); |
864
|
|
|
|
865
|
|
|
// With the same access they go by name so they should flip |
866
|
|
|
$pro->access = $pub->access; |
867
|
|
|
$this->assertEquals(1, $rm->invoke($p, $pub, $pro)); |
868
|
|
|
$this->assertEquals(-1, $rm->invoke($p, $pro, $pub)); |
869
|
|
|
|
870
|
|
|
// With the same name they should go by hierarchy |
871
|
|
|
$pro->name = $pub->name; |
872
|
|
|
$pro->owner_class = 'Kint\\Test\\Fixtures\\TestClass'; |
873
|
|
|
$this->assertEquals(-1, $rm->invoke($p, $pub, $pro)); |
874
|
|
|
$this->assertEquals(1, $rm->invoke($p, $pro, $pub)); |
875
|
|
|
|
876
|
|
|
// With everything the same they should be more or less equal |
877
|
|
|
$pro->owner_class = $pub->owner_class; |
878
|
|
|
$this->assertEquals(0, $rm->invoke($p, $pub, $pro)); |
879
|
|
|
$this->assertEquals(0, $rm->invoke($p, $pro, $pub)); |
880
|
|
|
} |
881
|
|
|
|
882
|
|
|
/** |
883
|
|
|
* @covers \Kint\Parser\Parser::getCleanArray |
884
|
|
|
*/ |
885
|
|
|
public function testGetCleanArray() |
886
|
|
|
{ |
887
|
|
|
$p = new Parser(); |
|
|
|
|
888
|
|
|
$b = BasicObject::blank('$v'); |
|
|
|
|
889
|
|
|
$v = array(1234); |
|
|
|
|
890
|
|
|
|
891
|
|
|
$arrays = array(); |
892
|
|
|
|
893
|
|
|
$pl = new ProxyPlugin( |
|
|
|
|
894
|
|
|
array('array'), |
895
|
|
|
Parser::TRIGGER_SUCCESS, |
896
|
|
|
function (&$var, &$o, $trig, $parser) use (&$arrays) { |
|
|
|
|
897
|
|
|
$clean = $parser->getCleanArray($var); |
898
|
|
|
|
899
|
|
|
// This here is exactly why you should never alter input |
900
|
|
|
// variables in plugins and always use getCleanArray |
901
|
|
|
$var[] = 4321; |
902
|
|
|
$clean[] = 8765; |
903
|
|
|
|
904
|
|
|
$arrays = array( |
905
|
|
|
'var' => $var, |
906
|
|
|
'clean' => $clean, |
907
|
|
|
); |
908
|
|
|
} |
909
|
|
|
); |
910
|
|
|
$p->addPlugin($pl); |
911
|
|
|
|
912
|
|
|
$o = $p->parse($v, clone $b); |
|
|
|
|
913
|
|
|
|
914
|
|
|
$this->assertEquals(array(1234, 4321), $v); |
915
|
|
|
$this->assertEquals(array(1234, 8765), $arrays['clean']); |
916
|
|
|
$this->assertEquals(count($v) + 1, count($arrays['var'])); |
917
|
|
|
} |
918
|
|
|
} |
919
|
|
|
|
Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.