5
5
*/
6
6
namespace Magento \Test \Integrity ;
7
7
8
+ use Composer \Semver \VersionParser ;
8
9
use Magento \Framework \App \Bootstrap ;
9
10
use Magento \Framework \Component \ComponentRegistrar ;
10
11
use Magento \Framework \Composer \MagentoComponent ;
@@ -20,6 +21,11 @@ class ComposerTest extends \PHPUnit\Framework\TestCase
20
21
*/
21
22
private static $ root ;
22
23
24
+ /**
25
+ * @var array
26
+ */
27
+ private static $ mainComposerModules ;
28
+
23
29
/**
24
30
* @var \stdClass
25
31
*/
@@ -39,6 +45,11 @@ public static function setUpBeforeClass()
39
45
{
40
46
self ::$ root = BP ;
41
47
self ::$ rootJson = json_decode (file_get_contents (self ::$ root . '/composer.json ' ), true );
48
+ $ availableSections = ['require ' , 'require-dev ' , 'replace ' ];
49
+ self ::$ mainComposerModules = [];
50
+ foreach ($ availableSections as $ availableSection ) {
51
+ self ::$ mainComposerModules = array_merge (self ::$ mainComposerModules , self ::$ rootJson [$ availableSection ]);
52
+ }
42
53
self ::$ dependencies = [];
43
54
self ::$ objectManager = Bootstrap::create (BP , $ _SERVER )->getObjectManager ();
44
55
}
@@ -174,6 +185,8 @@ private function assertMagentoConventions($dir, $packageType, \StdClass $json)
174
185
default :
175
186
throw new \InvalidArgumentException ("Unknown package type {$ packageType }" );
176
187
}
188
+
189
+ $ this ->assertPackageVersions ($ json );
177
190
}
178
191
179
192
/**
@@ -290,11 +303,11 @@ private function assertRequireInSync(\StdClass $json)
290
303
// Magento Composer Installer is not needed for already existing components
291
304
continue ;
292
305
}
293
- if (!isset (self ::$ rootJson ['require-dev ' ][$ depName ]) && !isset (self ::$ rootJson ['require ' ][$ depName ])
294
- && !isset (self ::$ rootJson ['replace ' ][$ depName ])) {
306
+ if (!isset (self ::$ mainComposerModules [$ depName ])) {
295
307
$ errors [] = "' $ name' depends on ' $ depName' " ;
296
308
}
297
309
}
310
+
298
311
if (!empty ($ errors )) {
299
312
$ this ->fail (
300
313
"The following dependencies are missing in root 'composer.json', "
@@ -308,6 +321,52 @@ private function assertRequireInSync(\StdClass $json)
308
321
}
309
322
}
310
323
324
+ /**
325
+ *
326
+ *
327
+ * @param \StdClass $json
328
+ */
329
+ private function assertPackageVersions (\StdClass $ json )
330
+ {
331
+ $ name = $ json ->name ;
332
+ if (preg_match ('/magento\/project-*/ ' , self ::$ rootJson ['name ' ]) == 1 ) {
333
+ return ;
334
+ }
335
+ if (isset ($ json ->require )) {
336
+ $ errors = [];
337
+ $ errorTemplate = "root composer.json has dependency '%s:%s' BUT '%s' composer.json has dependency '%s:%s' " ;
338
+ foreach (array_keys ((array )$ json ->require ) as $ depName ) {
339
+ if ($ this ->checkDiscrepancy ($ json , $ depName )) {
340
+ $ errors [] = sprintf (
341
+ $ errorTemplate ,
342
+ $ depName ,
343
+ self ::$ mainComposerModules [$ depName ],
344
+ $ name ,
345
+ $ depName ,
346
+ $ json ->require ->$ depName
347
+ );
348
+ }
349
+ }
350
+
351
+ if (!empty ($ errors )) {
352
+ $ this ->fail (join ("\n" , $ errors ));
353
+ }
354
+ }
355
+ }
356
+
357
+ /**
358
+ * @param $componentConfig
359
+ * @param $packageName
360
+ * @return bool
361
+ */
362
+ private function checkDiscrepancy ($ componentConfig , $ packageName )
363
+ {
364
+ $ rootConstraint = (new VersionParser ())->parseConstraints (self ::$ mainComposerModules [$ packageName ]);
365
+ $ componentConstraint = (new VersionParser ())->parseConstraints ($ componentConfig ->require ->$ packageName );
366
+
367
+ return !$ rootConstraint ->matches ($ componentConstraint );
368
+ }
369
+
311
370
/**
312
371
* Convert a fully qualified module name to a composer package name according to conventions
313
372
*
0 commit comments