Skip to content

Commit b5d6627

Browse files
author
oleksandrkravchuk
committed
Fix Magento Integrity Dependency test in case to be used not in scope of app/code isntallation.
1 parent b307274 commit b5d6627

File tree

4 files changed

+102
-14
lines changed

4 files changed

+102
-14
lines changed

dev/tests/static/framework/Magento/TestFramework/Dependency/PhpRule.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\App\Utility\Files;
1313
use Magento\Framework\Exception\LocalizedException;
1414
use Magento\Framework\UrlInterface;
15+
use Magento\TestFramework\Dependency\Reader\ClassScanner;
1516
use Magento\TestFramework\Dependency\Route\RouteMapper;
1617
use Magento\TestFramework\Exception\NoSuchActionException;
1718

@@ -78,26 +79,34 @@ class PhpRule implements RuleInterface
7879
* @var array
7980
*/
8081
private $whitelists;
82+
/**
83+
* @var ClassScanner
84+
*/
85+
private $classScanner;
8186

8287
/**
8388
* @param array $mapRouters
8489
* @param array $mapLayoutBlocks
8590
* @param array $pluginMap
8691
* @param array $whitelists
87-
* @throws \Exception
92+
* @param ClassScanner|null $classScanner
93+
*
94+
* @throws LocalizedException
8895
*/
8996
public function __construct(
9097
array $mapRouters,
9198
array $mapLayoutBlocks,
9299
array $pluginMap = [],
93-
array $whitelists = []
100+
array $whitelists = [],
101+
ClassScanner $classScanner = null
94102
) {
95103
$this->_mapRouters = $mapRouters;
96104
$this->_mapLayoutBlocks = $mapLayoutBlocks;
97105
$this->_namespaces = implode('|', \Magento\Framework\App\Utility\Files::init()->getNamespaces());
98106
$this->pluginMap = $pluginMap ?: null;
99107
$this->routeMapper = new RouteMapper();
100108
$this->whitelists = $whitelists;
109+
$this->classScanner = $classScanner ?? new ClassScanner();
101110
}
102111

103112
/**
@@ -177,7 +186,7 @@ private function caseClassesAndIdentifiers($currentModule, $file, &$contents)
177186
if (empty($matches['class_inside_module'][$i]) && !empty($matches['module_scoped_key'][$i])) {
178187
$dependencyType = RuleInterface::TYPE_SOFT;
179188
} else {
180-
$currentClass = $this->getClassFromFilepath($file, $currentModule);
189+
$currentClass = $this->getClassFromFilepath($file);
181190
$dependencyType = $this->isPluginDependency($currentClass, $dependencyClass)
182191
? RuleInterface::TYPE_SOFT
183192
: RuleInterface::TYPE_HARD;
@@ -197,14 +206,11 @@ private function caseClassesAndIdentifiers($currentModule, $file, &$contents)
197206
* Get class name from filename based on class/file naming conventions
198207
*
199208
* @param string $filepath
200-
* @param string $module
201209
* @return string
202210
*/
203-
private function getClassFromFilepath($filepath, $module)
211+
private function getClassFromFilepath(string $filepath): string
204212
{
205-
$class = strstr($filepath, str_replace(['_', '\\', '/'], DIRECTORY_SEPARATOR, $module));
206-
$class = str_replace(DIRECTORY_SEPARATOR, '\\', strstr($class, '.php', true));
207-
return $class;
213+
return $this->classScanner->getClassName($filepath);
208214
}
209215

210216
/**
@@ -268,7 +274,8 @@ private function isPluginDependency($dependent, $dependency)
268274
if ($subject === $dependency) {
269275
return true;
270276
} elseif ($subject) {
271-
$subjectModule = substr($subject, 0, strpos($subject, '\\', 9)); // (strlen('Magento\\') + 1) === 9
277+
$moduleNameLength = strpos($subject, '\\', strpos($subject, '\\') + 1);
278+
$subjectModule = substr($subject, 0, $moduleNameLength);
272279
return strpos($dependency, $subjectModule) === 0;
273280
} else {
274281
return false;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\TestFramework\Dependency\Reader;
9+
10+
/**
11+
* Search classes in file by path.
12+
*/
13+
class ClassScanner
14+
{
15+
/**
16+
* @var string[]
17+
*/
18+
private $classNames = [];
19+
20+
/**
21+
* Get class name by file name.
22+
*
23+
* @param string $filePath
24+
*
25+
* @return string
26+
*/
27+
public function getClassName(string $filePath): string
28+
{
29+
if (!isset($this->classNames[$filePath])) {
30+
$this->classNames[$filePath] = $this->loadClassName($filePath);
31+
}
32+
33+
return $this->classNames[$filePath];
34+
}
35+
36+
/**
37+
* Load class name from file.
38+
*
39+
* @param string $filePath
40+
*
41+
* @return string
42+
*/
43+
private function loadClassName(string $filePath): string
44+
{
45+
$scanner = new \Magento\Setup\Module\Di\Code\Reader\FileClassScanner($filePath);
46+
return $scanner->getClassName();
47+
}
48+
}

dev/tests/static/framework/autoload.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@
3434

3535
$generatedCode = DirectoryList::getDefaultConfig()[DirectoryList::GENERATED_CODE][DirectoryList::PATH];
3636
$autoloadWrapper->addPsr4('Magento\\', $baseDir . '/' . $generatedCode . '/Magento/');
37+
38+
$setup = DirectoryList::getDefaultConfig()[DirectoryList::SETUP][DirectoryList::PATH];
39+
$autoloadWrapper->addPsr4('Magento\\Setup\\', $baseDir . '/' . $setup . '/Magento/Setup/');

dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/PhpRuleTest.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Framework\Exception\LocalizedException;
99
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
10+
use Magento\TestFramework\Dependency\Reader\ClassScanner;
1011
use Magento\TestFramework\Exception\NoSuchActionException;
1112

1213
/**
@@ -24,6 +25,11 @@ class PhpRuleTest extends \PHPUnit\Framework\TestCase
2425
*/
2526
private $objectManagerHelper;
2627

28+
/**
29+
* @var ClassScanner
30+
*/
31+
private $classScanner;
32+
2733
/**
2834
* @inheritDoc
2935
* @throws \Exception
@@ -39,13 +45,16 @@ protected function setUp()
3945
$whitelist = [];
4046

4147
$this->objectManagerHelper = new ObjectManagerHelper($this);
48+
$this->classScanner = $this->createMock(ClassScanner::class);
49+
4250
$this->model = $this->objectManagerHelper->getObject(
4351
PhpRule::class,
4452
[
4553
'mapRouters' => $mapRoutes,
4654
'mapLayoutBlocks' => $mapLayoutBlocks,
4755
'pluginMap' => $pluginMap,
4856
'whitelists' => $whitelist,
57+
'classScanner' => $this->classScanner
4958
]
5059
);
5160
}
@@ -62,14 +71,20 @@ public function testNonPhpGetDependencyInfo()
6271
/**
6372
* @param string $class
6473
* @param string $content
74+
* @param int $expectedScans
6575
* @param array $expected
66-
* @dataProvider getDependencyInfoDataProvider
76+
*
6777
* @throws \Exception
78+
* @dataProvider getDependencyInfoDataProvider
6879
*/
69-
public function testGetDependencyInfo($class, $content, array $expected)
80+
public function testGetDependencyInfo(string $class, string $content, int $expectedScans, array $expected): void
7081
{
7182
$file = $this->makeMockFilepath($class);
7283
$module = $this->getModuleFromClass($class);
84+
$this->classScanner->expects($this->exactly($expectedScans))
85+
->method('getClassName')
86+
->with($file)
87+
->willReturn($class);
7388
$this->assertEquals($expected, $this->model->getDependencyInfo($module, 'php', $file, $content));
7489
}
7590

@@ -82,11 +97,13 @@ public function getDependencyInfoDataProvider()
8297
'Extend class in same module' => [
8398
'Magento\SomeModule\SomeClass',
8499
'something extends \Magento\SomeModule\Any\ClassName {',
100+
0,
85101
[]
86102
],
87103
'Extend class in different module' => [
88104
'Magento\AnotherModule\SomeClass',
89105
'something extends \Magento\SomeModule\Any\ClassName {',
106+
1,
90107
[
91108
[
92109
'module' => 'Magento\SomeModule',
@@ -98,11 +115,13 @@ public function getDependencyInfoDataProvider()
98115
'getViewFileUrl in same module' => [
99116
'Magento\SomeModule\SomeClass',
100117
'$this->getViewFileUrl("Magento_SomeModule::js/order-by-sku-failure.js")',
118+
0,
101119
[]
102120
],
103121
'getViewFileUrl in different module' => [
104122
'Magento\AnotherModule\SomeClass',
105123
'$this->getViewFileUrl("Magento_SomeModule::js/order-by-sku-failure.js")',
124+
1,
106125
[
107126
[
108127
'module' => 'Magento\SomeModule',
@@ -114,11 +133,13 @@ public function getDependencyInfoDataProvider()
114133
'Helper class from same module' => [
115134
'Magento\SomeModule\SomeClass',
116135
'$this->helper("Magento\SomeModule\Any\ClassName")',
136+
0,
117137
[]
118138
],
119139
'Helper class from another module' => [
120140
'Magento\AnotherModule\SomeClass',
121141
'$this->helper("Magento\SomeModule\Any\ClassName")',
142+
1,
122143
[
123144
[
124145
'module' => 'Magento\SomeModule',
@@ -129,11 +150,14 @@ public function getDependencyInfoDataProvider()
129150
],
130151
'getBlock from same module' => [
131152
'Magento\SomeModule\SomeClass',
132-
'$this->getLayout()->getBlock(\'block.name\');', []
153+
'$this->getLayout()->getBlock(\'block.name\');',
154+
0,
155+
[]
133156
],
134157
'getBlock from another module' => [
135158
'Magento\AnotherModule\SomeClass',
136159
'$this->getLayout()->getBlock(\'block.name\');',
160+
0,
137161
[
138162
[
139163
'module' => 'Magento\SomeModule',
@@ -145,16 +169,19 @@ public function getDependencyInfoDataProvider()
145169
'Plugin on class in same module' => [
146170
'Magento\Module1\Plugin1',
147171
', \Magento\Module1\Subject $variable',
172+
0,
148173
[]
149174
],
150175
'Plugin depends on arbitrary class in same module' => [
151176
'Magento\Module1\Plugin1',
152177
', \Magento\Module1\NotSubject $variable',
178+
0,
153179
[]
154180
],
155181
'Plugin on class in different module' => [
156182
'Magento\Module1\Plugin2',
157183
'Magento\Module2\Subject',
184+
1,
158185
[
159186
[
160187
'module' => 'Magento\Module2',
@@ -166,6 +193,7 @@ public function getDependencyInfoDataProvider()
166193
'Plugin depends on arbitrary class in same module as subject' => [
167194
'Magento\Module1\Plugin2',
168195
'Magento\Module2\NotSubject',
196+
1,
169197
[
170198
[
171199
'module' => 'Magento\Module2',
@@ -177,6 +205,7 @@ public function getDependencyInfoDataProvider()
177205
'Plugin depends on arbitrary class in arbitrary module' => [
178206
'Magento\Module1\Plugin2',
179207
'Magento\OtherModule\NotSubject',
208+
1,
180209
[
181210
[
182211
'module' => 'Magento\OtherModule',
@@ -322,8 +351,9 @@ private function makeMockFilepath($class)
322351
* @param string $class
323352
* @return string
324353
*/
325-
private function getModuleFromClass($class)
354+
private function getModuleFromClass(string $class): string
326355
{
327-
return substr($class, 0, strpos($class, '\\', 9)); // (strlen('Magento\\') + 1) === 9
356+
$moduleNameLength = strpos($class, '\\', strpos($class, '\\') + 1);
357+
return substr($class, 0, $moduleNameLength);
328358
}
329359
}

0 commit comments

Comments
 (0)