Skip to content

Commit

Permalink
Add shouldNotExist assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnaDamm authored Jul 5, 2024
1 parent ce5818b commit 24f657b
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 1 deletion.
3 changes: 3 additions & 0 deletions docs/documentation/assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 **do not exist**.

## shouldApplyAttribute()
It asserts that the selected classes **apply** the target attributes.

Expand Down
8 changes: 7 additions & 1 deletion extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ services:
tags:
- phpstan.rules.rule

# # # # # RELATION RULES # # # # #
# ShouldNotExist rules
-
class: PHPat\Rule\Assertion\Declaration\ShouldNotExist\ExistsRule
tags:
- phpstan.rules.rule

# # # # # RELATION RULES # # # # #

# ShouldImplement rules
-
Expand Down
15 changes: 15 additions & 0 deletions src/Rule/Assertion/Declaration/ShouldNotExist/ExistsRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);

namespace PHPat\Rule\Assertion\Declaration\ShouldNotExist;

use PHPat\Rule\Extractor\Declaration\ExistsExtractor;
use PHPStan\Node\InClassNode;
use PHPStan\Rules\Rule;

/**
* @implements Rule<InClassNode>
*/
final class ExistsRule extends ShouldNotExist implements Rule
{
use ExistsExtractor;
}
44 changes: 44 additions & 0 deletions src/Rule/Assertion/Declaration/ShouldNotExist/ShouldNotExist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types=1);

namespace PHPat\Rule\Assertion\Declaration\ShouldNotExist;

use PHPat\Configuration;
use PHPat\Rule\Assertion\Declaration\DeclarationAssertion;
use PHPat\Rule\Assertion\Declaration\ValidationTrait;
use PHPat\Statement\Builder\StatementBuilderFactory;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\FileTypeMapper;

abstract class ShouldNotExist extends DeclarationAssertion
{
use ValidationTrait;

public function __construct(
StatementBuilderFactory $statementBuilderFactory,
Configuration $configuration,
ReflectionProvider $reflectionProvider,
FileTypeMapper $fileTypeMapper
) {
parent::__construct(
__CLASS__,
$statementBuilderFactory,
$configuration,
$reflectionProvider,
$fileTypeMapper
);
}

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)
);
}
}
23 changes: 23 additions & 0 deletions src/Rule/Extractor/Declaration/ExistsExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php declare(strict_types=1);

namespace PHPat\Rule\Extractor\Declaration;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassNode;

trait ExistsExtractor
{
public function getNodeType(): string
{
return InClassNode::class;
}

/**
* @param InClassNode $node
*/
protected function meetsDeclaration(Node $node, Scope $scope, array $params = []): bool
{
return true;
}
}
8 changes: 8 additions & 0 deletions src/Test/Builder/AssertionStep.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
48 changes: 48 additions & 0 deletions tests/unit/rules/ShouldNotExist/ShouldNotExistTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php declare(strict_types=1);

namespace Tests\PHPat\unit\rules\ShouldNotExist;

use PHPat\Configuration;
use PHPat\Rule\Assertion\Declaration\ShouldNotExist\ExistsRule;
use PHPat\Rule\Assertion\Declaration\ShouldNotExist\ShouldNotExist;
use PHPat\Selector\Classname;
use PHPat\Statement\Builder\StatementBuilderFactory;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use PHPStan\Type\FileTypeMapper;
use Tests\PHPat\fixtures\FixtureClass;
use Tests\PHPat\unit\FakeTestParser;

/**
* @extends RuleTestCase<ShouldNotExist>
* @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 ExistsRule(
new StatementBuilderFactory($testParser),
new Configuration(false, true, false),
$this->createReflectionProvider(),
self::getContainer()->getByType(FileTypeMapper::class)
);
}
}

0 comments on commit 24f657b

Please sign in to comment.