comparison vendor/symfony/var-dumper/Tests/Dumper/CliDumperTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\VarDumper\Tests\Dumper;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\VarDumper\Cloner\VarCloner;
16 use Symfony\Component\VarDumper\Dumper\CliDumper;
17 use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
18 use Twig\Environment;
19 use Twig\Loader\FilesystemLoader;
20
21 /**
22 * @author Nicolas Grekas <p@tchwork.com>
23 */
24 class CliDumperTest extends TestCase
25 {
26 use VarDumperTestTrait;
27
28 public function testGet()
29 {
30 require __DIR__.'/../Fixtures/dumb-var.php';
31
32 $dumper = new CliDumper('php://output');
33 $dumper->setColors(false);
34 $cloner = new VarCloner();
35 $cloner->addCasters(array(
36 ':stream' => function ($res, $a) {
37 unset($a['uri'], $a['wrapper_data']);
38
39 return $a;
40 },
41 ));
42 $data = $cloner->cloneVar($var);
43
44 ob_start();
45 $dumper->dump($data);
46 $out = ob_get_clean();
47 $out = preg_replace('/[ \t]+$/m', '', $out);
48 $intMax = PHP_INT_MAX;
49 $res = (int) $var['res'];
50
51 $r = defined('HHVM_VERSION') ? '' : '#%d';
52 $this->assertStringMatchesFormat(
53 <<<EOTXT
54 array:24 [
55 "number" => 1
56 0 => &1 null
57 "const" => 1.1
58 1 => true
59 2 => false
60 3 => NAN
61 4 => INF
62 5 => -INF
63 6 => {$intMax}
64 "str" => "déjà\\n"
65 7 => b"é\\x00"
66 "[]" => []
67 "res" => stream resource {@{$res}
68 %A wrapper_type: "plainfile"
69 stream_type: "STDIO"
70 mode: "r"
71 unread_bytes: 0
72 seekable: true
73 %A options: []
74 }
75 "obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d
76 +foo: "foo"
77 +"bar": "bar"
78 }
79 "closure" => Closure {{$r}
80 class: "Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest"
81 this: Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest {{$r} …}
82 parameters: {
83 \$a: {}
84 &\$b: {
85 typeHint: "PDO"
86 default: null
87 }
88 }
89 file: "{$var['file']}"
90 line: "{$var['line']} to {$var['line']}"
91 }
92 "line" => {$var['line']}
93 "nobj" => array:1 [
94 0 => &3 {#%d}
95 ]
96 "recurs" => &4 array:1 [
97 0 => &4 array:1 [&4]
98 ]
99 8 => &1 null
100 "sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d}
101 "snobj" => &3 {#%d}
102 "snobj2" => {#%d}
103 "file" => "{$var['file']}"
104 b"bin-key-é" => ""
105 ]
106
107 EOTXT
108 ,
109 $out
110 );
111 }
112
113 /**
114 * @dataProvider provideDumpWithCommaFlagTests
115 */
116 public function testDumpWithCommaFlag($expected, $flags)
117 {
118 $dumper = new CliDumper(null, null, $flags);
119 $dumper->setColors(false);
120 $cloner = new VarCloner();
121
122 $var = array(
123 'array' => array('a', 'b'),
124 'string' => 'hello',
125 'multiline string' => "this\nis\na\multiline\nstring",
126 );
127
128 $dump = $dumper->dump($cloner->cloneVar($var), true);
129
130 $this->assertSame($expected, $dump);
131 }
132
133 public function testDumpWithCommaFlagsAndExceptionCodeExcerpt()
134 {
135 $dumper = new CliDumper(null, null, CliDumper::DUMP_TRAILING_COMMA);
136 $dumper->setColors(false);
137 $cloner = new VarCloner();
138
139 $ex = new \RuntimeException('foo');
140
141 $dump = $dumper->dump($cloner->cloneVar($ex)->withRefHandles(false), true);
142
143 $this->assertStringMatchesFormat(<<<'EOTXT'
144 RuntimeException {
145 #message: "foo"
146 #code: 0
147 #file: "%ACliDumperTest.php"
148 #line: %d
149 trace: {
150 %ACliDumperTest.php:%d: {
151 :
152 : $ex = new \RuntimeException('foo');
153 :
154 }
155 %A
156 }
157 }
158
159 EOTXT
160 , $dump);
161 }
162
163 public function provideDumpWithCommaFlagTests()
164 {
165 $expected = <<<'EOTXT'
166 array:3 [
167 "array" => array:2 [
168 0 => "a",
169 1 => "b"
170 ],
171 "string" => "hello",
172 "multiline string" => """
173 this\n
174 is\n
175 a\multiline\n
176 string
177 """
178 ]
179
180 EOTXT;
181
182 yield array($expected, CliDumper::DUMP_COMMA_SEPARATOR);
183
184 $expected = <<<'EOTXT'
185 array:3 [
186 "array" => array:2 [
187 0 => "a",
188 1 => "b",
189 ],
190 "string" => "hello",
191 "multiline string" => """
192 this\n
193 is\n
194 a\multiline\n
195 string
196 """,
197 ]
198
199 EOTXT;
200
201 yield array($expected, CliDumper::DUMP_TRAILING_COMMA);
202 }
203
204 /**
205 * @requires extension xml
206 */
207 public function testXmlResource()
208 {
209 $var = xml_parser_create();
210
211 $this->assertDumpMatchesFormat(
212 <<<'EOTXT'
213 xml resource {
214 current_byte_index: %i
215 current_column_number: %i
216 current_line_number: 1
217 error_code: XML_ERROR_NONE
218 }
219 EOTXT
220 ,
221 $var
222 );
223 }
224
225 public function testJsonCast()
226 {
227 $var = (array) json_decode('{"0":{},"1":null}');
228 foreach ($var as &$v) {
229 }
230 $var[] = &$v;
231 $var[''] = 2;
232
233 if (\PHP_VERSION_ID >= 70200) {
234 $this->assertDumpMatchesFormat(
235 <<<'EOTXT'
236 array:4 [
237 0 => {}
238 1 => &1 null
239 2 => &1 null
240 "" => 2
241 ]
242 EOTXT
243 ,
244 $var
245 );
246 } else {
247 $this->assertDumpMatchesFormat(
248 <<<'EOTXT'
249 array:4 [
250 "0" => {}
251 "1" => &1 null
252 0 => &1 null
253 "" => 2
254 ]
255 EOTXT
256 ,
257 $var
258 );
259 }
260 }
261
262 public function testObjectCast()
263 {
264 $var = (object) array(1 => 1);
265 $var->{1} = 2;
266
267 if (\PHP_VERSION_ID >= 70200) {
268 $this->assertDumpMatchesFormat(
269 <<<'EOTXT'
270 {
271 +"1": 2
272 }
273 EOTXT
274 ,
275 $var
276 );
277 } else {
278 $this->assertDumpMatchesFormat(
279 <<<'EOTXT'
280 {
281 +1: 1
282 +"1": 2
283 }
284 EOTXT
285 ,
286 $var
287 );
288 }
289 }
290
291 public function testClosedResource()
292 {
293 if (defined('HHVM_VERSION') && HHVM_VERSION_ID < 30600) {
294 $this->markTestSkipped();
295 }
296
297 $var = fopen(__FILE__, 'r');
298 fclose($var);
299
300 $dumper = new CliDumper('php://output');
301 $dumper->setColors(false);
302 $cloner = new VarCloner();
303 $data = $cloner->cloneVar($var);
304
305 ob_start();
306 $dumper->dump($data);
307 $out = ob_get_clean();
308 $res = (int) $var;
309
310 $this->assertStringMatchesFormat(
311 <<<EOTXT
312 Closed resource @{$res}
313
314 EOTXT
315 ,
316 $out
317 );
318 }
319
320 public function testFlags()
321 {
322 putenv('DUMP_LIGHT_ARRAY=1');
323 putenv('DUMP_STRING_LENGTH=1');
324
325 $var = array(
326 range(1, 3),
327 array('foo', 2 => 'bar'),
328 );
329
330 $this->assertDumpEquals(
331 <<<EOTXT
332 [
333 [
334 1
335 2
336 3
337 ]
338 [
339 0 => (3) "foo"
340 2 => (3) "bar"
341 ]
342 ]
343 EOTXT
344 ,
345 $var
346 );
347
348 putenv('DUMP_LIGHT_ARRAY=');
349 putenv('DUMP_STRING_LENGTH=');
350 }
351
352 /**
353 * @requires function Twig\Template::getSourceContext
354 */
355 public function testThrowingCaster()
356 {
357 $out = fopen('php://memory', 'r+b');
358
359 require_once __DIR__.'/../Fixtures/Twig.php';
360 $twig = new \__TwigTemplate_VarDumperFixture_u75a09(new Environment(new FilesystemLoader()));
361
362 $dumper = new CliDumper();
363 $dumper->setColors(false);
364 $cloner = new VarCloner();
365 $cloner->addCasters(array(
366 ':stream' => function ($res, $a) {
367 unset($a['wrapper_data']);
368
369 return $a;
370 },
371 ));
372 $cloner->addCasters(array(
373 ':stream' => eval('return function () use ($twig) {
374 try {
375 $twig->render(array());
376 } catch (\Twig\Error\RuntimeError $e) {
377 throw $e->getPrevious();
378 }
379 };'),
380 ));
381 $ref = (int) $out;
382
383 $data = $cloner->cloneVar($out);
384 $dumper->dump($data, $out);
385 $out = stream_get_contents($out, -1, 0);
386
387 $r = defined('HHVM_VERSION') ? '' : '#%d';
388 $this->assertStringMatchesFormat(
389 <<<EOTXT
390 stream resource {@{$ref}
391 ⚠: Symfony\Component\VarDumper\Exception\ThrowingCasterException {{$r}
392 #message: "Unexpected Exception thrown from a caster: Foobar"
393 trace: {
394 %sTwig.php:2: {
395 : foo bar
396 : twig source
397 :
398 }
399 %sTemplate.php:%d: {
400 : try {
401 : \$this->doDisplay(\$context, \$blocks);
402 : } catch (Twig%sError \$e) {
403 }
404 %sTemplate.php:%d: {
405 : {
406 : \$this->displayWithErrorHandling(\$this->env->mergeGlobals(\$context), array_merge(\$this->blocks, \$blocks));
407 : }
408 }
409 %sTemplate.php:%d: {
410 : try {
411 : \$this->display(\$context);
412 : } catch (%s \$e) {
413 }
414 %sCliDumperTest.php:%d: {
415 %A
416 }
417 }
418 }
419 %Awrapper_type: "PHP"
420 stream_type: "MEMORY"
421 mode: "%s+b"
422 unread_bytes: 0
423 seekable: true
424 uri: "php://memory"
425 %Aoptions: []
426 }
427
428 EOTXT
429 ,
430 $out
431 );
432 }
433
434 public function testRefsInProperties()
435 {
436 $var = (object) array('foo' => 'foo');
437 $var->bar = &$var->foo;
438
439 $dumper = new CliDumper();
440 $dumper->setColors(false);
441 $cloner = new VarCloner();
442
443 $data = $cloner->cloneVar($var);
444 $out = $dumper->dump($data, true);
445
446 $r = defined('HHVM_VERSION') ? '' : '#%d';
447 $this->assertStringMatchesFormat(
448 <<<EOTXT
449 {{$r}
450 +"foo": &1 "foo"
451 +"bar": &1 "foo"
452 }
453
454 EOTXT
455 ,
456 $out
457 );
458 }
459
460 /**
461 * @runInSeparateProcess
462 * @preserveGlobalState disabled
463 * @requires PHP 5.6
464 */
465 public function testSpecialVars56()
466 {
467 $var = $this->getSpecialVars();
468
469 $this->assertDumpEquals(
470 <<<'EOTXT'
471 array:3 [
472 0 => array:1 [
473 0 => &1 array:1 [
474 0 => &1 array:1 [&1]
475 ]
476 ]
477 1 => array:1 [
478 "GLOBALS" => &2 array:1 [
479 "GLOBALS" => &2 array:1 [&2]
480 ]
481 ]
482 2 => &2 array:1 [&2]
483 ]
484 EOTXT
485 ,
486 $var
487 );
488 }
489
490 /**
491 * @runInSeparateProcess
492 * @preserveGlobalState disabled
493 */
494 public function testGlobalsNoExt()
495 {
496 $var = $this->getSpecialVars();
497 unset($var[0]);
498 $out = '';
499
500 $dumper = new CliDumper(function ($line, $depth) use (&$out) {
501 if ($depth >= 0) {
502 $out .= str_repeat(' ', $depth).$line."\n";
503 }
504 });
505 $dumper->setColors(false);
506 $cloner = new VarCloner();
507
508 $refl = new \ReflectionProperty($cloner, 'useExt');
509 $refl->setAccessible(true);
510 $refl->setValue($cloner, false);
511
512 $data = $cloner->cloneVar($var);
513 $dumper->dump($data);
514
515 $this->assertSame(
516 <<<'EOTXT'
517 array:2 [
518 1 => array:1 [
519 "GLOBALS" => &1 array:1 [
520 "GLOBALS" => &1 array:1 [&1]
521 ]
522 ]
523 2 => &1 array:1 [&1]
524 ]
525
526 EOTXT
527 ,
528 $out
529 );
530 }
531
532 /**
533 * @runInSeparateProcess
534 * @preserveGlobalState disabled
535 */
536 public function testBuggyRefs()
537 {
538 if (\PHP_VERSION_ID >= 50600) {
539 $this->markTestSkipped('PHP 5.6 fixed refs counting');
540 }
541
542 $var = $this->getSpecialVars();
543 $var = $var[0];
544
545 $dumper = new CliDumper();
546 $dumper->setColors(false);
547 $cloner = new VarCloner();
548
549 $data = $cloner->cloneVar($var)->withMaxDepth(3);
550 $out = '';
551 $dumper->dump($data, function ($line, $depth) use (&$out) {
552 if ($depth >= 0) {
553 $out .= str_repeat(' ', $depth).$line."\n";
554 }
555 });
556
557 $this->assertSame(
558 <<<'EOTXT'
559 array:1 [
560 0 => array:1 [
561 0 => array:1 [
562 0 => array:1 [ …1]
563 ]
564 ]
565 ]
566
567 EOTXT
568 ,
569 $out
570 );
571 }
572
573 public function testIncompleteClass()
574 {
575 $unserializeCallbackHandler = ini_set('unserialize_callback_func', null);
576 $var = unserialize('O:8:"Foo\Buzz":0:{}');
577 ini_set('unserialize_callback_func', $unserializeCallbackHandler);
578
579 $this->assertDumpMatchesFormat(
580 <<<EOTXT
581 __PHP_Incomplete_Class(Foo\Buzz) {}
582 EOTXT
583 ,
584 $var
585 );
586 }
587
588 private function getSpecialVars()
589 {
590 foreach (array_keys($GLOBALS) as $var) {
591 if ('GLOBALS' !== $var) {
592 unset($GLOBALS[$var]);
593 }
594 }
595
596 $var = function &() {
597 $var = array();
598 $var[] = &$var;
599
600 return $var;
601 };
602
603 return array($var(), $GLOBALS, &$GLOBALS);
604 }
605 }