298c33e6293d6526ac8aded4cafdff7160b3ac0c
[yaffs-website] / vendor / symfony / var-dumper / Tests / Dumper / CliDumperTest.php
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: "%s%eTests%eFixtures%edumb-var.php"
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       %s%eTemplate.php:%d { …}
400       %s%eTemplate.php:%d { …}
401       %s%eTemplate.php:%d { …}
402       %s%eTests%eDumper%eCliDumperTest.php:%d { …}
403 %A  }
404   }
405 %Awrapper_type: "PHP"
406   stream_type: "MEMORY"
407   mode: "%s+b"
408   unread_bytes: 0
409   seekable: true
410   uri: "php://memory"
411 %Aoptions: []
412 }
413
414 EOTXT
415             ,
416             $out
417         );
418     }
419
420     public function testRefsInProperties()
421     {
422         $var = (object) array('foo' => 'foo');
423         $var->bar = &$var->foo;
424
425         $dumper = new CliDumper();
426         $dumper->setColors(false);
427         $cloner = new VarCloner();
428
429         $data = $cloner->cloneVar($var);
430         $out = $dumper->dump($data, true);
431
432         $r = \defined('HHVM_VERSION') ? '' : '#%d';
433         $this->assertStringMatchesFormat(
434             <<<EOTXT
435 {{$r}
436   +"foo": &1 "foo"
437   +"bar": &1 "foo"
438 }
439
440 EOTXT
441             ,
442             $out
443         );
444     }
445
446     /**
447      * @runInSeparateProcess
448      * @preserveGlobalState disabled
449      * @requires PHP 5.6
450      */
451     public function testSpecialVars56()
452     {
453         $var = $this->getSpecialVars();
454
455         $this->assertDumpEquals(
456             <<<'EOTXT'
457 array:3 [
458   0 => array:1 [
459     0 => &1 array:1 [
460       0 => &1 array:1 [&1]
461     ]
462   ]
463   1 => array:1 [
464     "GLOBALS" => &2 array:1 [
465       "GLOBALS" => &2 array:1 [&2]
466     ]
467   ]
468   2 => &2 array:1 [&2]
469 ]
470 EOTXT
471             ,
472             $var
473         );
474     }
475
476     /**
477      * @runInSeparateProcess
478      * @preserveGlobalState disabled
479      */
480     public function testGlobalsNoExt()
481     {
482         $var = $this->getSpecialVars();
483         unset($var[0]);
484         $out = '';
485
486         $dumper = new CliDumper(function ($line, $depth) use (&$out) {
487             if ($depth >= 0) {
488                 $out .= str_repeat('  ', $depth).$line."\n";
489             }
490         });
491         $dumper->setColors(false);
492         $cloner = new VarCloner();
493
494         $refl = new \ReflectionProperty($cloner, 'useExt');
495         $refl->setAccessible(true);
496         $refl->setValue($cloner, false);
497
498         $data = $cloner->cloneVar($var);
499         $dumper->dump($data);
500
501         $this->assertSame(
502             <<<'EOTXT'
503 array:2 [
504   1 => array:1 [
505     "GLOBALS" => &1 array:1 [
506       "GLOBALS" => &1 array:1 [&1]
507     ]
508   ]
509   2 => &1 array:1 [&1]
510 ]
511
512 EOTXT
513             ,
514             $out
515         );
516     }
517
518     /**
519      * @runInSeparateProcess
520      * @preserveGlobalState disabled
521      */
522     public function testBuggyRefs()
523     {
524         if (\PHP_VERSION_ID >= 50600) {
525             $this->markTestSkipped('PHP 5.6 fixed refs counting');
526         }
527
528         $var = $this->getSpecialVars();
529         $var = $var[0];
530
531         $dumper = new CliDumper();
532         $dumper->setColors(false);
533         $cloner = new VarCloner();
534
535         $data = $cloner->cloneVar($var)->withMaxDepth(3);
536         $out = '';
537         $dumper->dump($data, function ($line, $depth) use (&$out) {
538             if ($depth >= 0) {
539                 $out .= str_repeat('  ', $depth).$line."\n";
540             }
541         });
542
543         $this->assertSame(
544             <<<'EOTXT'
545 array:1 [
546   0 => array:1 [
547     0 => array:1 [
548       0 => array:1 [ …1]
549     ]
550   ]
551 ]
552
553 EOTXT
554             ,
555             $out
556         );
557     }
558
559     public function testIncompleteClass()
560     {
561         $unserializeCallbackHandler = ini_set('unserialize_callback_func', null);
562         $var = unserialize('O:8:"Foo\Buzz":0:{}');
563         ini_set('unserialize_callback_func', $unserializeCallbackHandler);
564
565         $this->assertDumpMatchesFormat(
566             <<<EOTXT
567 __PHP_Incomplete_Class(Foo\Buzz) {}
568 EOTXT
569             ,
570             $var
571         );
572     }
573
574     private function getSpecialVars()
575     {
576         foreach (array_keys($GLOBALS) as $var) {
577             if ('GLOBALS' !== $var) {
578                 unset($GLOBALS[$var]);
579             }
580         }
581
582         $var = function &() {
583             $var = array();
584             $var[] = &$var;
585
586             return $var;
587         };
588
589         return array($var(), $GLOBALS, &$GLOBALS);
590     }
591 }