Skip to content

Commit 1de7456

Browse files
authored
MQE-2045: Upgrade script to remove unused arguments (#696)
* MQE-2045: Upgrade script to remove unused arguments * MQE-2045: Upgrade script to remove unused arguments Fixed static checks, extracted some code into methods * MQE-2045: Upgrade script to remove unused arguments Fixed static checks * MQE-2045: Upgrade script to remove unused arguments Fixed static checks * MQE-2045: Upgrade script to remove unused arguments
1 parent df94717 commit 1de7456

File tree

3 files changed

+110
-28
lines changed

3 files changed

+110
-28
lines changed

src/Magento/FunctionalTestingFramework/StaticCheck/ActionGroupArgumentsCheck.php

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,16 @@
1212
use Symfony\Component\Finder\Finder;
1313
use Exception;
1414
use Magento\FunctionalTestingFramework\Util\Script\ScriptUtil;
15+
use Symfony\Component\Finder\SplFileInfo;
16+
use DOMElement;
1517

1618
/**
1719
* Class ActionGroupArgumentsCheck
1820
* @package Magento\FunctionalTestingFramework\StaticCheck
1921
*/
2022
class ActionGroupArgumentsCheck implements StaticCheckInterface
2123
{
22-
const ACTIONGROUP_XML_REGEX_PATTERN = '/<actionGroup\sname=(?: (?!<\/actionGroup>).)*/mxs';
23-
const ACTIONGROUP_ARGUMENT_REGEX_PATTERN = '/<argument[^\/>]*name="([^"\']*)/mxs';
2424
const ACTIONGROUP_NAME_REGEX_PATTERN = '/<actionGroup name=["\']([^\'"]*)/';
25-
2625
const ERROR_LOG_FILENAME = 'mftf-arguments-checks';
2726
const ERROR_LOG_MESSAGE = 'MFTF Action Group Unused Arguments Check';
2827

@@ -97,45 +96,62 @@ public function getOutput()
9796
private function findErrorsInFileSet($files)
9897
{
9998
$actionGroupErrors = [];
99+
/** @var SplFileInfo $filePath */
100100
foreach ($files as $filePath) {
101-
$contents = file_get_contents($filePath);
102-
preg_match_all(self::ACTIONGROUP_XML_REGEX_PATTERN, $contents, $actionGroups);
103-
$actionGroupToArguments = $this->buildUnusedArgumentList($actionGroups[0]);
104-
$actionGroupErrors += $this->setErrorOutput($actionGroupToArguments, $filePath);
101+
$actionGroupToArguments = [];
102+
$contents = $filePath->getContents();
103+
/** @var DOMElement $actionGroup */
104+
$actionGroup = $this->getActionGroupDomElement($contents);
105+
$arguments = $this->extractActionGroupArguments($actionGroup);
106+
$unusedArguments = $this->findUnusedArguments($arguments, $contents);
107+
if (!empty($unusedArguments)) {
108+
$actionGroupToArguments[$actionGroup->getAttribute('name')] = $unusedArguments;
109+
$actionGroupErrors += $this->setErrorOutput($actionGroupToArguments, $filePath);
110+
}
105111
}
106112
return $actionGroupErrors;
107113
}
108114

109115
/**
110-
* Builds array of action group => unused arguments
111-
* @param array $actionGroups
112-
* @return array $actionGroupToArguments
116+
* Extract actionGroup DomElement from xml file
117+
* @param string $contents
118+
* @return \DOMElement
113119
*/
114-
private function buildUnusedArgumentList($actionGroups)
120+
public function getActionGroupDomElement($contents)
115121
{
116-
$actionGroupToArguments = [];
122+
$domDocument = new \DOMDocument();
123+
$domDocument->loadXML($contents);
124+
return $domDocument->getElementsByTagName('actionGroup')[0];
125+
}
117126

118-
foreach ($actionGroups as $actionGroupXml) {
119-
preg_match(self::ACTIONGROUP_NAME_REGEX_PATTERN, $actionGroupXml, $actionGroupName);
120-
$unusedArguments = $this->findUnusedArguments($actionGroupXml);
121-
if (!empty($unusedArguments)) {
122-
$actionGroupToArguments[$actionGroupName[1]] = $unusedArguments;
127+
/**
128+
* Get list of action group arguments declared in an action group
129+
* @param \DOMElement $actionGroup
130+
* @return array $arguments
131+
*/
132+
public function extractActionGroupArguments($actionGroup)
133+
{
134+
$arguments = [];
135+
$argumentsNodes = $actionGroup->getElementsByTagName('arguments');
136+
if ($argumentsNodes->length > 0) {
137+
$argumentNodes = $argumentsNodes[0]->getElementsByTagName('argument');
138+
foreach ($argumentNodes as $argumentNode) {
139+
$arguments[] = $argumentNode->getAttribute('name');
123140
}
124141
}
125-
return $actionGroupToArguments;
142+
return $arguments;
126143
}
127144

128145
/**
129146
* Returns unused arguments in an action group
130-
* @param string $actionGroupXml
147+
* @param array $arguments
148+
* @param string $contents
131149
* @return array
132150
*/
133-
private function findUnusedArguments($actionGroupXml)
151+
public function findUnusedArguments($arguments, $contents)
134152
{
135153
$unusedArguments = [];
136-
137-
preg_match_all(self::ACTIONGROUP_ARGUMENT_REGEX_PATTERN, $actionGroupXml, $arguments);
138-
preg_match(self::ACTIONGROUP_NAME_REGEX_PATTERN, $actionGroupXml, $actionGroupName);
154+
preg_match(self::ACTIONGROUP_NAME_REGEX_PATTERN, $contents, $actionGroupName);
139155
$validActionGroup = false;
140156
try {
141157
$actionGroup = ActionGroupObjectHandler::getInstance()->getObject($actionGroupName[1]);
@@ -149,18 +165,18 @@ private function findUnusedArguments($actionGroupXml)
149165
return $unusedArguments;
150166
}
151167

152-
foreach ($arguments[1] as $argument) {
168+
foreach ($arguments as $argument) {
153169
//pattern to match all argument references
154170
$patterns = [
155171
'(\{{2}' . $argument . '(\.[a-zA-Z0-9_\[\]\(\).,\'\/ ]+)?}{2})',
156172
'([(,\s\'$$]' . $argument . '(\.[a-zA-Z0-9_$\[\]]+)?[),\s\'])'
157173
];
158174
// matches entity references
159-
if (preg_match($patterns[0], $actionGroupXml)) {
175+
if (preg_match($patterns[0], $contents)) {
160176
continue;
161177
}
162178
//matches parametrized references
163-
if (preg_match($patterns[1], $actionGroupXml)) {
179+
if (preg_match($patterns[1], $contents)) {
164180
continue;
165181
}
166182
//for extending action groups, exclude arguments that are also defined in parent action group
@@ -196,8 +212,8 @@ private function isParentActionGroupArgument($argument, $actionGroup)
196212
/**
197213
* Builds and returns error output for violating references
198214
*
199-
* @param array $actionGroupToArguments
200-
* @param string $path
215+
* @param array $actionGroupToArguments
216+
* @param SplFileInfo $path
201217
* @return mixed
202218
*/
203219
private function setErrorOutput($actionGroupToArguments, $path)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\Upgrade;
8+
9+
use Magento\FunctionalTestingFramework\StaticCheck\ActionGroupArgumentsCheck;
10+
use Magento\FunctionalTestingFramework\Util\Script\ScriptUtil;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
use Symfony\Component\Filesystem\Filesystem;
14+
use DOMElement;
15+
16+
/**
17+
* Class RenameMetadataFiles
18+
* @package Magento\FunctionalTestingFramework\Upgrade
19+
*/
20+
class RemoveUnusedArguments implements UpgradeInterface
21+
{
22+
const ARGUMENTS_BLOCK_REGEX_PATTERN = "/\s*<arguments.*\/arguments>/s";
23+
24+
/**
25+
* Updates all actionGroup xml files
26+
*
27+
* @param InputInterface $input
28+
* @param OutputInterface $output
29+
* @return string
30+
*/
31+
public function execute(InputInterface $input, OutputInterface $output)
32+
{
33+
$scriptUtil = new ScriptUtil();
34+
$testPaths[] = $input->getArgument('path');
35+
if (empty($testPaths[0])) {
36+
$testPaths = $scriptUtil->getAllModulePaths();
37+
}
38+
$xmlFiles = $scriptUtil->getModuleXmlFilesByScope($testPaths, 'ActionGroup');
39+
$actionGroupsUpdated = 0;
40+
$fileSystem = new Filesystem();
41+
foreach ($xmlFiles as $file) {
42+
$contents = $file->getContents();
43+
$argumentsCheck = new ActionGroupArgumentsCheck();
44+
/** @var DOMElement $actionGroup */
45+
$actionGroup = $argumentsCheck->getActionGroupDomElement($contents);
46+
$allArguments = $argumentsCheck->extractActionGroupArguments($actionGroup);
47+
$unusedArguments = $argumentsCheck->findUnusedArguments($allArguments, $contents);
48+
if (empty($unusedArguments)) {
49+
continue;
50+
}
51+
//Remove <arguments> block if all arguments are unused
52+
if (empty(array_diff($allArguments, $unusedArguments))) {
53+
$contents = preg_replace(self::ARGUMENTS_BLOCK_REGEX_PATTERN, '', $contents);
54+
} else {
55+
foreach ($unusedArguments as $argument) {
56+
$argumentRegexPattern = "/\s*<argument.*name\s*=\s*\"".$argument."\".*\/>/";
57+
$contents = preg_replace($argumentRegexPattern, '', $contents);
58+
}
59+
}
60+
$fileSystem->dumpFile($file->getRealPath(), $contents);
61+
$actionGroupsUpdated++;
62+
}
63+
return "Removed unused action group arguments from {$actionGroupsUpdated} file(s).";
64+
}
65+
}

src/Magento/FunctionalTestingFramework/Upgrade/UpgradeScriptList.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class UpgradeScriptList implements UpgradeScriptListInterface
2828
public function __construct(array $scripts = [])
2929
{
3030
$this->scripts = [
31+
'removeUnusedArguments' => new RemoveUnusedArguments(),
3132
'upgradeTestSchema' => new UpdateTestSchemaPaths(),
3233
'upgradeAssertionSchema' => new UpdateAssertionSchema(),
3334
'renameMetadataFiles' => new RenameMetadataFiles(),

0 commit comments

Comments
 (0)