8f564c1c6eb0d6cb51086a0d74e67fc33e0ab921
[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 use TYPO3\CMS\Core\Service\DependencyOrderingService;
19 use TYPO3\CMS\Core\Tests\UnitTestCase;
20
21 /**
22 * Test case
23 */
24 class DependencyResolverTest extends 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 {
35 /** @var DependencyResolver|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $dependencyResolver */
36 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
37 $dependencyResolver->injectDependencyOrderingService(new DependencyOrderingService());
38 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn($frameworkPackageKeys);
39 $dependencyGraph = $dependencyResolver->_call('buildDependencyGraph', $unsortedPackageStatesConfiguration);
40
41 $this->assertEquals($expectedGraph, $dependencyGraph);
42 }
43
44 /**
45 * @test
46 * @dataProvider packageSortingDataProvider
47 * @param array $unsortedPackageStatesConfiguration
48 * @param array $frameworkPackageKeys
49 * @param array $expectedSortedPackageStatesConfiguration
50 */
51 public function sortPackageStatesConfigurationByDependencyMakesSureThatDependantPackagesAreStandingBeforeAPackageInTheInternalPackagesAndPackagesConfigurationArrays($unsortedPackageStatesConfiguration, $frameworkPackageKeys, $expectedSortedPackageStatesConfiguration)
52 {
53 /** @var DependencyResolver|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $dependencyResolver */
54 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
55 $dependencyResolver->injectDependencyOrderingService(new DependencyOrderingService());
56 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn($frameworkPackageKeys);
57 $sortedPackageStatesConfiguration = $dependencyResolver->_call('sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);
58
59 $this->assertEquals($expectedSortedPackageStatesConfiguration, $sortedPackageStatesConfiguration, 'The package states configurations have not been ordered according to their dependencies!');
60 }
61
62 /**
63 * @test
64 * @expectedException \UnexpectedValueException
65 */
66 public function sortPackageStatesConfigurationByDependencyThrowsExceptionWhenCycleDetected()
67 {
68 $unsortedPackageStatesConfiguration = array(
69 'A' => array(
70 'state' => 'active',
71 'dependencies' => array('B'),
72 ),
73 'B' => array(
74 'state' => 'active',
75 'dependencies' => array('A')
76 ),
77 );
78
79 /** @var DependencyResolver|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $dependencyResolver */
80 $dependencyResolver = $this->getAccessibleMock(DependencyResolver::class, array('findFrameworkPackages'));
81 $dependencyResolver->injectDependencyOrderingService(new DependencyOrderingService());
82 $dependencyResolver->expects($this->any())->method('findFrameworkPackages')->willReturn(array());
83 $dependencyResolver->_call('sortPackageStatesConfigurationByDependency', $unsortedPackageStatesConfiguration);
84 }
85
86 /**
87 * @return array
88 */
89 public function buildDependencyGraphBuildsCorrectGraphDataProvider()
90 {
91 return array(
92 'TYPO3 Flow Packages' => array(
93 array(
94 'TYPO3.Flow' => array(
95 'state' => 'active',
96 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
97 ),
98 'Doctrine.ORM' => array(
99 'state' => 'active',
100 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
101 ),
102 'Doctrine.Common' => array(
103 'state' => 'active',
104 'dependencies' => array()
105 ),
106 'Doctrine.DBAL' => array(
107 'state' => 'active',
108 'dependencies' => array('Doctrine.Common')
109 ),
110 'Symfony.Component.Yaml' => array(
111 'state' => 'active',
112 'dependencies' => array()
113 ),
114 ),
115 array(
116 'Doctrine.Common'
117 ),
118 array(
119 'TYPO3.Flow' => array(
120 'TYPO3.Flow' => false,
121 'Doctrine.ORM' => true,
122 'Doctrine.Common' => true,
123 'Doctrine.DBAL' => true,
124 'Symfony.Component.Yaml' => true,
125 ),
126 'Doctrine.ORM' => array(
127 'TYPO3.Flow' => false,
128 'Doctrine.ORM' => false,
129 'Doctrine.Common' => true,
130 'Doctrine.DBAL' => true,
131 'Symfony.Component.Yaml' => false,
132 ),
133 'Doctrine.Common' => array(
134 'TYPO3.Flow' => false,
135 'Doctrine.ORM' => false,
136 'Doctrine.Common' => false,
137 'Doctrine.DBAL' => false,
138 'Symfony.Component.Yaml' => false,
139 ),
140 'Doctrine.DBAL' => array(
141 'TYPO3.Flow' => false,
142 'Doctrine.ORM' => false,
143 'Doctrine.Common' => true,
144 'Doctrine.DBAL' => false,
145 'Symfony.Component.Yaml' => false,
146 ),
147 'Symfony.Component.Yaml' => array(
148 'TYPO3.Flow' => false,
149 'Doctrine.ORM' => false,
150 'Doctrine.Common' => true,
151 'Doctrine.DBAL' => false,
152 'Symfony.Component.Yaml' => false,
153 ),
154 ),
155 ),
156 'TYPO3 CMS Extensions' => array(
157 array(
158 'core' => array(
159 'state' => 'active',
160 'dependencies' => array(),
161 ),
162 'setup' => array(
163 'state' => 'active',
164 'dependencies' => array('core'),
165 ),
166 'openid' => array(
167 'state' => 'active',
168 'dependencies' => array('core', 'setup')
169 ),
170 'news' => array(
171 'state' => 'active',
172 'dependencies' => array('extbase'),
173 ),
174 'extbase' => array(
175 'state' => 'active',
176 'dependencies' => array('core'),
177 ),
178 'pt_extbase' => array(
179 'state' => 'active',
180 'dependencies' => array('extbase'),
181 ),
182 'foo' => array(
183 'state' => 'active',
184 'dependencies' => array(),
185 ),
186 ),
187 array(
188 'core', 'setup', 'openid', 'extbase'
189 ),
190 array(
191 'core' => array(
192 'core' => false,
193 'setup' => false,
194 'openid' => false,
195 'news' => false,
196 'extbase' => false,
197 'pt_extbase' => false,
198 'foo' => false
199 ),
200 'setup' => array(
201 'core' => true,
202 'setup' => false,
203 'openid' => false,
204 'news' => false,
205 'extbase' => false,
206 'pt_extbase' => false,
207 'foo' => false
208 ),
209 'openid' => array(
210 'core' => true,
211 'setup' => true,
212 'openid' => false,
213 'news' => false,
214 'extbase' => false,
215 'pt_extbase' => false,
216 'foo' => false
217 ),
218 'news' => array(
219 'core' => false,
220 'setup' => false,
221 'openid' => true,
222 'news' => false,
223 'extbase' => true,
224 'pt_extbase' => false,
225 'foo' => false
226 ),
227 'extbase' => array(
228 'core' => true,
229 'setup' => false,
230 'openid' => false,
231 'news' => false,
232 'extbase' => false,
233 'pt_extbase' => false,
234 'foo' => false
235 ),
236 'pt_extbase' => array(
237 'core' => false,
238 'setup' => false,
239 'openid' => true,
240 'news' => false,
241 'extbase' => true,
242 'pt_extbase' => false,
243 'foo' => false
244 ),
245 'foo' => array(
246 'core' => false,
247 'setup' => false,
248 'openid' => true,
249 'news' => false,
250 'extbase' => true,
251 'pt_extbase' => false,
252 'foo' => false
253 ),
254 ),
255 ),
256 'Dummy Packages' => array(
257 array(
258 'A' => array(
259 'state' => 'active',
260 'dependencies' => array('B', 'D', 'C'),
261 ),
262 'B' => array(
263 'state' => 'active',
264 'dependencies' => array()
265 ),
266 'C' => array(
267 'state' => 'active',
268 'dependencies' => array('E')
269 ),
270 'D' => array(
271 'state' => 'active',
272 'dependencies' => array('E'),
273 ),
274 'E' => array(
275 'state' => 'active',
276 'dependencies' => array(),
277 ),
278 'F' => array(
279 'state' => 'active',
280 'dependencies' => array(),
281 ),
282 ),
283 array(
284 'B', 'C', 'E'
285 ),
286 array(
287 'A' => array(
288 'A' => false,
289 'B' => true,
290 'C' => true,
291 'D' => true,
292 'E' => false,
293 'F' => false,
294 ),
295 'B' => array(
296 'A' => false,
297 'B' => false,
298 'C' => false,
299 'D' => false,
300 'E' => false,
301 'F' => false,
302 ),
303 'C' => array(
304 'A' => false,
305 'B' => false,
306 'C' => false,
307 'D' => false,
308 'E' => true,
309 'F' => false,
310 ),
311 'D' => array(
312 'A' => false,
313 'B' => true,
314 'C' => true,
315 'D' => false,
316 'E' => false,
317 'F' => false,
318 ),
319 'E' => array(
320 'A' => false,
321 'B' => false,
322 'C' => false,
323 'D' => false,
324 'E' => false,
325 'F' => false,
326 ),
327 'F' => array(
328 'A' => false,
329 'B' => true,
330 'C' => true,
331 'D' => false,
332 'E' => false,
333 'F' => false,
334 ),
335 ),
336 ),
337 );
338 }
339
340 /**
341 * @return array
342 */
343 public function packageSortingDataProvider()
344 {
345 return array(
346 'TYPO3 Flow Packages' => array(
347 array(
348 'TYPO3.Flow' => array(
349 'state' => 'active',
350 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
351 ),
352 'Doctrine.ORM' => array(
353 'state' => 'active',
354 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
355 ),
356 'Doctrine.Common' => array(
357 'state' => 'active',
358 'dependencies' => array()
359 ),
360 'Doctrine.DBAL' => array(
361 'state' => 'active',
362 'dependencies' => array('Doctrine.Common')
363 ),
364 'Symfony.Component.Yaml' => array(
365 'state' => 'active',
366 'dependencies' => array()
367 ),
368 ),
369 array(
370 'Doctrine.Common'
371 ),
372 array(
373 'Doctrine.Common' => array(
374 'state' => 'active',
375 'dependencies' => array()
376 ),
377 'Doctrine.DBAL' => array(
378 'state' => 'active',
379 'dependencies' => array('Doctrine.Common')
380 ),
381 'Doctrine.ORM' => array(
382 'state' => 'active',
383 'dependencies' => array('Doctrine.Common', 'Doctrine.DBAL')
384 ),
385 'Symfony.Component.Yaml' => array(
386 'state' => 'active',
387 'dependencies' => array()
388 ),
389 'TYPO3.Flow' => array(
390 'state' => 'active',
391 'dependencies' => array('Symfony.Component.Yaml', 'Doctrine.Common', 'Doctrine.DBAL', 'Doctrine.ORM')
392 ),
393 ),
394 ),
395 'TYPO3 CMS Extensions' => array(
396 array(
397 'core' => array(
398 'state' => 'active',
399 'dependencies' => array(),
400 ),
401 'setup' => array(
402 'state' => 'active',
403 'dependencies' => array('core'),
404 ),
405 'openid' => array(
406 'state' => 'active',
407 'dependencies' => array('core', 'setup')
408 ),
409 'news' => array(
410 'state' => 'active',
411 'dependencies' => array('extbase'),
412 ),
413 'extbase' => array(
414 'state' => 'active',
415 'dependencies' => array('core'),
416 ),
417 'pt_extbase' => array(
418 'state' => 'active',
419 'dependencies' => array('extbase'),
420 ),
421 'foo' => array(
422 'state' => 'active',
423 'dependencies' => array(),
424 ),
425 ),
426 array(
427 'core', 'setup', 'openid', 'extbase'
428 ),
429 array(
430 'core' => array(
431 'state' => 'active',
432 'dependencies' => array(),
433 ),
434 'setup' => array(
435 'state' => 'active',
436 'dependencies' => array('core'),
437 ),
438 'openid' => array(
439 'state' => 'active',
440 'dependencies' => array('core', 'setup')
441 ),
442 'extbase' => array(
443 'state' => 'active',
444 'dependencies' => array('core'),
445 ),
446 'foo' => array(
447 'state' => 'active',
448 'dependencies' => array(),
449 ),
450 'pt_extbase' => array(
451 'state' => 'active',
452 'dependencies' => array('extbase'),
453 ),
454 'news' => array(
455 'state' => 'active',
456 'dependencies' => array('extbase'),
457 ),
458 ),
459 ),
460 'Dummy Packages' => array(
461 array(
462 'A' => array(
463 'state' => 'active',
464 'dependencies' => array('B', 'D', 'C'),
465 ),
466 'B' => array(
467 'state' => 'active',
468 'dependencies' => array()
469 ),
470 'C' => array(
471 'state' => 'active',
472 'dependencies' => array('E')
473 ),
474 'D' => array(
475 'state' => 'active',
476 'dependencies' => array('E'),
477 ),
478 'E' => array(
479 'state' => 'active',
480 'dependencies' => array(),
481 ),
482 'F' => array(
483 'state' => 'active',
484 'dependencies' => array(),
485 ),
486 ),
487 array(
488 'B', 'C', 'E'
489 ),
490 array(
491 'B' => array(
492 'state' => 'active',
493 'dependencies' => array(),
494 ),
495 'E' => array(
496 'state' => 'active',
497 'dependencies' => array(),
498 ),
499 'C' => array(
500 'state' => 'active',
501 'dependencies' => array('E'),
502 ),
503 'F' => array(
504 'state' => 'active',
505 'dependencies' => array(),
506 ),
507 'D' => array(
508 'state' => 'active',
509 'dependencies' => array('E'),
510 ),
511 'A' => array(
512 'state' => 'active',
513 'dependencies' => array('B', 'D', 'C'),
514 ),
515 ),
516 ),
517 );
518 }
519 }