[TASK] Add extension precedence
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Package / DependencyResolverTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Package;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Package\DependencyResolver;
18
19 /**
20 * Testcase for the dependency resolver class
21 *
22 * @author Markus Klein <klein.t3@mfc-linz.at>
23 */
24 class DependencyResolverTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
25
26 /**
27 * @test
28 * @param array $unsortedPackageStatesConfiguration
29 * @param array $frameworkPackageKeys
30 * @param array $expectedGraph
31 * @dataProvider buildDependencyGraphBuildsCorrectGraphDataProvider
32 */
33 public function buildDependencyGraphBuildsCorrectGraph(array $unsortedPackageStatesConfiguration, array $frameworkPackageKeys, array $expectedGraph) {
34 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
35 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn($frameworkPackageKeys);
36 $dependencyGraph = $dependencyResolver->_call('buildDependencyGraph', $unsortedPackageStatesConfiguration);
37
38 $this->assertEquals($expectedGraph, $dependencyGraph);
39 }
40
41 /**
42 * @test
43 * @dataProvider packageSortingDataProvider
44 */
45 public function sortPackageStatesConfigurationByDependencyMakesSureThatDependantPackagesAreStandingBeforeAPackageInTheInternalPackagesAndPackagesConfigurationArrays($unsortedPackageStatesConfiguration, $frameworkPackageKeys, $expectedSortedPackageStatesConfiguration) {
46 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
47 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn($frameworkPackageKeys);
48 $sortedPackageStatesConfiguration = $dependencyResolver->_call('sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);
49
50 $this->assertEquals($expectedSortedPackageStatesConfiguration, $sortedPackageStatesConfiguration, 'The package states configurations have not been ordered according to their dependencies!');
51 }
52
53 /**
54 * @test
55 * @dataProvider buildDependencyGraphForPackagesBuildsCorrectGraphDataProvider
56 */
57 public function buildDependencyGraphForPackagesBuildsCorrectGraph($packages, $expectedGraph) {
58 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
59 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn(array());
60 $dependencyGraph = $dependencyResolver->_call('buildDependencyGraphForPackages', $packages, array_keys($packages));
61
62 $this->assertEquals($expectedGraph, $dependencyGraph);
63 }
64
65 /**
66 * @test
67 * @expectedException \UnexpectedValueException
68 */
69 public function sortPackageStatesConfigurationByDependencyThrowsExceptionWhenCycleDetected() {
70 $unsortedPackageStatesConfiguration = array(
71 'A' => array(
72 'state' => 'active',
73 'dependencies' => array('B'),
74 ),
75 'B' => array(
76 'state' => 'active',
77 'dependencies' => array('A')
78 ),
79 );
80
81 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
82 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn(array());
83 $dependencyResolver->_call('sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);
84 }
85
86 /**
87 * @test
88 * @expectedException \UnexpectedValueException
89 */
90 public function buildDependencyGraphForPackagesThrowsExceptionWhenDependencyOnUnavailablePackageDetected() {
91 $packages = array(
92 'A' => array(
93 'dependencies' => array('B'),
94 )
95 );
96 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('dummy'));
97 $dependencyResolver->_call('buildDependencyGraphForPackages', $packages, array_keys($packages));
98 }
99
100 /**
101 * @return array
102 */
103 public function buildDependencyGraphBuildsCorrectGraphDataProvider() {
104 return array(
105 'TYPO3 Flow Packages' => array(
106 array(
107 'TYPO3.Flow' => array(
108 'state' => 'active',
109 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
110 ),
111 'Doctrine.ORM' => array(
112 'state' => 'active',
113 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
114 ),
115 'Doctrine.Common' => array(
116 'state' => 'active',
117 'dependencies' => array()
118 ),
119 'Doctrine.DBAL' => array(
120 'state' => 'active',
121 'dependencies' => array('Doctrine.Common')
122 ),
123 'Symfony.Component.Yaml' => array(
124 'state' => 'active',
125 'dependencies' => array()
126 ),
127 ),
128 array(
129 'Doctrine.Common'
130 ),
131 array(
132 'TYPO3.Flow' => array(
133 'TYPO3.Flow' => FALSE,
134 'Doctrine.ORM' => TRUE,
135 'Doctrine.Common' => TRUE,
136 'Doctrine.DBAL' => TRUE,
137 'Symfony.Component.Yaml' => TRUE,
138 ),
139 'Doctrine.ORM' => array(
140 'TYPO3.Flow' => FALSE,
141 'Doctrine.ORM' => FALSE,
142 'Doctrine.Common' => TRUE,
143 'Doctrine.DBAL' => TRUE,
144 'Symfony.Component.Yaml' => FALSE,
145 ),
146 'Doctrine.Common' => array(
147 'TYPO3.Flow' => FALSE,
148 'Doctrine.ORM' => FALSE,
149 'Doctrine.Common' => FALSE,
150 'Doctrine.DBAL' => FALSE,
151 'Symfony.Component.Yaml' => FALSE,
152 ),
153 'Doctrine.DBAL' => array(
154 'TYPO3.Flow' => FALSE,
155 'Doctrine.ORM' => FALSE,
156 'Doctrine.Common' => TRUE,
157 'Doctrine.DBAL' => FALSE,
158 'Symfony.Component.Yaml' => FALSE,
159 ),
160 'Symfony.Component.Yaml' => array(
161 'TYPO3.Flow' => FALSE,
162 'Doctrine.ORM' => FALSE,
163 'Doctrine.Common' => TRUE,
164 'Doctrine.DBAL' => FALSE,
165 'Symfony.Component.Yaml' => FALSE,
166 ),
167 ),
168 ),
169 'TYPO3 CMS Extensions' => array(
170 array(
171 'core' => array(
172 'state' => 'active',
173 'dependencies' => array(),
174 ),
175 'setup' => array (
176 'state' => 'active',
177 'dependencies' => array('core'),
178 ),
179 'openid' => array(
180 'state' => 'active',
181 'dependencies' => array('core', 'setup')
182 ),
183 'news' => array (
184 'state' => 'active',
185 'dependencies' => array('extbase'),
186 ),
187 'extbase' => array (
188 'state' => 'active',
189 'dependencies' => array('core'),
190 ),
191 'pt_extbase' => array (
192 'state' => 'active',
193 'dependencies' => array('extbase'),
194 ),
195 'foo' => array (
196 'state' => 'active',
197 'dependencies' => array(),
198 ),
199 ),
200 array(
201 'core', 'setup', 'openid', 'extbase'
202 ),
203 array(
204 'core' => array(
205 'core' => FALSE,
206 'setup' => FALSE,
207 'openid' => FALSE,
208 'news' => FALSE,
209 'extbase' => FALSE,
210 'pt_extbase' => FALSE,
211 'foo' => FALSE
212 ),
213 'setup' => array(
214 'core' => TRUE,
215 'setup' => FALSE,
216 'openid' => FALSE,
217 'news' => FALSE,
218 'extbase' => FALSE,
219 'pt_extbase' => FALSE,
220 'foo' => FALSE
221 ),
222 'openid' => array (
223 'core' => TRUE,
224 'setup' => TRUE,
225 'openid' => FALSE,
226 'news' => FALSE,
227 'extbase' => FALSE,
228 'pt_extbase' => FALSE,
229 'foo' => FALSE
230 ),
231 'news' => array (
232 'core' => FALSE,
233 'setup' => FALSE,
234 'openid' => TRUE,
235 'news' => FALSE,
236 'extbase' => TRUE,
237 'pt_extbase' => FALSE,
238 'foo' => FALSE
239 ),
240 'extbase' => array (
241 'core' => TRUE,
242 'setup' => FALSE,
243 'openid' => FALSE,
244 'news' => FALSE,
245 'extbase' => FALSE,
246 'pt_extbase' => FALSE,
247 'foo' => FALSE
248 ),
249 'pt_extbase' => array(
250 'core' => FALSE,
251 'setup' => FALSE,
252 'openid' => TRUE,
253 'news' => FALSE,
254 'extbase' => TRUE,
255 'pt_extbase' => FALSE,
256 'foo' => FALSE
257 ),
258 'foo' => array(
259 'core' => FALSE,
260 'setup' => FALSE,
261 'openid' => TRUE,
262 'news' => FALSE,
263 'extbase' => TRUE,
264 'pt_extbase' => FALSE,
265 'foo' => FALSE
266 ),
267 ),
268 ),
269 'Dummy Packages' => array(
270 array(
271 'A' => array(
272 'state' => 'active',
273 'dependencies' => array('B', 'D', 'C'),
274 ),
275 'B' => array(
276 'state' => 'active',
277 'dependencies' => array()
278 ),
279 'C' => array(
280 'state' => 'active',
281 'dependencies' => array('E')
282 ),
283 'D' => array (
284 'state' => 'active',
285 'dependencies' => array('E'),
286 ),
287 'E' => array (
288 'state' => 'active',
289 'dependencies' => array(),
290 ),
291 'F' => array (
292 'state' => 'active',
293 'dependencies' => array(),
294 ),
295 ),
296 array(
297 'B', 'C', 'E'
298 ),
299 array(
300 'A' => array(
301 'A' => FALSE,
302 'B' => TRUE,
303 'C' => TRUE,
304 'D' => TRUE,
305 'E' => FALSE,
306 'F' => FALSE,
307 ),
308 'B' => array(
309 'A' => FALSE,
310 'B' => FALSE,
311 'C' => FALSE,
312 'D' => FALSE,
313 'E' => FALSE,
314 'F' => FALSE,
315 ),
316 'C' => array(
317 'A' => FALSE,
318 'B' => FALSE,
319 'C' => FALSE,
320 'D' => FALSE,
321 'E' => TRUE,
322 'F' => FALSE,
323 ),
324 'D' => array (
325 'A' => FALSE,
326 'B' => TRUE,
327 'C' => TRUE,
328 'D' => FALSE,
329 'E' => FALSE,
330 'F' => FALSE,
331 ),
332 'E' => array (
333 'A' => FALSE,
334 'B' => FALSE,
335 'C' => FALSE,
336 'D' => FALSE,
337 'E' => FALSE,
338 'F' => FALSE,
339 ),
340 'F' => array (
341 'A' => FALSE,
342 'B' => TRUE,
343 'C' => TRUE,
344 'D' => FALSE,
345 'E' => FALSE,
346 'F' => FALSE,
347 ),
348 ),
349 ),
350 );
351 }
352
353 /**
354 * @return array
355 */
356 public function packageSortingDataProvider() {
357 return array(
358 'TYPO3 Flow Packages' => array(
359 array(
360 'TYPO3.Flow' => array(
361 'state' => 'active',
362 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
363 ),
364 'Doctrine.ORM' => array(
365 'state' => 'active',
366 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
367 ),
368 'Doctrine.Common' => array(
369 'state' => 'active',
370 'dependencies' => array()
371 ),
372 'Doctrine.DBAL' => array(
373 'state' => 'active',
374 'dependencies' => array('Doctrine.Common')
375 ),
376 'Symfony.Component.Yaml' => array(
377 'state' => 'active',
378 'dependencies' => array()
379 ),
380 ),
381 array(
382 'Doctrine.Common'
383 ),
384 array(
385 'Doctrine.Common' => array(
386 'state' => 'active',
387 'dependencies' => array()
388 ),
389 'Doctrine.DBAL' => array(
390 'state' => 'active',
391 'dependencies' => array('Doctrine.Common')
392 ),
393 'Doctrine.ORM' => array(
394 'state' => 'active',
395 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
396 ),
397 'Symfony.Component.Yaml' => array(
398 'state' => 'active',
399 'dependencies' => array()
400 ),
401 'TYPO3.Flow' => array(
402 'state' => 'active',
403 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
404 ),
405 ),
406 ),
407 'TYPO3 CMS Extensions' => array(
408 array(
409 'core' => array(
410 'state' => 'active',
411 'dependencies' => array(),
412 ),
413 'setup' => array (
414 'state' => 'active',
415 'dependencies' => array('core'),
416 ),
417 'openid' => array(
418 'state' => 'active',
419 'dependencies' => array('core', 'setup')
420 ),
421 'news' => array (
422 'state' => 'active',
423 'dependencies' => array('extbase'),
424 ),
425 'extbase' => array (
426 'state' => 'active',
427 'dependencies' => array('core'),
428 ),
429 'pt_extbase' => array (
430 'state' => 'active',
431 'dependencies' => array('extbase'),
432 ),
433 'foo' => array (
434 'state' => 'active',
435 'dependencies' => array(),
436 ),
437 ),
438 array(
439 'core', 'setup', 'openid', 'extbase'
440 ),
441 array(
442 'core' => array(
443 'state' => 'active',
444 'dependencies' => array(),
445 ),
446 'setup' => array (
447 'state' => 'active',
448 'dependencies' => array('core'),
449 ),
450 'openid' => array(
451 'state' => 'active',
452 'dependencies' => array('core', 'setup')
453 ),
454 'extbase' => array (
455 'state' => 'active',
456 'dependencies' => array('core'),
457 ),
458 'foo' => array (
459 'state' => 'active',
460 'dependencies' => array(),
461 ),
462 'pt_extbase' => array (
463 'state' => 'active',
464 'dependencies' => array('extbase'),
465 ),
466 'news' => array (
467 'state' => 'active',
468 'dependencies' => array('extbase'),
469 ),
470 ),
471 ),
472 'Dummy Packages' => array(
473 array(
474 'A' => array(
475 'state' => 'active',
476 'dependencies' => array('B', 'D', 'C'),
477 ),
478 'B' => array(
479 'state' => 'active',
480 'dependencies' => array()
481 ),
482 'C' => array(
483 'state' => 'active',
484 'dependencies' => array('E')
485 ),
486 'D' => array (
487 'state' => 'active',
488 'dependencies' => array('E'),
489 ),
490 'E' => array (
491 'state' => 'active',
492 'dependencies' => array(),
493 ),
494 'F' => array (
495 'state' => 'active',
496 'dependencies' => array(),
497 ),
498 ),
499 array(
500 'B', 'C', 'E'
501 ),
502 array(
503 'B' => array(
504 'state' => 'active',
505 'dependencies' => array(),
506 ),
507 'E' => array (
508 'state' => 'active',
509 'dependencies' => array(),
510 ),
511 'C' => array (
512 'state' => 'active',
513 'dependencies' => array('E'),
514 ),
515 'F' => array (
516 'state' => 'active',
517 'dependencies' => array(),
518 ),
519 'D' => array(
520 'state' => 'active',
521 'dependencies' => array('E'),
522 ),
523 'A' => array(
524 'state' => 'active',
525 'dependencies' => array('B', 'D', 'C'),
526 ),
527 ),
528 ),
529 );
530 }
531
532 /**
533 * @return array
534 */
535 public function buildDependencyGraphForPackagesBuildsCorrectGraphDataProvider() {
536 return array(
537 'TYPO3 Flow Packages' => array(
538 array(
539 'TYPO3.Flow' => array(
540 'state' => 'active',
541 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
542 ),
543 'Doctrine.ORM' => array(
544 'state' => 'active',
545 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
546 ),
547 'Doctrine.Common' => array(
548 'state' => 'active',
549 'dependencies' => array()
550 ),
551 'Doctrine.DBAL' => array(
552 'state' => 'active',
553 'dependencies' => array('Doctrine.Common')
554 ),
555 'Symfony.Component.Yaml' => array(
556 'state' => 'active',
557 'dependencies' => array()
558 ),
559 ),
560 array(
561 'TYPO3.Flow' => array(
562 'TYPO3.Flow' => FALSE,
563 'Doctrine.ORM' => TRUE,
564 'Doctrine.Common' => TRUE,
565 'Doctrine.DBAL' => TRUE,
566 'Symfony.Component.Yaml' => TRUE,
567 ),
568 'Doctrine.ORM' => array(
569 'TYPO3.Flow' => FALSE,
570 'Doctrine.ORM' => FALSE,
571 'Doctrine.Common' => TRUE,
572 'Doctrine.DBAL' => TRUE,
573 'Symfony.Component.Yaml' => FALSE,
574 ),
575 'Doctrine.Common' => array(
576 'TYPO3.Flow' => FALSE,
577 'Doctrine.ORM' => FALSE,
578 'Doctrine.Common' => FALSE,
579 'Doctrine.DBAL' => FALSE,
580 'Symfony.Component.Yaml' => FALSE,
581 ),
582 'Doctrine.DBAL' => array(
583 'TYPO3.Flow' => FALSE,
584 'Doctrine.ORM' => FALSE,
585 'Doctrine.Common' => TRUE,
586 'Doctrine.DBAL' => FALSE,
587 'Symfony.Component.Yaml' => FALSE,
588 ),
589 'Symfony.Component.Yaml' => array(
590 'TYPO3.Flow' => FALSE,
591 'Doctrine.ORM' => FALSE,
592 'Doctrine.Common' => FALSE,
593 'Doctrine.DBAL' => FALSE,
594 'Symfony.Component.Yaml' => FALSE,
595 ),
596 ),
597 ),
598 'TYPO3 CMS Extensions' => array(
599 array(
600 'core' => array(
601 'state' => 'active',
602 'dependencies' => array(),
603 ),
604 'openid' => array(
605 'state' => 'active',
606 'dependencies' => array('core', 'setup')
607 ),
608 'scheduler' => array (
609 'state' => 'active',
610 'dependencies' => array('core'),
611 ),
612 'setup' => array (
613 'state' => 'active',
614 'dependencies' => array('core'),
615 ),
616 'sv' => array (
617 'state' => 'active',
618 'dependencies' => array('core'),
619 ),
620 ),
621 array(
622 'core' => array(
623 'core' => FALSE,
624 'setup' => FALSE,
625 'sv' => FALSE,
626 'scheduler' => FALSE,
627 'openid' => FALSE,
628 ),
629 'openid' => array(
630 'core' => TRUE,
631 'setup' => TRUE,
632 'sv' => FALSE,
633 'scheduler' => FALSE,
634 'openid' => FALSE,
635 ),
636 'scheduler' => array (
637 'core' => TRUE,
638 'setup' => FALSE,
639 'sv' => FALSE,
640 'scheduler' => FALSE,
641 'openid' => FALSE,
642 ),
643 'setup' => array (
644 'core' => TRUE,
645 'setup' => FALSE,
646 'sv' => FALSE,
647 'scheduler' => FALSE,
648 'openid' => FALSE,
649 ),
650 'sv' => array (
651 'core' => TRUE,
652 'setup' => FALSE,
653 'sv' => FALSE,
654 'scheduler' => FALSE,
655 'openid' => FALSE,
656 ),
657 ),
658 ),
659 'Dummy Packages' => array(
660 array(
661 'A' => array(
662 'state' => 'active',
663 'dependencies' => array('B', 'D', 'C'),
664 ),
665 'B' => array(
666 'state' => 'active',
667 'dependencies' => array()
668 ),
669 'C' => array(
670 'state' => 'active',
671 'dependencies' => array('E')
672 ),
673 'D' => array (
674 'state' => 'active',
675 'dependencies' => array('E'),
676 ),
677 'E' => array (
678 'state' => 'active',
679 'dependencies' => array(),
680 ),
681 'F' => array (
682 'state' => 'active',
683 'dependencies' => array(),
684 ),
685 ),
686 array(
687 'A' => array(
688 'A' => FALSE,
689 'B' => TRUE,
690 'C' => TRUE,
691 'D' => TRUE,
692 'E' => FALSE,
693 'F' => FALSE,
694 ),
695 'B' => array(
696 'A' => FALSE,
697 'B' => FALSE,
698 'C' => FALSE,
699 'D' => FALSE,
700 'E' => FALSE,
701 'F' => FALSE,
702 ),
703 'C' => array(
704 'A' => FALSE,
705 'B' => FALSE,
706 'C' => FALSE,
707 'D' => FALSE,
708 'E' => TRUE,
709 'F' => FALSE,
710 ),
711 'D' => array (
712 'A' => FALSE,
713 'B' => FALSE,
714 'C' => FALSE,
715 'D' => FALSE,
716 'E' => TRUE,
717 'F' => FALSE,
718 ),
719 'E' => array (
720 'A' => FALSE,
721 'B' => FALSE,
722 'C' => FALSE,
723 'D' => FALSE,
724 'E' => FALSE,
725 'F' => FALSE,
726 ),
727 'F' => array (
728 'A' => FALSE,
729 'B' => FALSE,
730 'C' => FALSE,
731 'D' => FALSE,
732 'E' => FALSE,
733 'F' => FALSE,
734 ),
735 ),
736 ),
737 'Suggestions without reverse dependency' => array(
738 array(
739 'A' => array(
740 'state' => 'active',
741 'suggestions' => array('B'),
742 ),
743 'B' => array(
744 'state' => 'active',
745 ),
746 'C' => array(
747 'state' => 'active',
748 'dependencies' => array('A')
749 ),
750 ),
751 array(
752 'A' => array(
753 'A' => FALSE,
754 'B' => TRUE,
755 'C' => FALSE,
756 ),
757 'B' => array(
758 'A' => FALSE,
759 'B' => FALSE,
760 'C' => FALSE,
761 ),
762 'C' => array(
763 'A' => TRUE,
764 'B' => FALSE,
765 'C' => FALSE,
766 ),
767 ),
768 ),
769 'Suggestions with reverse dependency' => array(
770 array(
771 'A' => array(
772 'state' => 'active',
773 'suggestions' => array('B'),
774 ),
775 'B' => array(
776 'state' => 'active',
777 'dependencies' => array('A')
778 ),
779 'C' => array(
780 'state' => 'active',
781 'dependencies' => array('A')
782 ),
783 ),
784 array(
785 'A' => array(
786 'A' => FALSE,
787 'B' => FALSE,
788 'C' => FALSE,
789 ),
790 'B' => array(
791 'A' => TRUE,
792 'B' => FALSE,
793 'C' => FALSE,
794 ),
795 'C' => array(
796 'A' => TRUE,
797 'B' => FALSE,
798 'C' => FALSE,
799 ),
800 ),
801 ),
802 );
803 }
804
805 /**
806 * @return array
807 */
808 public function findPathInGraphReturnsCorrectPathDataProvider() {
809 return array(
810 'Simple path' => array(
811 array(
812 'A' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => TRUE),
813 'B' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE),
814 'C' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE),
815 'Z' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE)
816 ),
817 'A', 'Z',
818 array('A', 'Z')
819 ),
820 'No path' => array(
821 array(
822 'A' => array('A' => FALSE, 'B' => TRUE, 'C' => FALSE, 'Z' => FALSE),
823 'B' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE),
824 'C' => array('A' => FALSE, 'B' => TRUE, 'C' => FALSE, 'Z' => FALSE),
825 'Z' => array('A' => FALSE, 'B' => TRUE, 'C' => FALSE, 'Z' => FALSE)
826 ),
827 'A', 'C',
828 array()
829 ),
830 'Longer path' => array(
831 array(
832 'A' => array('A' => FALSE, 'B' => TRUE, 'C' => TRUE, 'Z' => TRUE),
833 'B' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE),
834 'C' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => TRUE),
835 'Z' => array('A' => FALSE, 'B' => FALSE, 'C' => FALSE, 'Z' => FALSE)
836 ),
837 'A', 'Z',
838 array('A', 'C', 'Z')
839 ),
840 );
841 }
842
843 /**
844 * @param array $graph
845 * @param string $from
846 * @param string $to
847 * @param array $expected
848 * @test
849 * @dataProvider findPathInGraphReturnsCorrectPathDataProvider
850 */
851 public function findPathInGraphReturnsCorrectPath(array $graph, $from, $to, array $expected) {
852 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('dummy'));
853 $path = $dependencyResolver->_call('findPathInGraph', $graph, $from, $to);
854
855 $this->assertSame($expected, $path);
856 }
857
858 }