VarClonerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\VarDumper\Tests\Cloner;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\VarDumper\Cloner\VarCloner;
  13. use Symfony\Component\VarDumper\Tests\Fixtures\Php74;
  14. /**
  15. * @author Nicolas Grekas <p@tchwork.com>
  16. */
  17. class VarClonerTest extends TestCase
  18. {
  19. public function testMaxIntBoundary()
  20. {
  21. $data = [PHP_INT_MAX => 123];
  22. $cloner = new VarCloner();
  23. $clone = $cloner->cloneVar($data);
  24. $expected = <<<EOTXT
  25. Symfony\Component\VarDumper\Cloner\Data Object
  26. (
  27. [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
  28. (
  29. [0] => Array
  30. (
  31. [0] => Array
  32. (
  33. [1] => 1
  34. )
  35. )
  36. [1] => Array
  37. (
  38. [%s] => 123
  39. )
  40. )
  41. [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  42. [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  43. [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
  44. [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  45. [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  46. )
  47. EOTXT;
  48. $this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true));
  49. }
  50. public function testClone()
  51. {
  52. $json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}');
  53. $cloner = new VarCloner();
  54. $clone = $cloner->cloneVar($json);
  55. $expected = <<<EOTXT
  56. Symfony\Component\VarDumper\Cloner\Data Object
  57. (
  58. [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
  59. (
  60. [0] => Array
  61. (
  62. [0] => Symfony\Component\VarDumper\Cloner\Stub Object
  63. (
  64. [type] => 4
  65. [class] => stdClass
  66. [value] =>
  67. [cut] => 0
  68. [handle] => %i
  69. [refCount] => 0
  70. [position] => 1
  71. [attr] => Array
  72. (
  73. )
  74. )
  75. )
  76. [1] => Array
  77. (
  78. [\000+\0001] => Symfony\Component\VarDumper\Cloner\Stub Object
  79. (
  80. [type] => 4
  81. [class] => stdClass
  82. [value] =>
  83. [cut] => 0
  84. [handle] => %i
  85. [refCount] => 0
  86. [position] => 2
  87. [attr] => Array
  88. (
  89. )
  90. )
  91. [\000+\0002] => Symfony\Component\VarDumper\Cloner\Stub Object
  92. (
  93. [type] => 4
  94. [class] => stdClass
  95. [value] =>
  96. [cut] => 0
  97. [handle] => %i
  98. [refCount] => 0
  99. [position] => 3
  100. [attr] => Array
  101. (
  102. )
  103. )
  104. )
  105. [2] => Array
  106. (
  107. [\000+\000var] => val
  108. )
  109. [3] => Array
  110. (
  111. [\000+\000var] => val
  112. )
  113. )
  114. [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  115. [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  116. [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
  117. [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  118. [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  119. )
  120. EOTXT;
  121. $this->assertStringMatchesFormat($expected, print_r($clone, true));
  122. }
  123. public function testLimits()
  124. {
  125. // Level 0:
  126. $data = [
  127. // Level 1:
  128. [
  129. // Level 2:
  130. [
  131. // Level 3:
  132. 'Level 3 Item 0',
  133. 'Level 3 Item 1',
  134. 'Level 3 Item 2',
  135. 'Level 3 Item 3',
  136. ],
  137. [
  138. 'Level 3 Item 4',
  139. 'Level 3 Item 5',
  140. 'Level 3 Item 6',
  141. ],
  142. [
  143. 'Level 3 Item 7',
  144. ],
  145. ],
  146. [
  147. [
  148. 'Level 3 Item 8',
  149. ],
  150. 'Level 2 Item 0',
  151. ],
  152. [
  153. 'Level 2 Item 1',
  154. ],
  155. 'Level 1 Item 0',
  156. [
  157. // Test setMaxString:
  158. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  159. 'SHORT',
  160. ],
  161. ];
  162. $cloner = new VarCloner();
  163. $cloner->setMinDepth(2);
  164. $cloner->setMaxItems(5);
  165. $cloner->setMaxString(20);
  166. $clone = $cloner->cloneVar($data);
  167. $expected = <<<EOTXT
  168. Symfony\Component\VarDumper\Cloner\Data Object
  169. (
  170. [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
  171. (
  172. [0] => Array
  173. (
  174. [0] => Array
  175. (
  176. [2] => 1
  177. )
  178. )
  179. [1] => Array
  180. (
  181. [0] => Array
  182. (
  183. [2] => 2
  184. )
  185. [1] => Array
  186. (
  187. [2] => 3
  188. )
  189. [2] => Array
  190. (
  191. [2] => 4
  192. )
  193. [3] => Level 1 Item 0
  194. [4] => Array
  195. (
  196. [2] => 5
  197. )
  198. )
  199. [2] => Array
  200. (
  201. [0] => Array
  202. (
  203. [2] => 6
  204. )
  205. [1] => Array
  206. (
  207. [0] => 2
  208. [2] => 7
  209. )
  210. [2] => Array
  211. (
  212. [0] => 1
  213. [2] => 0
  214. )
  215. )
  216. [3] => Array
  217. (
  218. [0] => Array
  219. (
  220. [0] => 1
  221. [2] => 0
  222. )
  223. [1] => Level 2 Item 0
  224. )
  225. [4] => Array
  226. (
  227. [0] => Level 2 Item 1
  228. )
  229. [5] => Array
  230. (
  231. [0] => Symfony\Component\VarDumper\Cloner\Stub Object
  232. (
  233. [type] => 2
  234. [class] => 2
  235. [value] => ABCDEFGHIJKLMNOPQRST
  236. [cut] => 6
  237. [handle] => 0
  238. [refCount] => 0
  239. [position] => 0
  240. [attr] => Array
  241. (
  242. )
  243. )
  244. [1] => SHORT
  245. )
  246. [6] => Array
  247. (
  248. [0] => Level 3 Item 0
  249. [1] => Level 3 Item 1
  250. [2] => Level 3 Item 2
  251. [3] => Level 3 Item 3
  252. )
  253. [7] => Array
  254. (
  255. [0] => Level 3 Item 4
  256. )
  257. )
  258. [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  259. [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  260. [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
  261. [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  262. [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  263. )
  264. EOTXT;
  265. $this->assertStringMatchesFormat($expected, print_r($clone, true));
  266. }
  267. public function testJsonCast()
  268. {
  269. if (2 == ini_get('xdebug.overload_var_dump')) {
  270. $this->markTestSkipped('xdebug is active');
  271. }
  272. $data = (array) json_decode('{"1":{}}');
  273. $cloner = new VarCloner();
  274. $clone = $cloner->cloneVar($data);
  275. $expected = <<<'EOTXT'
  276. object(Symfony\Component\VarDumper\Cloner\Data)#%i (6) {
  277. ["data":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  278. array(2) {
  279. [0]=>
  280. array(1) {
  281. [0]=>
  282. array(1) {
  283. [1]=>
  284. int(1)
  285. }
  286. }
  287. [1]=>
  288. array(1) {
  289. ["1"]=>
  290. object(Symfony\Component\VarDumper\Cloner\Stub)#%i (8) {
  291. ["type"]=>
  292. int(4)
  293. ["class"]=>
  294. string(8) "stdClass"
  295. ["value"]=>
  296. NULL
  297. ["cut"]=>
  298. int(0)
  299. ["handle"]=>
  300. int(%i)
  301. ["refCount"]=>
  302. int(0)
  303. ["position"]=>
  304. int(0)
  305. ["attr"]=>
  306. array(0) {
  307. }
  308. }
  309. }
  310. }
  311. ["position":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  312. int(0)
  313. ["key":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  314. int(0)
  315. ["maxDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  316. int(20)
  317. ["maxItemsPerDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  318. int(-1)
  319. ["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=>
  320. int(-1)
  321. }
  322. EOTXT;
  323. ob_start();
  324. var_dump($clone);
  325. $this->assertStringMatchesFormat(\PHP_VERSION_ID >= 70200 ? str_replace('"1"', '1', $expected) : $expected, ob_get_clean());
  326. }
  327. public function testCaster()
  328. {
  329. $cloner = new VarCloner([
  330. '*' => function ($obj, $array) {
  331. return ['foo' => 123];
  332. },
  333. __CLASS__ => function ($obj, $array) {
  334. ++$array['foo'];
  335. return $array;
  336. },
  337. ]);
  338. $clone = $cloner->cloneVar($this);
  339. $expected = <<<EOTXT
  340. Symfony\Component\VarDumper\Cloner\Data Object
  341. (
  342. [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
  343. (
  344. [0] => Array
  345. (
  346. [0] => Symfony\Component\VarDumper\Cloner\Stub Object
  347. (
  348. [type] => 4
  349. [class] => %s
  350. [value] =>
  351. [cut] => 0
  352. [handle] => %i
  353. [refCount] => 0
  354. [position] => 1
  355. [attr] => Array
  356. (
  357. [file] => %a%eVarClonerTest.php
  358. [line] => 21
  359. )
  360. )
  361. )
  362. [1] => Array
  363. (
  364. [foo] => 124
  365. )
  366. )
  367. [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  368. [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  369. [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
  370. [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  371. [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  372. )
  373. EOTXT;
  374. $this->assertStringMatchesFormat($expected, print_r($clone, true));
  375. }
  376. /**
  377. * @requires PHP 7.4
  378. */
  379. public function testPhp74()
  380. {
  381. $data = new Php74();
  382. $cloner = new VarCloner();
  383. $clone = $cloner->cloneVar($data);
  384. $expected = <<<'EOTXT'
  385. Symfony\Component\VarDumper\Cloner\Data Object
  386. (
  387. [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array
  388. (
  389. [0] => Array
  390. (
  391. [0] => Symfony\Component\VarDumper\Cloner\Stub Object
  392. (
  393. [type] => 4
  394. [class] => Symfony\Component\VarDumper\Tests\Fixtures\Php74
  395. [value] =>
  396. [cut] => 0
  397. [handle] => %i
  398. [refCount] => 0
  399. [position] => 1
  400. [attr] => Array
  401. (
  402. [file] => %s
  403. [line] => 5
  404. )
  405. )
  406. )
  407. [1] => Array
  408. (
  409. [p1] => 123
  410. [p2] => Symfony\Component\VarDumper\Cloner\Stub Object
  411. (
  412. [type] => 4
  413. [class] => stdClass
  414. [value] =>
  415. [cut] => 0
  416. [handle] => %i
  417. [refCount] => 0
  418. [position] => 0
  419. [attr] => Array
  420. (
  421. )
  422. )
  423. )
  424. )
  425. [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  426. [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0
  427. [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
  428. [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  429. [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
  430. )
  431. EOTXT;
  432. $this->assertStringMatchesFormat($expected, print_r($clone, true));
  433. }
  434. }