Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
StructureTest.php
Go to the documentation of this file.
1 <?php
7 
8 class StructureTest extends \PHPUnit\Framework\TestCase
9 {
13  protected $_structure;
14 
18  protected function setUp()
19  {
20  $this->_structure = new \Magento\Framework\Data\Structure();
21  }
22 
28  public function testConstructImportExportElements($elements)
29  {
30  $this->assertSame([], $this->_structure->exportElements());
31  $this->_structure->importElements($elements);
32  $this->assertSame($elements, $this->_structure->exportElements());
33  $structure = new \Magento\Framework\Data\Structure($elements);
34  $this->assertSame($elements, $structure->exportElements());
35  }
36 
41  {
42  return [
43  [[]],
44  [['element' => ['arbitrary_key' => 'value']]],
45  [
46  [
47  'one' => [\Magento\Framework\Data\Structure::CHILDREN => ['two' => 2, 'three' => 3]],
49  'three' => [\Magento\Framework\Data\Structure::PARENT => 'one'],
51  ]
52  ],
53  [
54  [
55  'one' => [
56  \Magento\Framework\Data\Structure::CHILDREN => ['two' => 't.w.o.'],
58  'group' => ['two' => 'two', 'three' => 'three'],
59  ],
60  ],
62  'three' => [],
63  ]
64  ]
65  ];
66  }
67 
74  public function testImportException($elements)
75  {
76  $this->_structure->importElements($elements);
77  }
78 
82  public function importExceptionDataProvider()
83  {
84  return [
85  'numeric id' => [['element']],
86  'completely missing nested set' => [
87  ['one' => [\Magento\Framework\Data\Structure::PARENT => 'two'], 'two' => []],
88  ],
89  'messed up nested set' => [
90  [
92  'two' => [\Magento\Framework\Data\Structure::CHILDREN => ['three' => 't.h.r.e.e.']],
93  'three' => [],
94  ],
95  ],
96  'nested set invalid data type' => [
98  ],
99  'duplicate aliases' => [
100  [
101  'one' => [
102  \Magento\Framework\Data\Structure::CHILDREN => ['two' => 'alias', 'three' => 'alias'],
103  ],
104  'two' => [\Magento\Framework\Data\Structure::PARENT => 'one'],
105  'three' => [\Magento\Framework\Data\Structure::PARENT => 'one'],
106  ],
107  ],
108  'missing reference back to parent' => [
109  ['one' => [
110  \Magento\Framework\Data\Structure::CHILDREN => ['two' => 't.w.o.'], ], 'two' => [],
111  ],
112  ],
113  'broken reference back to parent' => [
114  [
115  'one' => [
116  \Magento\Framework\Data\Structure::CHILDREN => ['two' => 't.w.o.', 'three' => 't.h.r.e.e.'],
117  ],
118  'two' => [\Magento\Framework\Data\Structure::PARENT => 'three'],
119  'three' => [\Magento\Framework\Data\Structure::PARENT => 'one'],
120  ],
121  ],
122  'groups invalid data type' => [['one' => [\Magento\Framework\Data\Structure::GROUPS => '']]],
123  'group invalid data type' => [
124  ['one' => [\Magento\Framework\Data\Structure::GROUPS => [1]]],
125  ],
126  'asymmetric group' => [
127  [
128  'one' => [\Magento\Framework\Data\Structure::GROUPS => ['two' => 'three']],
129  'two' => [],
130  'three' => [],
131  ],
132  ],
133  'group references to non-existing element' => [
134  ['one' => [\Magento\Framework\Data\Structure::GROUPS => ['two' => 'two']]],
135  ]
136  ];
137  }
138 
145  public function testImportExceptionElementNotFound($elements)
146  {
147  $this->_structure->importElements($elements);
148  }
149 
154  {
155  return [
156  'non-existing parent' => [
157  ['element' => [\Magento\Framework\Data\Structure::PARENT => 'unknown']],
158  ],
159  'missing child' => [
160  [
161  'one' => [
162  \Magento\Framework\Data\Structure::CHILDREN => ['two' => 't.w.o.', 'three' => 't.h.r.e.e.'],
163  ],
164  'two' => [\Magento\Framework\Data\Structure::PARENT => 'one'],
165  ],
166  ],
167  ];
168  }
169 
173  public function testCreateGetHasElement()
174  {
175  $data = [uniqid() => uniqid()];
176  $elementId = uniqid('id');
177  $this->assertFalse($this->_structure->hasElement($elementId));
178  $this->assertFalse($this->_structure->getElement($elementId));
179 
180  $this->_structure->createElement($elementId, $data);
181  $this->assertTrue($this->_structure->hasElement($elementId));
182  $this->assertSame($data, $this->_structure->getElement($elementId));
183  }
184 
189  public function testCreateElementException()
190  {
191  $elementId = uniqid('id');
192  $this->_structure->createElement($elementId, []);
193  $this->_structure->createElement($elementId, []);
194  }
195 
199  public function testUnsetElement()
200  {
201  $this->_populateSampleStructure();
202 
203  // non-recursively
204  $this->assertTrue($this->_structure->unsetElement('six', false));
205  $this->assertFalse($this->_structure->unsetElement('six', false));
206  $this->assertSame([5], $this->_structure->getElement('five'));
207 
208  // recursively
209  $this->assertTrue($this->_structure->unsetElement('three'));
210  $this->assertTrue($this->_structure->unsetElement('four'));
211  $this->assertSame(['one' => [], 'five' => [5]], $this->_structure->exportElements());
212  }
213 
217  public function testSetGetAttribute()
218  {
219  $this->_populateSampleStructure();
220  $this->assertFalse($this->_structure->getAttribute('two', 'non-existing'));
221  $this->assertEquals('bar', $this->_structure->getAttribute('two', 'foo'));
222  $value = uniqid();
223  $this->_structure->setAttribute('two', 'non-existing', $value)->setAttribute('two', 'foo', $value);
224  $this->assertEquals($value, $this->_structure->getAttribute('two', 'non-existing'));
225  $this->assertEquals($value, $this->_structure->getAttribute('two', 'foo'));
226  }
227 
233  {
234  $this->_structure->setAttribute('non-existing', 'foo', 'bar');
235  }
236 
244  {
245  $this->_structure->importElements(['element' => []]);
246  $this->_structure->setAttribute('element', $attribute, 'value');
247  }
248 
253  {
254  return [
258  ];
259  }
260 
266  {
267  $this->_structure->getAttribute('non-existing', 'foo');
268  }
269 
273  public function testRenameElement()
274  {
275  $this->_populateSampleStructure();
276 
277  // rename element and see how children got updated
278  $element = $this->_structure->getElement('four');
279  $this->assertNotEmpty($element);
280  $this->assertFalse($this->_structure->getElement('four.5'));
281  $this->assertSame($this->_structure, $this->_structure->renameElement('four', 'four.5'));
282  $this->assertSame($element, $this->_structure->getElement('four.5'));
283  $this->assertEquals(
284  'four.5',
285  $this->_structure->getAttribute('two', \Magento\Framework\Data\Structure::PARENT)
286  );
287  $this->assertEquals(
288  'four.5',
289  $this->_structure->getAttribute('three', \Magento\Framework\Data\Structure::PARENT)
290  );
291 
292  // rename element and see how parent got updated
293  $this->_structure->renameElement('three', 'three.5');
294  // first child
295  $this->assertSame(['three.5' => 'th', 'two' => 'tw'], $this->_structure->getChildren('four.5'));
296  $this->_structure->renameElement('two', 'two.5');
297  // second and last child
298  $this->assertSame(['three.5' => 'th', 'two.5' => 'tw'], $this->_structure->getChildren('four.5'));
299  }
300 
304  public function testSetAsChild()
305  {
306  $this->_populateSampleStructure();
307 
308  // default alias
309  $this->_structure->setAsChild('two', 'one');
310  $this->assertEquals('one', $this->_structure->getParentId('two'));
311  $this->assertEquals(['two' => 'two'], $this->_structure->getChildren('one'));
312  $this->assertEquals(['three' => 'th'], $this->_structure->getChildren('four'));
313 
314  // specified alias
315  $this->_structure->setAsChild('six', 'three', 's');
316  $this->assertEquals('three', $this->_structure->getParentId('six'));
317  $this->assertEquals(['six' => 's'], $this->_structure->getChildren('three'));
318  }
319 
326  public function testSetAsChildOffset($offset, $expectedOffset)
327  {
329  $this->_structure->setAsChild('x', 'parent', '', $offset);
330  $children = $this->_structure->getChildren('parent');
331  $actualOffset = array_search('x', array_keys($children));
332  $this->assertSame(
333  $expectedOffset,
334  $actualOffset,
335  "The 'x' is expected to be at '{$expectedOffset}' offset, rather than '{$actualOffset}', in array: " .
336  var_export(
337  $children,
338  1
339  )
340  );
341  }
342 
347  {
348  return [
349  [0, 0],
350  [1, 1],
351  [2, 2],
352  [3, 3],
353  [4, 4],
354  [5, 5],
355  [null, 5],
356  [-1, 4],
357  [-2, 3],
358  [-3, 2],
359  [-4, 1],
360  [-5, 0]
361  ];
362  }
363 
371  public function testSetAsChildException($elementId, $parentId)
372  {
373  $this->_structure->createElement('one', []);
374  $this->_structure->createElement('two', []);
375  $this->_structure->createElement('three', []);
376  $this->_structure->setAsChild('three', 'two');
377  $this->_structure->setAsChild('two', 'one');
378  $this->_structure->setAsChild($elementId, $parentId);
379  }
380 
385  {
386  return [['one', 'three'], ['one', 'one']];
387  }
388 
392  public function testUnsetChild()
393  {
394  $this->_populateSampleStructure();
395 
396  // specify element by name
397  $this->_structure->unsetChild('five');
398  $this->assertFalse($this->_structure->getParentId('five'));
399  $this->assertArrayNotHasKey(\Magento\Framework\Data\Structure::CHILDREN, $this->_structure->getElement('six'));
400 
401  // specify element by parent and alias
402  $this->_structure->unsetChild('four', 'tw');
403  $this->assertFalse($this->_structure->getChildId('four', 'tw'));
404  $this->assertFalse($this->_structure->getParentId('two'));
405  }
406 
414  public function testReorderChild($initialOffset, $newOffset, $expectedOffset)
415  {
417  $this->_structure->setAsChild('x', 'parent', '', $initialOffset);
418  $this->assertSame($expectedOffset, $this->_structure->reorderChild('parent', 'x', $newOffset));
419  }
420 
424  public function reorderChildDataProvider()
425  {
426  return [
427  // x* 1 2 3 4 5
428  [0, 0, 1],
429  [0, 1, 1],
430  [0, 2, 2],
431  [0, 3, 3],
432  [0, +100500, 6],
433  [0, -1, 5],
434  [0, -4, 2],
435  [0, -5, 1],
436  [0, -999, 1],
437  // 1 x* 2 3 4 5
438  [1, 0, 1],
439  [1, 1, 2],
440  [1, 2, 2],
441  [1, 3, 3],
442  [1, -1, 5],
443  [1, -4, 2],
444  [1, -5, 2],
445  [1, -6, 1],
446  // 1 2 x* 3 4 5
447  [2, 0, 1],
448  [2, 1, 2],
449  [2, 2, 3],
450  [2, 3, 3],
451  [2, 4, 4],
452  [2, null, 6],
453  // 1 2 3 4 5 x*
454  [5, 0, 1],
455  [5, 1, 2],
456  [5, 5, 6]
457  ];
458  }
459 
464  public function testReorderChildException()
465  {
466  $this->_structure->createElement('one', []);
467  $this->_structure->createElement('two', []);
468  $this->_structure->reorderChild('one', 'two', 0);
469  }
470 
479  public function testReorderToSibling($initialOffset, $sibling, $delta, $expectedOffset)
480  {
482  $this->_structure->setAsChild('x', 'parent', '', $initialOffset);
483  $this->assertSame($expectedOffset, $this->_structure->reorderToSibling('parent', 'x', $sibling, $delta));
484  }
485 
489  public function reorderSiblingDataProvider()
490  {
491  return [
492  // x* 1 2 3 4 5
493  [0, 'one', 1, 2],
494  [0, 'three', 2, 5],
495  [0, 'five', 1, 6],
496  [0, 'five', 10, 6],
497  [0, 'one', -1, 1],
498  [0, 'one', -999, 1],
499  // 1 2 x* 3 4 5
500  [2, 'two', 1, 3],
501  [2, 'two', 2, 4],
502  [2, 'two', 3, 5],
503  [2, 'two', 999, 6],
504  [2, 'two', -1, 2],
505  [2, 'two', -2, 1],
506  [2, 'two', -999, 1],
507  [2, 'x', 1, 3],
508  [2, 'x', 2, 4],
509  [2, 'x', 3, 5],
510  [2, 'x', 999, 6],
511  [2, 'x', -1, 3],
512  [2, 'x', -2, 2],
513  [2, 'x', -999, 1]
514  ];
515  }
516 
522  {
523  $this->_structure->createElement('one', []);
524  $this->_structure->createElement('two', []);
525  $this->_structure->createElement('three', []);
526  $this->_structure->setAsChild('two', 'one');
527  $this->_structure->reorderToSibling('one', 'three', 'two', 1);
528  }
529 
533  public function testGetChildId()
534  {
535  $this->_populateSampleStructure();
536  $this->assertFalse($this->_structure->getChildId('nonexisting-parent', 'does not matter'));
537  $this->assertEquals('five', $this->_structure->getChildId('six', 'f'));
538  }
539 
544  {
545  $this->_structure->createElement('one', []);
546  $this->_structure->createElement('two', []);
547  $this->_structure->createElement('three', []);
548  $this->_structure->setAsChild('two', 'one');
549  $this->_structure->setAsChild('three', 'one', 'th');
550 
551  // getChildren()
552  $this->assertSame(['two' => 'two', 'three' => 'th'], $this->_structure->getChildren('one'));
553  $this->assertSame([], $this->_structure->getChildren('three'));
554  $this->assertSame([], $this->_structure->getChildren('nonexisting'));
555 
556  // getParentId()
557  $this->assertEquals('one', $this->_structure->getParentId('two'));
558  $this->assertFalse($this->_structure->getParentId('nonexistent'));
559 
560  // getChildAlias()
561  $this->assertEquals('two', $this->_structure->getChildAlias('one', 'two'));
562  $this->assertEquals('th', $this->_structure->getChildAlias('one', 'three'));
563  $this->assertFalse($this->_structure->getChildAlias('nonexistent', 'child'));
564  $this->assertFalse($this->_structure->getChildAlias('one', 'nonexistent'));
565  }
566 
572  public function testGroups()
573  {
574  // non-existing element
575  $this->assertFalse($this->_structure->addToParentGroup('non-existing', 'group1'));
576  $this->assertSame([], $this->_structure->getGroupChildNames('non-existing', 'group1'));
577 
578  // not a child
579  $this->_structure->createElement('one', []);
580  $this->_structure->createElement('two', []);
581  $this->assertFalse($this->_structure->addToParentGroup('two', 'group1'));
582  $this->assertSame([], $this->_structure->getGroupChildNames('one', 'group1'));
583 
584  // child
585  $this->_structure->setAsChild('two', 'one');
586  $this->assertTrue($this->_structure->addToParentGroup('two', 'group1'));
587  $this->assertTrue($this->_structure->addToParentGroup('two', 'group2'));
588 
589  // group getter
590  $this->_structure->createElement('three', []);
591  $this->_structure->createElement('four', []);
592  $this->_structure->setAsChild('three', 'one', 'th');
593  $this->_structure->setAsChild('four', 'one');
594  $this->_structure->addToParentGroup('three', 'group1');
595  $this->_structure->addToParentGroup('four', 'group2');
596  $this->assertSame(['two', 'three'], $this->_structure->getGroupChildNames('one', 'group1'));
597  $this->assertSame(['two', 'four'], $this->_structure->getGroupChildNames('one', 'group2'));
598 
599  // unset a child
600  $this->_structure->unsetChild('one', 'two');
601  $this->assertSame(['three'], $this->_structure->getGroupChildNames('one', 'group1'));
602  $this->assertSame(['four'], $this->_structure->getGroupChildNames('one', 'group2'));
603 
604  // return child back
605  $this->_structure->setAsChild('two', 'one');
606  $this->assertSame(['two', 'three'], $this->_structure->getGroupChildNames('one', 'group1'));
607  $this->assertSame(['two', 'four'], $this->_structure->getGroupChildNames('one', 'group2'));
608  }
609 
614  protected function _populateSampleStructure()
615  {
616  $this->_structure->importElements(
617  [
618  'one' => [],
619  'two' => [\Magento\Framework\Data\Structure::PARENT => 'four', 'foo' => 'bar'],
620  'three' => [\Magento\Framework\Data\Structure::PARENT => 'four', 'bar' => 'baz'],
621  'four' => [\Magento\Framework\Data\Structure::CHILDREN => ['three' => 'th', 'two' => 'tw']],
622  'five' => [\Magento\Framework\Data\Structure::PARENT => 'six', 5],
623  'six' => [\Magento\Framework\Data\Structure::CHILDREN => ['five' => 'f']],
624  ]
625  );
626  }
627 
632  protected function _populateSampleSortStructure()
633  {
634  $child = [\Magento\Framework\Data\Structure::PARENT => 'parent'];
635  $this->_structure->importElements(
636  [
637  'parent' => [
638  \Magento\Framework\Data\Structure::CHILDREN => [
639  'one' => 'e1',
640  'two' => 'e2',
641  'three' => 'e3',
642  'four' => 'e4',
643  'five' => 'e5',
644  ],
645  ],
646  'one' => $child,
647  'two' => $child,
648  'three' => $child,
649  'four' => $child,
650  'five' => $child,
651  'x' => [],
652  ]
653  );
654  }
655 }
testReorderChild($initialOffset, $newOffset, $expectedOffset)
$value
Definition: gender.phtml:16
testReorderToSibling($initialOffset, $sibling, $delta, $expectedOffset)
$children
Definition: actions.phtml:11
$element
Definition: element.phtml:12