-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TE-10302: TE-9946: TE-10308: TE-10300: Created rule for delete facade…
… method (#113) * TE-10302: Created rule for delete facade method * TE-10302: Created rule for delete facade method * TE-10302: Created rule for delete facade method * TE-10302: Changed violation for facade rule * TE-10302: Added create rule * TE-10302: Added create rule * TE-10302: Added create rule * TE-10302: created rule update, save * TE-10302: Create rule get*Collection for facade signature * TE-10302: updated messages * TE-10302: fixed error message Co-authored-by: dima_tsemma <[email protected]>
- Loading branch information
1 parent
6edac6a
commit 4a29a06
Showing
6 changed files
with
502 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved. | ||
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. | ||
*/ | ||
|
||
namespace ArchitectureSniffer\Common\Bridge; | ||
|
||
use ArchitectureSniffer\SprykerAbstractRule; | ||
use PHPMD\AbstractNode; | ||
use PHPMD\Node\ClassNode; | ||
use PHPMD\Node\MethodNode; | ||
use PHPMD\Rule\ClassAware; | ||
use ReflectionMethod; | ||
use ReflectionType; | ||
|
||
class BridgeFacadeMethodsRule extends SprykerAbstractRule implements ClassAware | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected const RULE = 'Based on naming convention the bridge facade method must follow CRUD signature.'; | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getDescription() | ||
{ | ||
return static::RULE; | ||
} | ||
|
||
/** | ||
* @param \PHPMD\AbstractNode $node | ||
* | ||
* @return void | ||
*/ | ||
public function apply(AbstractNode $node) | ||
{ | ||
if ( | ||
preg_match('([A-Za-z0-9]+Bridge$)', $node->getName()) === 0 || | ||
preg_match('#.*\\\\Dependency\\\\Facade.*#', $node->getNamespaceName()) === 0 || | ||
!$node instanceof ClassNode | ||
) { | ||
return; | ||
} | ||
$bridgeName = $node->getFullQualifiedName(); | ||
|
||
foreach ($node->getMethods() as $method) { | ||
$interfaceMethodName = sprintf('%s::%s', $bridgeName, $method->getName()); | ||
$interfaceMethodReflection = new ReflectionMethod($interfaceMethodName); | ||
$methodReturnType = $interfaceMethodReflection->getReturnType(); | ||
|
||
if (preg_match('/^(get|read|find)/', $method->getName())) { | ||
$this->verifyGetMethod($method, $methodReturnType); | ||
|
||
continue; | ||
} | ||
|
||
if (preg_match('/^(delete|remove)/', $method->getName())) { | ||
$this->verifyDeleteMethod($method, $methodReturnType); | ||
|
||
continue; | ||
} | ||
|
||
if (preg_match('/^(create|add)/', $method->getName())) { | ||
$this->verifyCreateMethod($method, $methodReturnType); | ||
|
||
continue; | ||
} | ||
|
||
if (preg_match('/^(update|change)/', $method->getName())) { | ||
$this->verifyUpdateMethod($method, $methodReturnType); | ||
|
||
continue; | ||
} | ||
|
||
if (strpos($method->getName(), 'save') === 0) { | ||
$this->addViolation($method, [sprintf( | ||
'Method `%s()` must have `public function [update|create]<DomainEntity>Collection(<DomainEntity>CollectionRequestTransfer): <DomainEntity>CollectionResponseTransfer` signature.', | ||
$method->getName(), | ||
)]); | ||
|
||
continue; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @param \PHPMD\Node\MethodNode $method | ||
* @param \ReflectionType|null $methodReturnType | ||
* | ||
* @return void | ||
*/ | ||
protected function verifyGetMethod(MethodNode $method, ?ReflectionType $methodReturnType): void | ||
{ | ||
$parameters = $method->getNode()->getParameters(); | ||
|
||
if ( | ||
$method->getParameterCount() !== 1 || | ||
!$parameters[0]->getClass() || | ||
!$methodReturnType || | ||
preg_match('/^get(?<domainEntity>\w+)Collection$/', $method->getName(), $methodNameMatches) === 0 || | ||
preg_match('/^(?<domainEntity>\w+)CriteriaTransfer$/', $parameters[0]->getClass()->getName(), $methodParameterMatches) === 0 || | ||
preg_match('/^Generated\\\\Shared\\\\Transfer\\\\(?<domainEntity>\w+)CollectionTransfer$/', $methodReturnType->getName(), $methodReturnTypeMatches) === 0 || | ||
count(array_unique([$methodNameMatches['domainEntity'], $methodParameterMatches['domainEntity'], $methodReturnTypeMatches['domainEntity']])) !== 1 | ||
) { | ||
$this->addViolation($method, [sprintf( | ||
'Method `%s()` must have `public function get<DomainEntity>Collection(<DomainEntity>CriteriaTransfer): <DomainEntity>CollectionTransfer` signature.', | ||
$method->getName(), | ||
)]); | ||
} | ||
} | ||
|
||
/** | ||
* @param \PHPMD\Node\MethodNode $method | ||
* @param \ReflectionType|null $methodReturnType | ||
* | ||
* @return void | ||
*/ | ||
protected function verifyUpdateMethod(MethodNode $method, ?ReflectionType $methodReturnType): void | ||
{ | ||
$parameters = $method->getNode()->getParameters(); | ||
|
||
if ( | ||
$method->getParameterCount() !== 1 || | ||
!$parameters[0]->getClass() || | ||
!$methodReturnType || | ||
preg_match('/^update(?<domainEntity>\w+)Collection$/', $method->getName(), $methodNameMatches) === 0 || | ||
preg_match('/^(?<domainEntity>\w+)CollectionRequestTransfer$/', $parameters[0]->getClass()->getName(), $methodParameterMatches) === 0 || | ||
preg_match('/^Generated\\\\Shared\\\\Transfer\\\\(?<domainEntity>\w+)CollectionResponseTransfer$/', $methodReturnType->getName(), $methodReturnTypeMatches) === 0 || | ||
count(array_unique([$methodNameMatches['domainEntity'], $methodParameterMatches['domainEntity'], $methodReturnTypeMatches['domainEntity']])) !== 1 | ||
) { | ||
$this->addViolation($method, [sprintf( | ||
'Method `%s()` must have `public function update<DomainEntity>Collection(<DomainEntity>CollectionRequestTransfer): <DomainEntity>CollectionResponseTransfer` signature.', | ||
$method->getName(), | ||
)]); | ||
} | ||
} | ||
|
||
/** | ||
* @param \PHPMD\Node\MethodNode $method | ||
* @param \ReflectionType|null $methodReturnType | ||
* | ||
* @return void | ||
*/ | ||
protected function verifyDeleteMethod(MethodNode $method, ?ReflectionType $methodReturnType): void | ||
{ | ||
$parameters = $method->getNode()->getParameters(); | ||
|
||
if ( | ||
$method->getParameterCount() !== 1 || | ||
!$parameters[0]->getClass() || | ||
!$methodReturnType || | ||
preg_match('/^delete(?<domainEntity>\w+)Collection$/', $method->getName(), $methodNameMatches) === 0 || | ||
preg_match('/^(?<domainEntity>\w+)CollectionDeleteCriteriaTransfer$/', $parameters[0]->getClass()->getName(), $methodParameterMatches) === 0 || | ||
preg_match('/^Generated\\\\Shared\\\\Transfer\\\\(?<domainEntity>\w+)CollectionResponseTransfer$/', $methodReturnType->getName(), $methodReturnTypeMatches) === 0 || | ||
count(array_unique([$methodNameMatches['domainEntity'], $methodParameterMatches['domainEntity'], $methodReturnTypeMatches['domainEntity']])) !== 1 | ||
) { | ||
$this->addViolation($method, [sprintf( | ||
'Method `%s()` must have `public function delete<DomainEntity>Collection(<DomainEntity>CollectionDeleteCriteriaTransfer): <DomainEntity>CollectionResponseTransfer` signature.', | ||
$method->getName(), | ||
)]); | ||
} | ||
} | ||
|
||
/** | ||
* @param \PHPMD\Node\MethodNode $method | ||
* @param \ReflectionType|null $methodReturnType | ||
* | ||
* @return void | ||
*/ | ||
protected function verifyCreateMethod(MethodNode $method, ?ReflectionType $methodReturnType): void | ||
{ | ||
$parameters = $method->getNode()->getParameters(); | ||
|
||
if ( | ||
$method->getParameterCount() !== 1 || | ||
!$parameters[0]->getClass() || | ||
!$methodReturnType || | ||
preg_match('/^create(?<domainEntity>\w+)Collection$/', $method->getName(), $methodNameMatches) === 0 || | ||
preg_match('/^(?<domainEntity>\w+)CollectionRequestTransfer$/', $parameters[0]->getClass()->getName(), $methodParameterMatches) === 0 || | ||
preg_match('/^Generated\\\\Shared\\\\Transfer\\\\(?<domainEntity>\w+)CollectionResponseTransfer$/', $methodReturnType->getName(), $methodReturnTypeMatches) === 0 || | ||
count(array_unique([$methodNameMatches['domainEntity'], $methodParameterMatches['domainEntity'], $methodReturnTypeMatches['domainEntity']])) !== 1 | ||
) { | ||
$this->addViolation($method, [sprintf( | ||
'Method `%s()` must have `public function create<DomainEntity>Collection(<DomainEntity>CollectionRequestTransfer): <DomainEntity>CollectionResponseTransfer` signature.', | ||
$method->getName(), | ||
)]); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
/** | ||
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved. | ||
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. | ||
*/ | ||
|
||
namespace ArchitectureSnifferTest\Common\Bridge; | ||
|
||
use ArchitectureSniffer\Common\Bridge\BridgeFacadeMethodsRule; | ||
use ArchitectureSnifferTest\AbstractArchitectureSnifferRuleTest; | ||
|
||
class BridgeFacadeMethodsTest extends AbstractArchitectureSnifferRuleTest | ||
{ | ||
/** | ||
* @return void | ||
*/ | ||
public function testRuleDoesNotApplyWhenBridgeFacadeMethodsAreNotCorrect(): void | ||
{ | ||
$bridgeMethodsRule = new BridgeFacadeMethodsRule(); | ||
$bridgeMethodsRule->setReport($this->getReportMock(17)); | ||
$bridgeMethodsRule->apply($this->getClassNode()); | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
public function testRuleAppliesWhenFacadeBridgeMethodsAreCorrect(): void | ||
{ | ||
$bridgeMethodsRule = new BridgeFacadeMethodsRule(); | ||
$bridgeMethodsRule->setReport($this->getReportMock(0)); | ||
$bridgeMethodsRule->apply($this->getClassNode()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...ommon/Bridge/BridgeFacadeMethodsTest/testRuleAppliesWhenFacadeBridgeMethodsAreCorrect.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
/** | ||
* MIT License | ||
* For full license information, please view the LICENSE file that was distributed with this source code. | ||
*/ | ||
|
||
namespace SprykerTest\Zed\Session\Dependency\Facade; | ||
|
||
use Generated\Shared\Transfer\TestCollectionDeleteCriteriaTransfer; | ||
use Generated\Shared\Transfer\TestCollectionRequestTransfer; | ||
use Generated\Shared\Transfer\TestCollectionResponseTransfer; | ||
use Generated\Shared\Transfer\TestCollectionTransfer; | ||
use Generated\Shared\Transfer\TestCriteriaTransfer; | ||
use Spryker\Zed\Test\Facade\SessionToTestFacadeInterface; | ||
|
||
class SessionToTestFacadeBridge implements SessionToTestFacadeInterface | ||
{ | ||
/** | ||
* @param \Spryker\Zed\Test\Facade\TestFacadeInterface $testFacade | ||
*/ | ||
public function __construct($testFacade) | ||
{ | ||
} | ||
|
||
public function deleteTestCollection(TestCollectionDeleteCriteriaTransfer $testCollectionDeleteCriteriaTransfer): TestCollectionResponseTransfer | ||
{ | ||
} | ||
|
||
public function createTestCollection(TestCollectionRequestTransfer $testCollectionRequestTransfer): TestCollectionResponseTransfer | ||
{ | ||
} | ||
|
||
public function updateTestCollection(TestCollectionRequestTransfer $testCollectionRequestTransfer): TestCollectionResponseTransfer | ||
{ | ||
} | ||
|
||
public function getTestCollection(TestCriteriaTransfer $testCriteriaTransfer): TestCollectionTransfer | ||
{ | ||
} | ||
} | ||
|
||
// Database module | ||
|
||
namespace Spryker\Zed\Test\Facade; | ||
|
||
use Generated\Shared\Transfer\TestCollectionDeleteCriteriaTransfer; | ||
use Generated\Shared\Transfer\TestCollectionRequestTransfer; | ||
use Generated\Shared\Transfer\TestCollectionResponseTransfer; | ||
use Generated\Shared\Transfer\TestCollectionTransfer; | ||
use Generated\Shared\Transfer\TestCriteriaTransfer; | ||
|
||
interface SessionToTestFacadeInterface | ||
{ | ||
public function deleteTestCollection(TestCollectionDeleteCriteriaTransfer $testCollectionDeleteCriteriaTransfer): TestCollectionResponseTransfer; | ||
public function createTestCollection(TestCollectionRequestTransfer $testCollectionRequestTransfer): TestCollectionResponseTransfer; | ||
public function updateTestCollection(TestCollectionRequestTransfer $testCollectionRequestTransfer): TestCollectionResponseTransfer; | ||
public function getTestCollection(TestCriteriaTransfer $testCriteriaTransfer): TestCollectionTransfer; | ||
} | ||
|
||
namespace Generated\Shared\Transfer; | ||
|
||
class TestCollectionTransfer | ||
{ | ||
|
||
} | ||
|
||
class TestCriteriaTransfer | ||
{ | ||
|
||
} | ||
|
||
class TestCollectionResponseTransfer | ||
{ | ||
|
||
} | ||
|
||
class TestCollectionRequestTransfer | ||
{ | ||
|
||
} | ||
|
||
class TestCollectionDeleteCriteriaTransfer | ||
{ | ||
|
||
} | ||
|
||
namespace Spryker\Zed\Test\Facade; | ||
|
||
interface TestFacadeInterface | ||
{ | ||
} |
Oops, something went wrong.