ArrayManagerTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Stdlib\Test\Unit;
  7. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
  8. use Magento\Framework\Stdlib\ArrayManager;
  9. class ArrayManagerTest extends \PHPUnit\Framework\TestCase
  10. {
  11. /**
  12. * @var ArrayManager
  13. */
  14. protected $arrayManager;
  15. /**
  16. * @var ObjectManagerHelper
  17. */
  18. protected $objectManagerHelper;
  19. protected function setUp()
  20. {
  21. $this->objectManagerHelper = new ObjectManagerHelper($this);
  22. $this->arrayManager = $this->objectManagerHelper->getObject(ArrayManager::class);
  23. }
  24. /**
  25. * @param string $path
  26. * @param array $data
  27. * @param bool $result
  28. * @dataProvider existsDataProvider
  29. */
  30. public function testExists($path, $data, $result)
  31. {
  32. $this->assertSame($result, $this->arrayManager->exists($path, $data));
  33. }
  34. /**
  35. * @return array
  36. */
  37. public function existsDataProvider()
  38. {
  39. return [
  40. 0 => [
  41. 'path' => 'some/path',
  42. 'data' => ['some' => ['path' => null]],
  43. 'result' => true
  44. ],
  45. 1 => [
  46. 'path' => '0/0/test',
  47. 'data' => [[['test' => false]]],
  48. 'result' => true
  49. ],
  50. 2 => [
  51. 'path' => 'invalid/path',
  52. 'data' => ['valid' => ['path' => 0]],
  53. 'result' => false
  54. ]
  55. ];
  56. }
  57. public function testExistsCustomDelimiter()
  58. {
  59. $data = ['custom' => ['delimiter' => null]];
  60. $this->assertFalse($this->arrayManager->exists('custom/delimiter', $data, '~'));
  61. $this->assertTrue($this->arrayManager->exists('custom~delimiter', $data, '~'));
  62. }
  63. /**
  64. * @param string $path
  65. * @param array $data
  66. * @param mixed $result
  67. * @dataProvider getDataProvider
  68. */
  69. public function testGet($path, $data, $result)
  70. {
  71. $this->assertSame($result, $this->arrayManager->get($path, $data));
  72. }
  73. /**
  74. * @return array
  75. */
  76. public function getDataProvider()
  77. {
  78. return [
  79. 0 => [
  80. 'path' => 'nested/path/0',
  81. 'data' => ['nested' => ['path' => ['value1']]],
  82. 'result' => 'value1'
  83. ],
  84. 1 => [
  85. 'path' => '0',
  86. 'data' => [false],
  87. 'result' => false
  88. ],
  89. 2 => [
  90. 'path' => 'invalid/path/0',
  91. 'data' => [],
  92. 'result' => null
  93. ]
  94. ];
  95. }
  96. /**
  97. * @param string $path
  98. * @param array $data
  99. * @param mixed $value
  100. * @param array $result
  101. * @dataProvider setDataProvider
  102. */
  103. public function testSet($path, $data, $value, $result)
  104. {
  105. $this->assertSame($result, $this->arrayManager->set($path, $data, $value));
  106. }
  107. /**
  108. * @return array
  109. */
  110. public function setDataProvider()
  111. {
  112. return [
  113. 0 => [
  114. 'path' => '0/1',
  115. 'data' => [[false, false]],
  116. 'value' => true,
  117. 'result' => [[false, true]]
  118. ],
  119. 1 => [
  120. 'path' => 'test',
  121. 'data' => ['test' => ['lost data']],
  122. 'value' => 'found data',
  123. 'result' => ['test' => 'found data']
  124. ],
  125. 2 => [
  126. 'path' => 'new/path/2',
  127. 'data' => ['existing' => ['path' => 1]],
  128. 'value' => 'valuable data',
  129. 'result' => ['existing' => ['path' => 1], 'new' => ['path' => [2 => 'valuable data']]]
  130. ],
  131. 3 => [
  132. 'path' => ['new', 'path/2'],
  133. 'data' => ['existing' => ['path' => 1]],
  134. 'value' => 'valuable data',
  135. 'result' => ['existing' => ['path' => 1], 'new' => ['path' => [2 => 'valuable data']]]
  136. ]
  137. ];
  138. }
  139. /**
  140. * @param string $path
  141. * @param array $data
  142. * @param mixed $value
  143. * @param array $result
  144. * @dataProvider setDataProvider
  145. */
  146. public function testReplace($path, $data, $value, $result)
  147. {
  148. $this->assertSame($result, $this->arrayManager->set($path, $data, $value));
  149. }
  150. /**
  151. * @return array
  152. */
  153. public function setReplaceProvider()
  154. {
  155. return [
  156. 0 => [
  157. 'path' => '0/1',
  158. 'data' => [[false, false]],
  159. 'value' => true,
  160. 'result' => [[false, true]]
  161. ],
  162. 1 => [
  163. 'path' => 'test',
  164. 'data' => ['test' => ['lost data']],
  165. 'value' => 'found data',
  166. 'result' => ['test' => 'found data']
  167. ],
  168. 2 => [
  169. 'path' => 'new/path/2',
  170. 'data' => ['existing' => ['path' => 1]],
  171. 'value' => 'valuable data',
  172. 'result' => ['existing' => ['path' => 1]]
  173. ],
  174. 3 => [
  175. 'path' => ['new', 'path', '2'],
  176. 'data' => ['existing' => ['path' => 1]],
  177. 'value' => 'valuable data',
  178. 'result' => ['existing' => ['path' => 1]]
  179. ]
  180. ];
  181. }
  182. /**
  183. * @param string $path
  184. * @param string $targetPath
  185. * @param array $data
  186. * @param bool $overwrite
  187. * @param array $result
  188. * @dataProvider moveDataProvider
  189. */
  190. public function testMove($path, $targetPath, array $data, $overwrite, array $result)
  191. {
  192. $this->assertSame($result, $this->arrayManager->move($path, $targetPath, $data, $overwrite));
  193. }
  194. /**
  195. * @return array
  196. */
  197. public function moveDataProvider()
  198. {
  199. return [
  200. 0 => [
  201. 'path' => 'not/valid/path',
  202. 'targetPath' => 'target/path',
  203. 'data' => ['valid' => ['path' => 'value']],
  204. 'overwrite' => false,
  205. 'result' => ['valid' => ['path' => 'value']]
  206. ],
  207. 1 => [
  208. 'path' => 'valid/path',
  209. 'targetPath' => 'target/path',
  210. 'data' => ['valid' => ['path' => 'value']],
  211. 'overwrite' => false,
  212. 'result' => ['valid' => [], 'target' => ['path' => 'value']]
  213. ],
  214. 2 => [
  215. 'path' => 'valid/path',
  216. 'targetPath' => 'target/path',
  217. 'data' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']],
  218. 'overwrite' => false,
  219. 'result' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']]
  220. ],
  221. 3 => [
  222. 'path' => 'valid/path',
  223. 'targetPath' => 'target/path',
  224. 'data' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']],
  225. 'overwrite' => true,
  226. 'result' => ['valid' => [], 'target' => ['path' => 'value']]
  227. ],
  228. 4 => [
  229. 'path' => ['valid', 'path'],
  230. 'targetPath' => 'target/path',
  231. 'data' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']],
  232. 'overwrite' => true,
  233. 'result' => ['valid' => [], 'target' => ['path' => 'value']]
  234. ]
  235. ];
  236. }
  237. /**
  238. * @param string $path
  239. * @param array $data
  240. * @param array $value
  241. * @param array $result
  242. * @dataProvider mergeDataProvider
  243. */
  244. public function testMerge($path, $data, $value, $result)
  245. {
  246. $this->assertSame($result, $this->arrayManager->merge($path, $data, $value));
  247. }
  248. /**
  249. * @return array
  250. */
  251. public function mergeDataProvider()
  252. {
  253. return [
  254. 0 => [
  255. 'path' => '0/path/1',
  256. 'data' => [['path' => [false, ['value' => false]]]],
  257. 'value' => ['value' => true, 'new_value' => false],
  258. 'result' => [['path' => [false, ['value' => true, 'new_value' => false]]]]
  259. ],
  260. 1 => [
  261. 'path' => 0,
  262. 'data' => [['nested' => ['test' => 2, 'test2' => 1]]],
  263. 'value' => ['nested' => ['test' => 3], 'more' => 4],
  264. 'result' => [['nested' => ['test' => 3, 'test2' => 1], 'more' => 4]]
  265. ],
  266. 2 => [
  267. 'path' => 'invalid/path',
  268. 'data' => [],
  269. 'value' => [true],
  270. 'result' => []
  271. ],
  272. 3 => [
  273. 'path' => ['0', 'path/1'],
  274. 'data' => [['path' => [false, ['value' => false]]]],
  275. 'value' => ['value' => true, 'new_value' => false],
  276. 'result' => [['path' => [false, ['value' => true, 'new_value' => false]]]]
  277. ],
  278. ];
  279. }
  280. /**
  281. * @param string $path
  282. * @param array $data
  283. * @param array $result
  284. * @dataProvider populateDataProvider
  285. */
  286. public function testPopulate($path, $data, $result)
  287. {
  288. $this->assertSame($result, $this->arrayManager->populate($path, $data));
  289. }
  290. /**
  291. * @return array
  292. */
  293. public function populateDataProvider()
  294. {
  295. return [
  296. 0 => [
  297. 'path' => 'some/is/not/array',
  298. 'data' => ['some' => true],
  299. 'result' => ['some' => true]
  300. ],
  301. 1 => [
  302. 'path' => 0,
  303. 'data' => [],
  304. 'result' => [[]]
  305. ],
  306. 2 => [
  307. 'path' => 'nested/1/array',
  308. 'data' => ['nested' => [true]],
  309. 'result' => ['nested' => [true, ['array' => []]]]
  310. ]
  311. ];
  312. }
  313. /**
  314. * @param string $path
  315. * @param array $data
  316. * @param array $result
  317. * @dataProvider removeDataProvider
  318. */
  319. public function testRemove($path, $data, $result)
  320. {
  321. $this->assertSame($result, $this->arrayManager->remove($path, $data));
  322. }
  323. /**
  324. * @return array
  325. */
  326. public function removeDataProvider()
  327. {
  328. return [
  329. 0 => [
  330. 'path' => '0/0/0/0',
  331. 'data' => [[[[null]]]],
  332. 'result' => [[[[]]]]
  333. ],
  334. 1 => [
  335. 'path' => 'simple',
  336. 'data' => ['simple' => true, 'complex' => false],
  337. 'result' => ['complex' => false]
  338. ],
  339. 2 => [
  340. 'path' => 'invalid',
  341. 'data' => [true],
  342. 'result' => [true]
  343. ],
  344. 3 => [
  345. 'path' => ['simple'],
  346. 'data' => ['simple' => true, 'complex' => false],
  347. 'result' => ['complex' => false]
  348. ],
  349. ];
  350. }
  351. /**
  352. * @param array|mixed $indexes
  353. * @param array $data
  354. * @param string|array|null $startPath
  355. * @param string|array|null $internalPath
  356. * @param array $result
  357. * @dataProvider findPathsDataProvider
  358. */
  359. public function testFindPaths($indexes, array $data, $startPath, $internalPath, $result)
  360. {
  361. $this->assertSame($result, $this->arrayManager->findPaths($indexes, $data, $startPath, $internalPath));
  362. }
  363. /**
  364. * @return array
  365. */
  366. public function findPathsDataProvider()
  367. {
  368. $data = [
  369. 'element1' => [
  370. 'children' => [
  371. 'element11' => [
  372. 'children' => [true, true]
  373. ],
  374. 'element12' => [
  375. 'config' => [
  376. 'argument' => [
  377. 'data' => true
  378. ]
  379. ]
  380. ]
  381. ]
  382. ],
  383. 'element2' => [
  384. 'children' => [true, true, true]
  385. ],
  386. '' => [
  387. [[[[]]]]
  388. ]
  389. ];
  390. return [
  391. 0 => [
  392. 'indexes' => [0, 2],
  393. 'data' => $data,
  394. 'startPath' => 'element2',
  395. 'internalPath' => null,
  396. 'result' => ['element2/children/0', 'element2/children/2']
  397. ],
  398. 1 => [
  399. 'indexes' => 0,
  400. 'data' => $data,
  401. 'startPath' => ['', '0'],
  402. 'internalPath' => '0',
  403. 'result' => ['/0/0', '/0/0/0/0']
  404. ],
  405. 2 => [
  406. 'indexes' => 0,
  407. 'data' => $data,
  408. 'startPath' => '',
  409. 'internalPath' => ['0', '0'],
  410. 'result' => ['/0', '/0/0/0/0']
  411. ],
  412. 3 => [
  413. 'indexes' => 'data',
  414. 'data' => $data,
  415. 'startPath' => 'element1/children',
  416. 'internalPath' => 'config/argument',
  417. 'result' => ['element1/children/element12/config/argument/data']
  418. ],
  419. 4 => [
  420. 'indexes' => 1,
  421. 'data' => $data,
  422. 'startPath' => null,
  423. 'internalPath' => 'elements',
  424. 'result' => []
  425. ]
  426. ];
  427. }
  428. /**
  429. * @param array|mixed $indexes
  430. * @param array $data
  431. * @param string|array|null $startPath
  432. * @param string|array|null $internalPath
  433. * @param array $result
  434. * @dataProvider findPathDataProvider
  435. */
  436. public function testFindPath($indexes, array $data, $startPath, $internalPath, $result)
  437. {
  438. $this->assertSame($result, $this->arrayManager->findPath($indexes, $data, $startPath, $internalPath));
  439. }
  440. /**
  441. * @return array
  442. */
  443. public function findPathDataProvider()
  444. {
  445. $data = [
  446. 'element1' => [
  447. 'children' => [
  448. 'element11' => [
  449. 'children' => [true, true]
  450. ],
  451. 'element12' => [
  452. 'config' => [
  453. 'argument' => [
  454. 'data' => true
  455. ]
  456. ]
  457. ]
  458. ]
  459. ],
  460. 'element2' => [
  461. 'children' => [true, true, true]
  462. ],
  463. '' => [
  464. [[[[]]]]
  465. ]
  466. ];
  467. return [
  468. 0 => [
  469. 'indexes' => [0, 2],
  470. 'data' => $data,
  471. 'startPath' => 'element2',
  472. 'internalPath' => null,
  473. 'result' => 'element2/children/0'
  474. ],
  475. 1 => [
  476. 'indexes' => 0,
  477. 'data' => $data,
  478. 'startPath' => ['', '0'],
  479. 'internalPath' => '0',
  480. 'result' => '/0/0'
  481. ],
  482. 2 => [
  483. 'indexes' => 0,
  484. 'data' => $data,
  485. 'startPath' => '',
  486. 'internalPath' => ['0', '0'],
  487. 'result' => '/0'
  488. ],
  489. 3 => [
  490. 'indexes' => 'data',
  491. 'data' => $data,
  492. 'startPath' => 'element1/children',
  493. 'internalPath' => 'config/argument',
  494. 'result' => 'element1/children/element12/config/argument/data'
  495. ],
  496. 4 => [
  497. 'indexes' => 1,
  498. 'data' => $data,
  499. 'startPath' => null,
  500. 'internalPath' => 'elements',
  501. 'result' => null
  502. ]
  503. ];
  504. }
  505. /**
  506. * @param string $path
  507. * @param int $offset
  508. * @param int|null $length
  509. * @param string $result
  510. * @dataProvider slicePathDataProvider
  511. */
  512. public function testSlicePath($path, $offset, $length, $result)
  513. {
  514. $this->assertSame($result, $this->arrayManager->slicePath($path, $offset, $length));
  515. }
  516. /**
  517. * @return array
  518. */
  519. public function slicePathDataProvider()
  520. {
  521. $path = 'some/very/very/long/path/0/goes/1/3/here';
  522. return [
  523. 0 => [
  524. 'path' => $path,
  525. 'offset' => 3,
  526. 'length' => null,
  527. 'result' => 'long/path/0/goes/1/3/here'
  528. ],
  529. 1 => [
  530. 'path' => $path,
  531. 'offset' => -3,
  532. 'length' => null,
  533. 'result' => '1/3/here'
  534. ],
  535. 2 => [
  536. 'path' => $path,
  537. 'offset' => 500,
  538. 'length' => null,
  539. 'result' => ''
  540. ],
  541. 3 => [
  542. 'path' => $path,
  543. 'offset' => 2,
  544. 'length' => 2,
  545. 'result' => 'very/long'
  546. ],
  547. 4 => [
  548. 'path' => $path,
  549. 'offset' => -6,
  550. 'length' => 3,
  551. 'result' => 'path/0/goes'
  552. ],
  553. ];
  554. }
  555. public function testSlicePathCustomDelimiter()
  556. {
  557. $path = 'my~custom~path';
  558. $this->assertSame('custom', $this->arrayManager->slicePath($path, 1, 1, '~'));
  559. $this->assertSame('', $this->arrayManager->slicePath($path, 1, 1));
  560. }
  561. }