diff --git a/docs/documentation/assertions.md b/docs/documentation/assertions.md index 35868f93..e683ab40 100644 --- a/docs/documentation/assertions.md +++ b/docs/documentation/assertions.md @@ -47,6 +47,9 @@ It asserts that the selected classes **do not depend** on the target classes. ## shouldNotConstruct() It asserts that the selected classes **do not use the constructor** of the target classes. +## shouldNotExist() +It asserts that the selected classes **should not exist**. + ## shouldApplyAttribute() It asserts that the selected classes **apply** the target attributes. diff --git a/src/Rule/Assertion/Declaration/ShouldNotExist/ShouldNotExist.php b/src/Rule/Assertion/Declaration/ShouldNotExist/ShouldNotExist.php new file mode 100644 index 00000000..f1f5beab --- /dev/null +++ b/src/Rule/Assertion/Declaration/ShouldNotExist/ShouldNotExist.php @@ -0,0 +1,61 @@ + + */ +final class ShouldNotExist extends DeclarationAssertion implements Rule +{ + use ValidationTrait; + + public function __construct( + StatementBuilderFactory $statementBuilderFactory, + Configuration $configuration, + ReflectionProvider $reflectionProvider, + FileTypeMapper $fileTypeMapper + ) { + parent::__construct( + __CLASS__, + $statementBuilderFactory, + $configuration, + $reflectionProvider, + $fileTypeMapper + ); + } + + public function getNodeType(): string + { + return InClassNode::class; + } + + protected function applyValidation(string $ruleName, ClassReflection $subject, bool $meetsDeclaration, array $tips, array $params = []): array + { + return $this->applyShouldNot($ruleName, $subject, $meetsDeclaration, $tips, $params); + } + + protected function getMessage(string $ruleName, string $subject, array $params = []): string + { + return $this->prepareMessage( + $ruleName, + sprintf('%s should not exist', $subject) + ); + } + + protected function meetsDeclaration(Node $node, Scope $scope, array $params = []): bool + { + return true; + } +} diff --git a/src/Test/Builder/AssertionStep.php b/src/Test/Builder/AssertionStep.php index 1d04cbf0..b133202c 100644 --- a/src/Test/Builder/AssertionStep.php +++ b/src/Test/Builder/AssertionStep.php @@ -11,6 +11,7 @@ use PHPat\Rule\Assertion\Declaration\ShouldNotBeAbstract\ShouldNotBeAbstract; use PHPat\Rule\Assertion\Declaration\ShouldNotBeFinal\ShouldNotBeFinal; use PHPat\Rule\Assertion\Declaration\ShouldNotBeReadonly\ShouldNotBeReadonly; +use PHPat\Rule\Assertion\Declaration\ShouldNotExist\ShouldNotExist; use PHPat\Rule\Assertion\Relation\CanOnlyDepend\CanOnlyDepend; use PHPat\Rule\Assertion\Relation\ShouldApplyAttribute\ShouldApplyAttribute; use PHPat\Rule\Assertion\Relation\ShouldExtend\ShouldExtend; @@ -157,4 +158,11 @@ public function shouldBeInterface(): TipOrBuildStep return new TipOrBuildStep($this->rule); } + + public function shouldNotExist(): TipOrBuildStep + { + $this->rule->assertion = ShouldNotExist::class; + + return new TipOrBuildStep($this->rule); + } } diff --git a/tests/unit/rules/ShouldNotExist/ShouldNotExistTest.php b/tests/unit/rules/ShouldNotExist/ShouldNotExistTest.php new file mode 100644 index 00000000..ed91639b --- /dev/null +++ b/tests/unit/rules/ShouldNotExist/ShouldNotExistTest.php @@ -0,0 +1,48 @@ + + * @internal + * @coversNothing + */ +class ShouldNotExistTest extends RuleTestCase +{ + public const RULE_NAME = 'test_FixtureClassShouldNotExist'; + + public function testRule(): void + { + $this->analyse(['tests/fixtures/FixtureClass.php'], [ + [sprintf('%s should not exist', FixtureClass::class), 29], + ]); + } + + protected function getRule(): Rule + { + $testParser = FakeTestParser::create( + self::RULE_NAME, + ShouldNotExist::class, + [new Classname(FixtureClass::class, false)], + [] + ); + + return new ShouldNotExist( + new StatementBuilderFactory($testParser), + new Configuration(false, true, false), + $this->createReflectionProvider(), + self::getContainer()->getByType(FileTypeMapper::class) + ); + } +}