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 12namespace Symfony\Component\VarDumper\Tests\Caster; 13 14use PHPUnit\Framework\TestCase; 15use Symfony\Component\VarDumper\Caster\Caster; 16use Symfony\Component\VarDumper\Test\VarDumperTestTrait; 17use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo; 18use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass; 19 20/** 21 * @author Nicolas Grekas <p@tchwork.com> 22 */ 23class ReflectionCasterTest extends TestCase 24{ 25 use VarDumperTestTrait; 26 27 public function testReflectionCaster() 28 { 29 $var = new \ReflectionClass('ReflectionClass'); 30 31 $this->assertDumpMatchesFormat( 32 <<<'EOTXT' 33ReflectionClass { 34 +name: "ReflectionClass" 35%Aimplements: array:%d [ 36 0 => "Reflector" 37%A] 38 constants: array:3 [ 39 "IS_IMPLICIT_ABSTRACT" => 16 40 "IS_EXPLICIT_ABSTRACT" => %d 41 "IS_FINAL" => %d 42 ] 43 properties: array:%d [ 44 "name" => ReflectionProperty { 45%A +name: "name" 46 +class: "ReflectionClass" 47%A modifiers: "public" 48 } 49%A] 50 methods: array:%d [ 51%A 52 "export" => ReflectionMethod { 53 +name: "export" 54 +class: "ReflectionClass" 55%A parameters: { 56 $%s: ReflectionParameter { 57%A position: 0 58%A 59} 60EOTXT 61 , $var 62 ); 63 } 64 65 public function testClosureCaster() 66 { 67 $a = $b = 123; 68 $var = function ($x) use ($a, &$b) {}; 69 70 $this->assertDumpMatchesFormat( 71 <<<'EOTXT' 72Closure($x) { 73%Ause: { 74 $a: 123 75 $b: & 123 76 } 77 file: "%sReflectionCasterTest.php" 78 line: "68 to 68" 79} 80EOTXT 81 , $var 82 ); 83 } 84 85 public function testFromCallableClosureCaster() 86 { 87 if (\defined('HHVM_VERSION_ID')) { 88 $this->markTestSkipped('Not for HHVM.'); 89 } 90 $var = [ 91 (new \ReflectionMethod($this, __FUNCTION__))->getClosure($this), 92 (new \ReflectionMethod(__CLASS__, 'stub'))->getClosure(), 93 ]; 94 95 $this->assertDumpMatchesFormat( 96 <<<EOTXT 97array:2 [ 98 0 => Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::testFromCallableClosureCaster() { 99 this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …} 100 file: "%sReflectionCasterTest.php" 101 line: "%d to %d" 102 } 103 1 => Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::stub(): void { 104 returnType: "void" 105 file: "%sReflectionCasterTest.php" 106 line: "%d to %d" 107 } 108] 109EOTXT 110 , $var 111 ); 112 } 113 114 public function testClosureCasterExcludingVerbosity() 115 { 116 $var = function &($a = 5) {}; 117 118 $this->assertDumpEquals('Closure&($a = 5) { …5}', $var, Caster::EXCLUDE_VERBOSE); 119 } 120 121 public function testReflectionParameter() 122 { 123 $var = new \ReflectionParameter(reflectionParameterFixture::class, 0); 124 125 $this->assertDumpMatchesFormat( 126 <<<'EOTXT' 127ReflectionParameter { 128 +name: "arg1" 129 position: 0 130 typeHint: "Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass" 131 default: null 132} 133EOTXT 134 , $var 135 ); 136 } 137 138 public function testReflectionParameterScalar() 139 { 140 $f = eval('return function (int $a) {};'); 141 $var = new \ReflectionParameter($f, 0); 142 143 $this->assertDumpMatchesFormat( 144 <<<'EOTXT' 145ReflectionParameter { 146 +name: "a" 147 position: 0 148 typeHint: "int" 149} 150EOTXT 151 , $var 152 ); 153 } 154 155 public function testReturnType() 156 { 157 $f = eval('return function ():int {};'); 158 $line = __LINE__ - 1; 159 160 $this->assertDumpMatchesFormat( 161 <<<EOTXT 162Closure(): int { 163 returnType: "int" 164 class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest" 165 this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …} 166 file: "%sReflectionCasterTest.php($line) : eval()'d code" 167 line: "1 to 1" 168} 169EOTXT 170 , $f 171 ); 172 } 173 174 public function testGenerator() 175 { 176 if (\extension_loaded('xdebug')) { 177 $this->markTestSkipped('xdebug is active'); 178 } 179 180 $generator = new GeneratorDemo(); 181 $generator = $generator->baz(); 182 183 $expectedDump = <<<'EODUMP' 184Generator { 185 this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} 186 executing: { 187 %sGeneratorDemo.php:14 { 188 Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() 189 › { 190 › yield from bar(); 191 › } 192 } 193 } 194 closed: false 195} 196EODUMP; 197 198 $this->assertDumpMatchesFormat($expectedDump, $generator); 199 200 foreach ($generator as $v) { 201 break; 202 } 203 204 $expectedDump = <<<'EODUMP' 205array:2 [ 206 0 => ReflectionGenerator { 207 this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} 208 trace: { 209 %s%eTests%eFixtures%eGeneratorDemo.php:9 { 210 Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() 211 › { 212 › yield 1; 213 › } 214 } 215 %s%eTests%eFixtures%eGeneratorDemo.php:20 { …} 216 %s%eTests%eFixtures%eGeneratorDemo.php:14 { …} 217 } 218 closed: false 219 } 220 1 => Generator { 221 executing: { 222 %sGeneratorDemo.php:10 { 223 Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() 224 › yield 1; 225 › } 226 › 227 } 228 } 229 closed: false 230 } 231] 232EODUMP; 233 234 $r = new \ReflectionGenerator($generator); 235 $this->assertDumpMatchesFormat($expectedDump, [$r, $r->getExecutingGenerator()]); 236 237 foreach ($generator as $v) { 238 } 239 240 $expectedDump = <<<'EODUMP' 241Generator { 242 closed: true 243} 244EODUMP; 245 $this->assertDumpMatchesFormat($expectedDump, $generator); 246 } 247 248 public static function stub(): void 249 { 250 } 251} 252 253function reflectionParameterFixture(NotLoadableClass $arg1 = null, $arg2) 254{ 255} 256