Skip to content

Commit

Permalink
Merge pull request #24 from DaveLiddament/feature/allow-test-tag-on-c…
Browse files Browse the repository at this point in the history
…lass

UPDATE allow TestTag on class
  • Loading branch information
DaveLiddament authored Aug 12, 2024
2 parents 2d30213 + 68a2e82 commit 083f566
Show file tree
Hide file tree
Showing 25 changed files with 433 additions and 129 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"require": {
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"phpstan/phpstan": "^1.11",
"dave-liddament/php-language-extensions": "^0.7.0"
"dave-liddament/php-language-extensions": "^0.8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6.12",
Expand Down
14 changes: 7 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 20 additions & 5 deletions src/Rules/AbstractTestTagRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,40 @@ protected function getErrorOrNull(
string $class,
string $methodName,
): ?RuleError {
$callingClass = $scope->getClassReflection()?->getName();

$classReflection = $this->reflectionProvider->getClass($class);
$className = $classReflection->getName();
$nativeReflection = $classReflection->getNativeReflection();

$fullMethodName = "{$className}::{$methodName}";

if ($this->cache->hasEntry($className)) {
$isTestTagOnClass = $this->cache->getEntry($className);
} else {
$isTestTagOnClass = count($nativeReflection->getAttributes(TestTag::class)) > 0;
$this->cache->addEntry($className, $isTestTagOnClass);
}

if ($this->cache->hasEntry($fullMethodName)) {
$isTestTag = $this->cache->getEntry($fullMethodName);
$isTestTagOnMethod = $this->cache->getEntry($fullMethodName);
} else {
if ($nativeReflection->hasMethod($methodName)) {
$methodReflection = $nativeReflection->getMethod($methodName);
$isTestTag = count($methodReflection->getAttributes(TestTag::class)) > 0;
$isTestTagOnMethod = count($methodReflection->getAttributes(TestTag::class)) > 0;
} else {
$isTestTag = false;
$isTestTagOnMethod = false;
}
$this->cache->addEntry($fullMethodName, $isTestTag);
$this->cache->addEntry($fullMethodName, $isTestTagOnMethod);
}

$hasTestTag = $isTestTagOnClass || $isTestTagOnMethod;

if (!$hasTestTag) {
return null;
}

if (!$isTestTag) {
if ($isTestTagOnClass && ($className === $callingClass)) {
return null;
}

Expand Down
35 changes: 0 additions & 35 deletions tests/Rules/AbstractTestTagRuleTest.php

This file was deleted.

33 changes: 33 additions & 0 deletions tests/Rules/TestTagClassOnConstructorIngoredOnTestClassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagNewCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use DaveLiddament\PhpstanRuleTestHelper\ErrorMessageFormatter;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagNewCallRule> */
class TestTagClassOnConstructorIngoredOnTestClassTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagNewCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(__DIR__.'/data/testTag/testTagClassOnConstructorIgnoredInTestClass.php');
}

protected function getErrorFormatter(): ErrorMessageFormatter|string
{
return 'TestTagClassOnConstructorIgnoredOnTestClass\Person::__construct is a test tag and can only be called from test code';
}
}
33 changes: 33 additions & 0 deletions tests/Rules/TestTagClassOnConstructorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagNewCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use DaveLiddament\PhpstanRuleTestHelper\ErrorMessageFormatter;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagNewCallRule> */
class TestTagClassOnConstructorTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagNewCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(__DIR__.'/data/testTag/testTagClassOnConstructor.php');
}

protected function getErrorFormatter(): ErrorMessageFormatter|string
{
return 'TestTagClassOnConstructor\Person::__construct is a test tag and can only be called from test code';
}
}
29 changes: 29 additions & 0 deletions tests/Rules/TestTagClassOnMethodIgnoredOnTestClassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagMethodCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagMethodCallRule> */
class TestTagClassOnMethodIgnoredOnTestClassTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagMethodCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(
__DIR__.'/data/testTag/testTagClassOnMethodIgnoredInTestClass.php',
);
}
}
33 changes: 33 additions & 0 deletions tests/Rules/TestTagClassOnMethodTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagMethodCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use DaveLiddament\PhpstanRuleTestHelper\ErrorMessageFormatter;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagMethodCallRule> */
class TestTagClassOnMethodTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagMethodCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(__DIR__.'/data/testTag/testTagClassOnMethod.php');
}

protected function getErrorFormatter(): ErrorMessageFormatter|string
{
return 'TestTagClassOnMethod\Person::updateName is a test tag and can only be called from test code';
}
}
27 changes: 27 additions & 0 deletions tests/Rules/TestTagClassOnStaticIgnoredOnTestClassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagStaticCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagStaticCallRule> */
class TestTagClassOnStaticIgnoredOnTestClassTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagStaticCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(__DIR__.'/data/testTag/testTagClassOnStaticMethodIgnoredInTestClass.php');
}
}
32 changes: 32 additions & 0 deletions tests/Rules/TestTagClassOnStaticTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace DaveLiddament\PhpstanPhpLanguageExtensions\Tests\Rules;

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagStaticCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use PHPStan\Rules\Rule;

/** @extends AbstractRuleTestCase<TestTagStaticCallRule> */
final class TestTagClassOnStaticTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new TestTagStaticCallRule(
$this->createReflectionProvider(),
new TestConfig(TestConfig::CLASS_NAME),
);
}

public function testMethodCall(): void
{
$this->assertIssuesReported(__DIR__.'/data/testTag/testTagClassOnStaticMethod.php');
}

protected function getErrorFormatter(): string
{
return 'TestTagClassOnStaticMethod\Person::updateName is a test tag and can only be called from test code';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagNewCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use PHPStan\Rules\Rule;

/** @extends AbstractTestTagRuleTest<TestTagNewCallRule> */
class TestTagOnConstructorIgnoredInTestNamespaceTest extends AbstractTestTagRuleTest
/** @extends AbstractRuleTestCase<TestTagNewCallRule> */
class TestTagOnConstructorIgnoredInTestNamespaceTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
Expand All @@ -24,7 +25,7 @@ protected function getRule(): Rule

public function testMethodCall(): void
{
$this->assertNoErrorsReported(
$this->assertIssuesReported(
__DIR__.'/data/testTag/testTagOnConstructorIgnoredInTestNamespace.php',
);
}
Expand Down
7 changes: 4 additions & 3 deletions tests/Rules/TestTagOnConstructorIgnoredOnTestClassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

use DaveLiddament\PhpstanPhpLanguageExtensions\Config\TestConfig;
use DaveLiddament\PhpstanPhpLanguageExtensions\Rules\TestTagNewCallRule;
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
use PHPStan\Rules\Rule;

/** @extends AbstractTestTagRuleTest<TestTagNewCallRule> */
class TestTagOnConstructorIgnoredOnTestClassTest extends AbstractTestTagRuleTest
/** @extends AbstractRuleTestCase<TestTagNewCallRule> */
class TestTagOnConstructorIgnoredOnTestClassTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
Expand All @@ -21,7 +22,7 @@ protected function getRule(): Rule

public function testMethodCall(): void
{
$this->assertNoErrorsReported(
$this->assertIssuesReported(
__DIR__.'/data/testTag/testTagOnConstructorIgnoredInTestClass.php',
);
}
Expand Down
Loading

0 comments on commit 083f566

Please sign in to comment.