Skip to content

Commit 786e0e6

Browse files
authored
Merge pull request #2155 from magento-borg/DEVOPS-2174
Fixed issues: - DEVOPS-2346 Fix static tests - MAGETWO-50594 testAclConfigFile uses full path name in test
2 parents ed6723f + 8fbf4cd commit 786e0e6

File tree

6 files changed

+158
-50
lines changed

6 files changed

+158
-50
lines changed

dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,42 @@ class ComposerTest extends \PHPUnit\Framework\TestCase
3535
*/
3636
private static $objectManager;
3737

38+
/**
39+
* @var string[]
40+
*/
41+
private static $rootComposerModuleBlacklist = [];
42+
43+
/**
44+
* @var string[]
45+
*/
46+
private static $moduleNameBlacklist;
47+
3848
public static function setUpBeforeClass()
3949
{
4050
self::$root = BP;
4151
self::$rootJson = json_decode(file_get_contents(self::$root . '/composer.json'), true);
4252
self::$dependencies = [];
4353
self::$objectManager = Bootstrap::create(BP, $_SERVER)->getObjectManager();
54+
// A block can be whitelisted and thus not be required to be public
55+
self::$rootComposerModuleBlacklist = self::getBlacklist(
56+
__DIR__ . '/_files/blacklist/composer_root_modules*.txt'
57+
);
58+
self::$moduleNameBlacklist = self::getBlacklist(__DIR__ . '/_files/blacklist/composer_module_names*.txt');
59+
}
60+
61+
/**
62+
* Return aggregated blacklist
63+
*
64+
* @param string $pattern
65+
* @return string[]
66+
*/
67+
public static function getBlacklist(string $pattern)
68+
{
69+
$blacklist = [];
70+
foreach (glob($pattern) as $list) {
71+
$blacklist = array_merge($blacklist, file($list, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
72+
}
73+
return $blacklist;
4474
}
4575

4676
public function testValidComposerJson()
@@ -222,13 +252,15 @@ private function assertNoMap(\StdClass $json)
222252
*/
223253
private function assertConsistentModuleName(\SimpleXMLElement $xml, $packageName)
224254
{
225-
$moduleName = (string)$xml->module->attributes()->name;
226-
$expectedPackageName = $this->convertModuleToPackageName($moduleName);
227-
$this->assertEquals(
228-
$expectedPackageName,
229-
$packageName,
230-
"For the module '{$moduleName}', the expected package name is '{$expectedPackageName}'"
231-
);
255+
if (!in_array($packageName, self::$moduleNameBlacklist)) {
256+
$moduleName = (string)$xml->module->attributes()->name;
257+
$expectedPackageName = $this->convertModuleToPackageName($moduleName);
258+
$this->assertEquals(
259+
$expectedPackageName,
260+
$packageName,
261+
"For the module '{$moduleName}', the expected package name is '{$expectedPackageName}'"
262+
);
263+
}
232264
}
233265

234266
/**
@@ -277,36 +309,48 @@ private function assertPhpVersionInSync($name, $phpVersion)
277309
* Make sure requirements of components are reflected in root composer.json
278310
*
279311
* @param \StdClass $json
312+
* @return void
280313
*/
281314
private function assertRequireInSync(\StdClass $json)
282315
{
283-
$name = $json->name;
284316
if (preg_match('/magento\/project-*/', self::$rootJson['name']) == 1) {
285317
return;
286318
}
287-
if (isset($json->require)) {
288-
$errors = [];
289-
foreach (array_keys((array)$json->require) as $depName) {
290-
if ($depName == 'magento/magento-composer-installer') {
291-
// Magento Composer Installer is not needed for already existing components
292-
continue;
293-
}
294-
if (!isset(self::$rootJson['require-dev'][$depName]) && !isset(self::$rootJson['require'][$depName])
295-
&& !isset(self::$rootJson['replace'][$depName])) {
296-
$errors[] = "'$name' depends on '$depName'";
297-
}
319+
if (!in_array($json->name, self::$rootComposerModuleBlacklist) && isset($json->require)) {
320+
$this->checkPackageInRootComposer($json);
321+
}
322+
}
323+
324+
/**
325+
* Check if package is reflected in root composer.json
326+
*
327+
* @param \StdClass $json
328+
* @return void
329+
*/
330+
private function checkPackageInRootComposer(\StdClass $json)
331+
{
332+
$name = $json->name;
333+
$errors = [];
334+
foreach (array_keys((array)$json->require) as $depName) {
335+
if ($depName == 'magento/magento-composer-installer') {
336+
// Magento Composer Installer is not needed for already existing components
337+
continue;
298338
}
299-
if (!empty($errors)) {
300-
$this->fail(
301-
"The following dependencies are missing in root 'composer.json',"
302-
. " while declared in child components.\n"
303-
. "Consider adding them to 'require-dev' section (if needed for child components only),"
304-
. " to 'replace' section (if they are present in the project),"
305-
. " to 'require' section (if needed for the skeleton).\n"
306-
. join("\n", $errors)
307-
);
339+
if (!isset(self::$rootJson['require-dev'][$depName]) && !isset(self::$rootJson['require'][$depName])
340+
&& !isset(self::$rootJson['replace'][$depName])) {
341+
$errors[] = "'$name' depends on '$depName'";
308342
}
309343
}
344+
if (!empty($errors)) {
345+
$this->fail(
346+
"The following dependencies are missing in root 'composer.json',"
347+
. " while declared in child components.\n"
348+
. "Consider adding them to 'require-dev' section (if needed for child components only),"
349+
. " to 'replace' section (if they are present in the project),"
350+
. " to 'require' section (if needed for the skeleton).\n"
351+
. join("\n", $errors)
352+
);
353+
}
310354
}
311355

312356
/**
@@ -401,7 +445,11 @@ private function checkProject()
401445
}
402446
}
403447
sort($dependenciesListed);
404-
$nonDeclaredDependencies = array_diff(self::$dependencies, $dependenciesListed);
448+
$nonDeclaredDependencies = array_diff(
449+
self::$dependencies,
450+
$dependenciesListed,
451+
self::$rootComposerModuleBlacklist
452+
);
405453
$nonexistentDependencies = array_diff($dependenciesListed, self::$dependencies);
406454
$this->assertEmpty(
407455
$nonDeclaredDependencies,

dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ class CompilerTest extends \PHPUnit\Framework\TestCase
6262
*/
6363
protected $pluginValidator;
6464

65+
/**
66+
* @var string[]|null
67+
*/
68+
private $pluginBlacklist;
69+
6570
protected function setUp()
6671
{
6772
$this->_shell = new \Magento\Framework\Shell(new \Magento\Framework\Shell\CommandRenderer());
@@ -107,6 +112,31 @@ protected function setUp()
107112
$this->pluginValidator = new PluginValidator(new InterfaceValidator());
108113
}
109114

115+
/**
116+
* Return plugin blacklist class names
117+
*
118+
* @return string[]
119+
*/
120+
private function getPluginBlacklist(): array
121+
{
122+
if ($this->pluginBlacklist === null) {
123+
$blacklistFiles = str_replace(
124+
'\\',
125+
'/',
126+
realpath(__DIR__) . '/../_files/blacklist/compiler_plugins*.txt'
127+
);
128+
$blacklistItems = [];
129+
foreach (glob($blacklistFiles) as $fileName) {
130+
$blacklistItems = array_merge(
131+
$blacklistItems,
132+
file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
133+
);
134+
}
135+
$this->pluginBlacklist = $blacklistItems;
136+
}
137+
return $this->pluginBlacklist;
138+
}
139+
110140
/**
111141
* Validate DI config file
112142
*
@@ -360,6 +390,7 @@ protected function validatePlugins($plugin, $type)
360390
* Get application plugins
361391
*
362392
* @return array
393+
* @throws \Exception
363394
*/
364395
protected function pluginDataProvider()
365396
{
@@ -376,8 +407,10 @@ protected function pluginDataProvider()
376407
$type = \Magento\Framework\App\Utility\Classes::resolveVirtualType($type);
377408
if ($node->attributes->getNamedItem('type')) {
378409
$plugin = $node->attributes->getNamedItem('type')->nodeValue;
379-
$plugin = \Magento\Framework\App\Utility\Classes::resolveVirtualType($plugin);
380-
$plugins[] = ['plugin' => $plugin, 'intercepted type' => $type];
410+
if (!in_array($plugin, $this->getPluginBlacklist())) {
411+
$plugin = \Magento\Framework\App\Utility\Classes::resolveVirtualType($plugin);
412+
$plugins[] = ['plugin' => $plugin, 'intercepted type' => $type];
413+
}
381414
}
382415
}
383416
}

dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ private function getAclResources()
148148
if ($this->aclResources !== null) {
149149
return $this->aclResources;
150150
}
151-
$aclFiles = array_keys(Files::init()->getConfigFiles('acl.xml', []));
151+
$aclFiles = Files::init()->getConfigFiles('acl.xml', []);
152152
$xmlResources = [];
153153
array_map(function ($file) use (&$xmlResources) {
154-
$config = simplexml_load_file($file);
154+
$config = simplexml_load_file($file[0]);
155155
$nodes = $config->xpath('.//resource/@id') ?: [];
156156
foreach ($nodes as $node) {
157157
$xmlResources[(string)$node] = $node;

dev/tests/static/testsuite/Magento/Test/Integrity/PublicCodeTest.php

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,53 @@ class PublicCodeTest extends \PHPUnit\Framework\TestCase
2222
'$this', 'void', 'string', 'int', 'bool', 'boolean', 'integer', 'null'
2323
];
2424

25+
/**
26+
* @var string[]|null
27+
*/
28+
private $blockWhitelist;
29+
30+
/**
31+
* Return whitelist class names
32+
*
33+
* @return string[]
34+
*/
35+
private function getWhitelist(): array
36+
{
37+
if ($this->blockWhitelist === null) {
38+
$whiteListFiles = str_replace(
39+
'\\',
40+
'/',
41+
realpath(__DIR__) . '/_files/whitelist/public_code*.txt'
42+
);
43+
$whiteListItems = [];
44+
foreach (glob($whiteListFiles) as $fileName) {
45+
$whiteListItems = array_merge(
46+
$whiteListItems,
47+
file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
48+
);
49+
}
50+
$this->blockWhitelist = $whiteListItems;
51+
}
52+
return $this->blockWhitelist;
53+
}
54+
2555
/**
2656
* Since blocks can be referenced from templates, they should be stable not to break theme customizations.
2757
* So all blocks should be @api annotated. This test checks that all blocks declared in layout files are public
2858
*
2959
* @param $layoutFile
60+
* @throws \ReflectionException
3061
* @dataProvider layoutFilesDataProvider
3162
*/
3263
public function testAllBlocksReferencedInLayoutArePublic($layoutFile)
3364
{
34-
// A block can be whitelisted and thus not be required to be public
35-
$whiteListFiles = str_replace('\\', '/', realpath(__DIR__))
36-
. '/_files/whitelist/public_code*.txt';
37-
$whiteListBlocks = [];
38-
foreach (glob($whiteListFiles) as $fileName) {
39-
$whiteListBlocks = array_merge(
40-
$whiteListBlocks,
41-
file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
42-
);
43-
}
44-
4565
$nonPublishedBlocks = [];
4666
$xml = simplexml_load_file($layoutFile);
4767
$elements = $xml->xpath('//block | //referenceBlock') ?: [];
4868
/** @var $node \SimpleXMLElement */
4969
foreach ($elements as $node) {
5070
$class = (string) $node['class'];
51-
if ($class && \class_exists($class) && !in_array($class, $whiteListBlocks)) {
71+
if ($class && \class_exists($class) && !in_array($class, $this->getWhitelist())) {
5272
$reflection = (new \ReflectionClass($class));
5373
if (strpos($reflection->getDocComment(), '@api') === false) {
5474
$nonPublishedBlocks[] = $class;
@@ -58,7 +78,7 @@ public function testAllBlocksReferencedInLayoutArePublic($layoutFile)
5878
if (count($nonPublishedBlocks)) {
5979
$this->fail(
6080
"Layout file '$layoutFile' uses following blocks that are not marked with @api annotation:\n"
61-
. implode(",\n", $nonPublishedBlocks)
81+
. implode(",\n", array_unique($nonPublishedBlocks))
6282
);
6383
}
6484
}
@@ -67,6 +87,7 @@ public function testAllBlocksReferencedInLayoutArePublic($layoutFile)
6787
* Find all layout update files in magento modules and themes.
6888
*
6989
* @return array
90+
* @throws \Exception
7091
*/
7192
public function layoutFilesDataProvider()
7293
{
@@ -79,8 +100,8 @@ public function layoutFilesDataProvider()
79100
* This test walks through all public PHP types and makes sure that all their method arguments
80101
* and return values are public types.
81102
*
82-
*
83103
* @param string $class
104+
* @throws \ReflectionException
84105
* @dataProvider publicPHPTypesDataProvider
85106
*/
86107
public function testAllPHPClassesReferencedFromPublicClassesArePublic($class)
@@ -113,14 +134,15 @@ public function testAllPHPClassesReferencedFromPublicClassesArePublic($class)
113134
if (count($nonPublishedClasses)) {
114135
$this->fail(
115136
"Public type '" . $class . "' references following non-public types:\n"
116-
. implode("\n", $nonPublishedClasses)
137+
. implode("\n", array_unique($nonPublishedClasses))
117138
);
118139
}
119140
}
120141

121142
/**
122143
* Retrieve list of all interfaces and classes in Magento codebase that are marked with @api annotation.
123144
* @return array
145+
* @throws \Exception
124146
*/
125147
public function publicPHPTypesDataProvider()
126148
{
@@ -130,7 +152,9 @@ public function publicPHPTypesDataProvider()
130152
$fileContents = \file_get_contents($file);
131153
if (strpos($fileContents, '@api') !== false) {
132154
foreach ($this->getDeclaredClassesAndInterfaces($file) as $class) {
133-
if (class_exists($class->getName()) || interface_exists($class->getName())) {
155+
if (!in_array($class->getName(), $this->getWhitelist())
156+
&& (class_exists($class->getName()) || interface_exists($class->getName()))
157+
) {
134158
$result[$class->getName()] = [$class->getName()];
135159
}
136160
}

lib/internal/Magento/Framework/App/Utility/Files.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ public static function composeDataSets(array $files)
162162
{
163163
$result = [];
164164
foreach ($files as $file) {
165-
$result[$file] = [$file];
165+
$key = str_replace(BP . '/', '', $file);
166+
$result[$key] = [$file];
166167
}
167168
return $result;
168169
}

lib/internal/Magento/Framework/View/Element/Html/Link.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* @method string getLabel()
1212
* @method string getPath()
1313
* @method string getTitle()
14+
*
15+
* @api
1416
*/
1517
class Link extends \Magento\Framework\View\Element\Template
1618
{

0 commit comments

Comments
 (0)