From 1efdb2295334f782481d04c861020c0103e698b5 Mon Sep 17 00:00:00 2001 From: Tom Reece Date: Tue, 10 Mar 2020 15:10:21 -0500 Subject: [PATCH 1/2] MQE-2016: Add warning for test materials that violate naming convention --- .../Handlers/DataObjectHandler.php | 28 +- .../OperationDefinitionObjectHandler.php | 6 + .../Page/Handlers/PageObjectHandler.php | 7 +- .../Page/Handlers/SectionObjectHandler.php | 12 +- .../Handlers/ActionGroupObjectHandler.php | 10 +- .../Test/Handlers/TestObjectHandler.php | 9 +- .../Util/Validation/NameValidationUtil.php | 260 ++++++++++++++++++ 7 files changed, 322 insertions(+), 10 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php index a210710db..7f59f5234 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php @@ -14,6 +14,7 @@ use Magento\FunctionalTestingFramework\ObjectManagerFactory; use Magento\FunctionalTestingFramework\DataGenerator\Util\DataExtensionUtil; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; class DataObjectHandler implements ObjectHandlerInterface { @@ -58,6 +59,20 @@ class DataObjectHandler implements ObjectHandlerInterface */ private $extendUtil; + /** + * Validates and keeps track of entity name violations. + * + * @var NameValidationUtil + */ + private $entityNameValidator; + + /** + * Validates and keeps track of entity key violations. + * + * @var NameValidationUtil + */ + private $entityKeyValidator; + /** * Constructor */ @@ -68,6 +83,8 @@ private function __construct() if (!$parserOutput) { return; } + $this->entityNameValidator = new NameValidationUtil(); + $this->entityKeyValidator = new NameValidationUtil(); $this->entityDataObjects = $this->processParserOutput($parserOutput); $this->extendUtil = new DataExtensionUtil(); } @@ -132,6 +149,8 @@ private function processParserOutput($parserOutput) throw new XmlException(sprintf(self::DATA_NAME_ERROR_MSG, $name)); } + $filename = $rawEntity[self::_FILENAME] ?? null; + $this->entityNameValidator->validateDataEntityName($name, $filename); $type = $rawEntity[self::_TYPE] ?? null; $data = []; $deprecated = null; @@ -139,7 +158,6 @@ private function processParserOutput($parserOutput) $uniquenessData = []; $vars = []; $parentEntity = null; - $filename = $rawEntity[self::_FILENAME] ?? null; if (array_key_exists(self::_DATA, $rawEntity)) { $data = $this->processDataElements($rawEntity); @@ -188,7 +206,8 @@ private function processParserOutput($parserOutput) $entityDataObjects[$entityDataObject->getName()] = $entityDataObject; } - + $this->entityNameValidator->summarize("data entity name"); + $this->entityKeyValidator->summarize("data entity key"); return $entityDataObjects; } @@ -220,7 +239,10 @@ private function processDataElements($entityData) { $dataValues = []; foreach ($entityData[self::_DATA] as $dataElement) { - $dataElementKey = strtolower($dataElement[self::_KEY]); + $originalDataElementKey = $dataElement[self::_KEY]; + $filename = $entityData[self::_FILENAME] ?? null; + $this->entityKeyValidator->validateDataEntityKey($originalDataElementKey, $filename); + $dataElementKey = strtolower($originalDataElementKey); $dataElementValue = $dataElement[self::_VALUE] ?? ""; $dataValues[$dataElementKey] = $dataElementValue; } diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php index 8c2ec7b0a..d01b36528 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php @@ -12,6 +12,7 @@ use Magento\FunctionalTestingFramework\ObjectManager\ObjectHandlerInterface; use Magento\FunctionalTestingFramework\ObjectManagerFactory; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; class OperationDefinitionObjectHandler implements ObjectHandlerInterface { @@ -136,7 +137,11 @@ private function initialize() $objectManager = ObjectManagerFactory::getObjectManager(); $parser = $objectManager->create(OperationDefinitionParser::class); $parserOutput = $parser->readOperationMetadata()[OperationDefinitionObjectHandler::ENTITY_OPERATION_ROOT_TAG]; + + $operationNameValidator = new NameValidationUtil(); foreach ($parserOutput as $dataDefName => $opDefArray) { + $operationNameValidator->validateMetadataOperationName($dataDefName); + $operation = $opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_TYPE]; $dataType = $opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_DATA_TYPE]; $url = $opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL] ?? null; @@ -230,6 +235,7 @@ private function initialize() $deprecated ); } + $operationNameValidator->summarize("metadata operation name"); } /** diff --git a/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php b/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php index c310b9bef..1fc8dfd34 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php @@ -10,6 +10,7 @@ use Magento\FunctionalTestingFramework\ObjectManagerFactory; use Magento\FunctionalTestingFramework\Page\Objects\PageObject; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; use Magento\FunctionalTestingFramework\XmlParser\PageParser; use Magento\FunctionalTestingFramework\Exceptions\XmlException; @@ -54,10 +55,14 @@ private function __construct() return; } + $pageNameValidator = new NameValidationUtil(); foreach ($parserOutput as $pageName => $pageData) { if (preg_match('/[^a-zA-Z0-9_]/', $pageName)) { throw new XmlException(sprintf(self::NAME_BLACKLIST_ERROR_MSG, $pageName)); } + + $filename = $pageData[self::FILENAME] ?? null; + $pageNameValidator->validatePageName($pageName, $filename); $area = $pageData[self::AREA] ?? null; $url = $pageData[self::URL] ?? null; @@ -68,7 +73,6 @@ private function __construct() $module = $pageData[self::MODULE] ?? null; $sectionNames = array_keys($pageData[self::SECTION] ?? []); $parameterized = $pageData[self::PARAMETERIZED] ?? false; - $filename = $pageData[self::FILENAME] ?? null; $deprecated = $pageData[self::OBJ_DEPRECATED] ?? null; if ($deprecated !== null) { @@ -81,6 +85,7 @@ private function __construct() $this->pageObjects[$pageName] = new PageObject($pageName, $url, $module, $sectionNames, $parameterized, $area, $filename, $deprecated); } + $pageNameValidator->summarize("page name"); } /** diff --git a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php index 2736100fd..09d073d33 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php @@ -10,8 +10,8 @@ use Magento\FunctionalTestingFramework\ObjectManagerFactory; use Magento\FunctionalTestingFramework\Page\Objects\ElementObject; use Magento\FunctionalTestingFramework\Page\Objects\SectionObject; -use Magento\FunctionalTestingFramework\Test\Util\TestObjectExtractor; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; use Magento\FunctionalTestingFramework\XmlParser\SectionParser; use Magento\FunctionalTestingFramework\Exceptions\XmlException; @@ -58,6 +58,8 @@ private function __construct() return; } + $sectionNameValidator = new NameValidationUtil(); + $elementNameValidator = new NameValidationUtil(); foreach ($parserOutput as $sectionName => $sectionData) { $elements = []; @@ -65,11 +67,16 @@ private function __construct() throw new XmlException(sprintf(self::SECTION_NAME_ERROR_MSG, $sectionName)); } + $filename = $sectionData[self::FILENAME] ?? null; + $sectionNameValidator->validateSectionName($sectionName, $filename); + try { foreach ($sectionData[SectionObjectHandler::ELEMENT] as $elementName => $elementData) { if (preg_match('/[^a-zA-Z0-9_]/', $elementName)) { throw new XmlException(sprintf(self::ELEMENT_NAME_ERROR_MSG, $elementName, $sectionName)); } + + $elementNameValidator->validateElementName($elementName, $filename); $elementType = $elementData[SectionObjectHandler::TYPE] ?? null; $elementSelector = $elementData[SectionObjectHandler::SELECTOR] ?? null; $elementLocatorFunc = $elementData[SectionObjectHandler::LOCATOR_FUNCTION] ?? null; @@ -96,7 +103,6 @@ private function __construct() throw new XmlException($exception->getMessage() . " in Section '{$sectionName}'"); } - $filename = $sectionData[self::FILENAME] ?? null; $sectionDeprecated = $sectionData[self::OBJ_DEPRECATED] ?? null; if ($sectionDeprecated !== null) { @@ -113,6 +119,8 @@ private function __construct() $sectionDeprecated ); } + $sectionNameValidator->summarize("section name"); + $elementNameValidator->summarize("element name"); } /** diff --git a/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php b/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php index 131ae0a26..47dacf200 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php @@ -9,10 +9,10 @@ use Magento\FunctionalTestingFramework\ObjectManager\ObjectHandlerInterface; use Magento\FunctionalTestingFramework\ObjectManagerFactory; use Magento\FunctionalTestingFramework\Test\Objects\ActionGroupObject; -use Magento\FunctionalTestingFramework\Test\Objects\TestObject; use Magento\FunctionalTestingFramework\Test\Parsers\ActionGroupDataParser; use Magento\FunctionalTestingFramework\Test\Util\ActionGroupObjectExtractor; use Magento\FunctionalTestingFramework\Test\Util\ObjectExtensionUtil; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; /** * Class ActionGroupObjectHandler @@ -22,6 +22,7 @@ class ActionGroupObjectHandler implements ObjectHandlerInterface const BEFORE_AFTER_ERROR_MSG = "Merge Error - Steps cannot have both before and after attributes.\tTestStep='%s'"; const ACTION_GROUP_ROOT = 'actionGroups'; const ACTION_GROUP = 'actionGroup'; + const ACTION_GROUP_FILENAME_ATTRIBUTE = 'filename'; /** * Single instance of class var @@ -110,7 +111,13 @@ private function initActionGroups() $actionGroupObjectExtractor = new ActionGroupObjectExtractor(); $neededActionGroup = $parsedActionGroups[ActionGroupObjectHandler::ACTION_GROUP_ROOT]; + $actionGroupNameValidator = new NameValidationUtil(); foreach ($neededActionGroup as $actionGroupName => $actionGroupData) { + if (!in_array($actionGroupName, ["nodeName", "xsi:noNamespaceSchemaLocation"])) { + $filename = $actionGroupData[ActionGroupObjectHandler::ACTION_GROUP_FILENAME_ATTRIBUTE]; + $actionGroupNameValidator->validateActionGroupName($actionGroupName, $filename); + } + if (!is_array($actionGroupData)) { continue; } @@ -118,6 +125,7 @@ private function initActionGroups() $this->actionGroups[$actionGroupName] = $actionGroupObjectExtractor->extractActionGroup($actionGroupData); } + $actionGroupNameValidator->summarize("action group name"); } /** diff --git a/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php b/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php index d5ed43806..8a72415f8 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php @@ -15,9 +15,8 @@ use Magento\FunctionalTestingFramework\Test\Parsers\TestDataParser; use Magento\FunctionalTestingFramework\Test\Util\ObjectExtensionUtil; use Magento\FunctionalTestingFramework\Test\Util\TestObjectExtractor; -use Magento\FunctionalTestingFramework\Test\Util\AnnotationExtractor; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; -use PHP_CodeSniffer\Tokenizers\PHP; +use Magento\FunctionalTestingFramework\Util\Validation\NameValidationUtil; /** * Class TestObjectHandler @@ -25,6 +24,7 @@ class TestObjectHandler implements ObjectHandlerInterface { const XML_ROOT = 'tests'; + const TEST_FILENAME_ATTRIBUTE = 'filename'; /** * Test Object Handler @@ -142,7 +142,10 @@ private function initTestData() } $exceptionCollector = new ExceptionCollector(); + $testNameValidator = new NameValidationUtil(); foreach ($parsedTestArray as $testName => $testData) { + $filename = $testData[TestObjectHandler::TEST_FILENAME_ATTRIBUTE]; + $testNameValidator->validateTestName($testName, $filename); if (!is_array($testData)) { continue; } @@ -153,7 +156,7 @@ private function initTestData() } } $exceptionCollector->throwException(); - + $testNameValidator->summarize("test name"); $testObjectExtractor->getAnnotationExtractor()->validateStoryTitleUniqueness(); $testObjectExtractor->getAnnotationExtractor()->validateTestCaseIdTitleUniqueness(); } diff --git a/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php b/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php index 60b4660fb..50918c146 100644 --- a/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php +++ b/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php @@ -6,12 +6,30 @@ namespace Magento\FunctionalTestingFramework\Util\Validation; +use Exception; use Magento\FunctionalTestingFramework\Exceptions\XmlException; +use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; class NameValidationUtil { const PHP_CLASS_REGEX_PATTERN = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/'; + /** + * The number of violations this instance has detected. + * + * @var integer + */ + private $count; + + /** + * NameValidationUtil constructor. + * + */ + public function __construct() + { + $this->count = 0; + } + /** * Function which runs a validation against the blacklisted char defined in this class. Validation occurs to insure * allure report does not error/future devOps builds do not error against illegal char. @@ -50,4 +68,246 @@ public static function validateName($name, $type) throw new XmlException($errorMessage); } } + + /** + * Validates data entity names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateDataEntityName($str, $filename = null) + { + if (!ctype_upper($str[0])) { + $message = "The data entity name {$str} should be PascalCase with an uppercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates data entity key names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateDataEntityKey($str, $filename = null) + { + if (!ctype_lower($str[0])) { + $message = "The data entity key {$str} should be camelCase with a lowercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates metadata operation names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateMetadataOperationName($str, $filename = null) + { + if (!ctype_upper($str[0])) { + $message = "The metadata operation name {$str} should be PascalCase with an uppercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates page names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validatePageName($str, $filename = null) + { + $isPrefixAdmin = substr($str, 0, 5) === "Admin"; + $isPrefixStorefront = substr($str, 0, 10) === "Storefront"; + $isSuffixPage = substr($str, -4) === "Page"; + + if ((!$isPrefixAdmin && !$isPrefixStorefront) || !$isSuffixPage) { + $message = "The page name {$str} should follow the pattern {Admin or Storefront}{Description}Page."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates section names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateSectionName($str, $filename = null) + { + $isPrefixAdmin = substr($str, 0, 5) === "Admin"; + $isPrefixStorefront = substr($str, 0, 10) === "Storefront"; + $isSuffixSection = substr($str, -7) === "Section"; + + if ((!$isPrefixAdmin && !$isPrefixStorefront) || !$isSuffixSection) { + $message = "The section name {$str} should follow the pattern {Admin or Storefront}{Description}Section."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates section element names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateElementName($str, $filename = null) + { + if (!ctype_lower($str[0])) { + $message = "The element name {$str} should be camelCase with a lowercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates action group names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateActionGroupName($str, $filename = null) + { + if (!ctype_upper($str[0])) { + $message = "The action group name {$str} should be PascalCase with an uppercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Validates test names. + * + * @param string $str + * @param string $filename + * @throws Exception + * @return void + */ + public function validateTestName($str, $filename = null) + { + if (!ctype_upper($str[0])) { + $message = "The test name {$str} should be PascalCase with an uppercase first letter."; + + if ($filename !== null) { + $message .= " See file {$filename}."; + } + + LoggingUtil::getInstance()->getLogger(self::class)->notification( + $message, + [], + false + ); + + $this->count++; + } + } + + /** + * Outputs the number of validations detected by this instance. + * + * @param string $type + * @throws Exception + * @return void + */ + public function summarize($type) + { + if ($this->count > 0) { + LoggingUtil::getInstance()->getLogger(self::class)->notification( + "{$this->count} {$type} violations detected. See mftf.log for details.", + [], + true + ); + } + } } From b3db4a209afca989283ac8edeb34a04352747108 Mon Sep 17 00:00:00 2001 From: Tom Reece Date: Wed, 11 Mar 2020 10:25:57 -0500 Subject: [PATCH 2/2] MQE-2016: Add warning for test materials that violate naming convention --- .../Handlers/DataObjectHandler.php | 16 +- .../OperationDefinitionObjectHandler.php | 7 +- .../Page/Handlers/PageObjectHandler.php | 4 +- .../Page/Handlers/SectionObjectHandler.php | 12 +- .../Handlers/ActionGroupObjectHandler.php | 8 +- .../Test/Handlers/TestObjectHandler.php | 4 +- .../Util/Validation/NameValidationUtil.php | 173 +++--------------- 7 files changed, 58 insertions(+), 166 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php index 7f59f5234..26b603915 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php @@ -150,7 +150,11 @@ private function processParserOutput($parserOutput) } $filename = $rawEntity[self::_FILENAME] ?? null; - $this->entityNameValidator->validateDataEntityName($name, $filename); + $this->entityNameValidator->validatePascalCase( + $name, + NameValidationUtil::DATA_ENTITY_NAME, + $filename + ); $type = $rawEntity[self::_TYPE] ?? null; $data = []; $deprecated = null; @@ -206,8 +210,8 @@ private function processParserOutput($parserOutput) $entityDataObjects[$entityDataObject->getName()] = $entityDataObject; } - $this->entityNameValidator->summarize("data entity name"); - $this->entityKeyValidator->summarize("data entity key"); + $this->entityNameValidator->summarize(NameValidationUtil::DATA_ENTITY_NAME); + $this->entityKeyValidator->summarize(NameValidationUtil::DATA_ENTITY_KEY); return $entityDataObjects; } @@ -241,7 +245,11 @@ private function processDataElements($entityData) foreach ($entityData[self::_DATA] as $dataElement) { $originalDataElementKey = $dataElement[self::_KEY]; $filename = $entityData[self::_FILENAME] ?? null; - $this->entityKeyValidator->validateDataEntityKey($originalDataElementKey, $filename); + $this->entityKeyValidator->validateCamelCase( + $originalDataElementKey, + NameValidationUtil::DATA_ENTITY_KEY, + $filename + ); $dataElementKey = strtolower($originalDataElementKey); $dataElementValue = $dataElement[self::_VALUE] ?? ""; $dataValues[$dataElementKey] = $dataElementValue; diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php index d01b36528..2c8ab7530 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php @@ -140,7 +140,10 @@ private function initialize() $operationNameValidator = new NameValidationUtil(); foreach ($parserOutput as $dataDefName => $opDefArray) { - $operationNameValidator->validateMetadataOperationName($dataDefName); + $operationNameValidator->validatePascalCase( + $dataDefName, + NameValidationUtil::METADATA_OPERATION_NAME + ); $operation = $opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_TYPE]; $dataType = $opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_DATA_TYPE]; @@ -235,7 +238,7 @@ private function initialize() $deprecated ); } - $operationNameValidator->summarize("metadata operation name"); + $operationNameValidator->summarize(NameValidationUtil::METADATA_OPERATION_NAME); } /** diff --git a/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php b/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php index 1fc8dfd34..5be765074 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Page/Handlers/PageObjectHandler.php @@ -62,7 +62,7 @@ private function __construct() } $filename = $pageData[self::FILENAME] ?? null; - $pageNameValidator->validatePageName($pageName, $filename); + $pageNameValidator->validateAffixes($pageName, NameValidationUtil::PAGE, $filename); $area = $pageData[self::AREA] ?? null; $url = $pageData[self::URL] ?? null; @@ -85,7 +85,7 @@ private function __construct() $this->pageObjects[$pageName] = new PageObject($pageName, $url, $module, $sectionNames, $parameterized, $area, $filename, $deprecated); } - $pageNameValidator->summarize("page name"); + $pageNameValidator->summarize(NameValidationUtil::PAGE . " name"); } /** diff --git a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php index 09d073d33..5d658bac0 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php @@ -68,7 +68,7 @@ private function __construct() } $filename = $sectionData[self::FILENAME] ?? null; - $sectionNameValidator->validateSectionName($sectionName, $filename); + $sectionNameValidator->validateAffixes($sectionName, NameValidationUtil::SECTION, $filename); try { foreach ($sectionData[SectionObjectHandler::ELEMENT] as $elementName => $elementData) { @@ -76,7 +76,11 @@ private function __construct() throw new XmlException(sprintf(self::ELEMENT_NAME_ERROR_MSG, $elementName, $sectionName)); } - $elementNameValidator->validateElementName($elementName, $filename); + $elementNameValidator->validateCamelCase( + $elementName, + NameValidationUtil::SECTION_ELEMENT_NAME, + $filename + ); $elementType = $elementData[SectionObjectHandler::TYPE] ?? null; $elementSelector = $elementData[SectionObjectHandler::SELECTOR] ?? null; $elementLocatorFunc = $elementData[SectionObjectHandler::LOCATOR_FUNCTION] ?? null; @@ -119,8 +123,8 @@ private function __construct() $sectionDeprecated ); } - $sectionNameValidator->summarize("section name"); - $elementNameValidator->summarize("element name"); + $sectionNameValidator->summarize(NameValidationUtil::SECTION . " name"); + $elementNameValidator->summarize(NameValidationUtil::SECTION_ELEMENT_NAME); } /** diff --git a/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php b/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php index 47dacf200..7f1d49d5c 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Test/Handlers/ActionGroupObjectHandler.php @@ -115,7 +115,11 @@ private function initActionGroups() foreach ($neededActionGroup as $actionGroupName => $actionGroupData) { if (!in_array($actionGroupName, ["nodeName", "xsi:noNamespaceSchemaLocation"])) { $filename = $actionGroupData[ActionGroupObjectHandler::ACTION_GROUP_FILENAME_ATTRIBUTE]; - $actionGroupNameValidator->validateActionGroupName($actionGroupName, $filename); + $actionGroupNameValidator->validatePascalCase( + $actionGroupName, + NameValidationUtil::ACTION_GROUP_NAME, + $filename + ); } if (!is_array($actionGroupData)) { @@ -125,7 +129,7 @@ private function initActionGroups() $this->actionGroups[$actionGroupName] = $actionGroupObjectExtractor->extractActionGroup($actionGroupData); } - $actionGroupNameValidator->summarize("action group name"); + $actionGroupNameValidator->summarize(NameValidationUtil::ACTION_GROUP_NAME); } /** diff --git a/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php b/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php index 8a72415f8..109237a77 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Test/Handlers/TestObjectHandler.php @@ -145,7 +145,7 @@ private function initTestData() $testNameValidator = new NameValidationUtil(); foreach ($parsedTestArray as $testName => $testData) { $filename = $testData[TestObjectHandler::TEST_FILENAME_ATTRIBUTE]; - $testNameValidator->validateTestName($testName, $filename); + $testNameValidator->validatePascalCase($testName, NameValidationUtil::TEST_NAME, $filename); if (!is_array($testData)) { continue; } @@ -156,7 +156,7 @@ private function initTestData() } } $exceptionCollector->throwException(); - $testNameValidator->summarize("test name"); + $testNameValidator->summarize(NameValidationUtil::TEST_NAME); $testObjectExtractor->getAnnotationExtractor()->validateStoryTitleUniqueness(); $testObjectExtractor->getAnnotationExtractor()->validateTestCaseIdTitleUniqueness(); } diff --git a/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php b/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php index 50918c146..0112af14e 100644 --- a/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php +++ b/src/Magento/FunctionalTestingFramework/Util/Validation/NameValidationUtil.php @@ -14,6 +14,15 @@ class NameValidationUtil { const PHP_CLASS_REGEX_PATTERN = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/'; + const DATA_ENTITY_NAME = "data entity name"; + const DATA_ENTITY_KEY = "data entity key"; + const METADATA_OPERATION_NAME = "metadata operation name"; + const PAGE = "Page"; + const SECTION = "Section"; + const SECTION_ELEMENT_NAME = "section element name"; + const ACTION_GROUP_NAME = "action group name"; + const TEST_NAME = "test name"; + /** * The number of violations this instance has detected. * @@ -70,17 +79,18 @@ public static function validateName($name, $type) } /** - * Validates data entity names. + * Validates that the string is PascalCase. * * @param string $str + * @param string $type * @param string $filename * @throws Exception * @return void */ - public function validateDataEntityName($str, $filename = null) + public function validatePascalCase($str, $type, $filename = null) { if (!ctype_upper($str[0])) { - $message = "The data entity name {$str} should be PascalCase with an uppercase first letter."; + $message = "The {$type} {$str} should be PascalCase with an uppercase first letter."; if ($filename !== null) { $message .= " See file {$filename}."; @@ -97,44 +107,18 @@ public function validateDataEntityName($str, $filename = null) } /** - * Validates data entity key names. + * Validates that the string is camelCase. * * @param string $str + * @param string $type * @param string $filename * @throws Exception * @return void */ - public function validateDataEntityKey($str, $filename = null) + public function validateCamelCase($str, $type, $filename = null) { if (!ctype_lower($str[0])) { - $message = "The data entity key {$str} should be camelCase with a lowercase first letter."; - - if ($filename !== null) { - $message .= " See file {$filename}."; - } - - LoggingUtil::getInstance()->getLogger(self::class)->notification( - $message, - [], - false - ); - - $this->count++; - } - } - - /** - * Validates metadata operation names. - * - * @param string $str - * @param string $filename - * @throws Exception - * @return void - */ - public function validateMetadataOperationName($str, $filename = null) - { - if (!ctype_upper($str[0])) { - $message = "The metadata operation name {$str} should be PascalCase with an uppercase first letter."; + $message = "The {$type} {$str} should be camelCase with a lowercase first letter."; if ($filename !== null) { $message .= " See file {$filename}."; @@ -151,133 +135,22 @@ public function validateMetadataOperationName($str, $filename = null) } /** - * Validates page names. - * - * @param string $str - * @param string $filename - * @throws Exception - * @return void - */ - public function validatePageName($str, $filename = null) - { - $isPrefixAdmin = substr($str, 0, 5) === "Admin"; - $isPrefixStorefront = substr($str, 0, 10) === "Storefront"; - $isSuffixPage = substr($str, -4) === "Page"; - - if ((!$isPrefixAdmin && !$isPrefixStorefront) || !$isSuffixPage) { - $message = "The page name {$str} should follow the pattern {Admin or Storefront}{Description}Page."; - - if ($filename !== null) { - $message .= " See file {$filename}."; - } - - LoggingUtil::getInstance()->getLogger(self::class)->notification( - $message, - [], - false - ); - - $this->count++; - } - } - - /** - * Validates section names. + * Validates that the string is of the pattern {Admin or Storefront}{Description}{Type}. * * @param string $str + * @param string $type * @param string $filename * @throws Exception * @return void */ - public function validateSectionName($str, $filename = null) + public function validateAffixes($str, $type, $filename = null) { $isPrefixAdmin = substr($str, 0, 5) === "Admin"; $isPrefixStorefront = substr($str, 0, 10) === "Storefront"; - $isSuffixSection = substr($str, -7) === "Section"; - - if ((!$isPrefixAdmin && !$isPrefixStorefront) || !$isSuffixSection) { - $message = "The section name {$str} should follow the pattern {Admin or Storefront}{Description}Section."; - - if ($filename !== null) { - $message .= " See file {$filename}."; - } - - LoggingUtil::getInstance()->getLogger(self::class)->notification( - $message, - [], - false - ); - - $this->count++; - } - } - - /** - * Validates section element names. - * - * @param string $str - * @param string $filename - * @throws Exception - * @return void - */ - public function validateElementName($str, $filename = null) - { - if (!ctype_lower($str[0])) { - $message = "The element name {$str} should be camelCase with a lowercase first letter."; + $isSuffixType = substr($str, -strlen($type)) === $type; - if ($filename !== null) { - $message .= " See file {$filename}."; - } - - LoggingUtil::getInstance()->getLogger(self::class)->notification( - $message, - [], - false - ); - - $this->count++; - } - } - - /** - * Validates action group names. - * - * @param string $str - * @param string $filename - * @throws Exception - * @return void - */ - public function validateActionGroupName($str, $filename = null) - { - if (!ctype_upper($str[0])) { - $message = "The action group name {$str} should be PascalCase with an uppercase first letter."; - - if ($filename !== null) { - $message .= " See file {$filename}."; - } - - LoggingUtil::getInstance()->getLogger(self::class)->notification( - $message, - [], - false - ); - - $this->count++; - } - } - - /** - * Validates test names. - * - * @param string $str - * @param string $filename - * @throws Exception - * @return void - */ - public function validateTestName($str, $filename = null) - { - if (!ctype_upper($str[0])) { - $message = "The test name {$str} should be PascalCase with an uppercase first letter."; + if ((!$isPrefixAdmin && !$isPrefixStorefront) || !$isSuffixType) { + $message = "The {$type} name {$str} should follow the pattern {Admin or Storefront}{Description}{$type}."; if ($filename !== null) { $message .= " See file {$filename}.";