-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
215 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
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,6 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Fratily\Tests\AttributeLoader\Helper; | ||
|
||
class BarNotAttribute extends FooAttribute {} |
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,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Fratily\Tests\AttributeLoader\Helper; | ||
|
||
use Attribute; | ||
|
||
#[Attribute()] | ||
class BazAttribute extends BarNotAttribute {} |
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,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Fratily\Tests\AttributeLoader\Helper; | ||
|
||
use Attribute; | ||
|
||
#[Attribute()] | ||
class FooAttribute {} |
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,55 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Fratily\Tests\AttributeLoader\Unit; | ||
|
||
use Fratily\AttributeLoader\AttributeLoader; | ||
use Fratily\Tests\AttributeLoader\Helper\BarNotAttribute; | ||
use InvalidArgumentException; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ConstructTest extends TestCase | ||
{ | ||
/** | ||
* @dataProvider dataProvider_invalidParameters | ||
* | ||
* @template T of object | ||
* @phpstan-param class-string<T> $attributeClass | ||
* @phpstan-param (callable(\ReflectionAttribute<T>):T)|null $attributeInstanceBuilder | ||
*/ | ||
public function test_invalidParameters( | ||
string $exceptionMessage, | ||
string $attributeClass, | ||
callable|null $attributeInstanceBuilder, | ||
bool $allowSubClass | ||
): void { | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage($exceptionMessage); | ||
|
||
new AttributeLoader($attributeClass, $attributeInstanceBuilder, $allowSubClass); | ||
} | ||
|
||
/** | ||
* @phpstan-return array<string,array{string,class-string,callable|null,bool}> | ||
*/ | ||
public function dataProvider_invalidParameters(): array | ||
{ | ||
/** @phpstan-var class-string */ | ||
$not_exists_class = 'not_exists_class'; | ||
$cannot_be_used_as_attribute = BarNotAttribute::class; | ||
return [ | ||
'not exists class' => [ | ||
"Class {$not_exists_class} is not exists.", | ||
$not_exists_class, | ||
null, | ||
false, | ||
], | ||
'cannot be used as attribute' => [ | ||
"Class {$cannot_be_used_as_attribute} cannot be used as attribute.", | ||
$cannot_be_used_as_attribute, | ||
null, | ||
false, | ||
], | ||
]; | ||
} | ||
} |
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,112 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Fratily\Tests\AttributeLoader\Unit; | ||
|
||
include __DIR__ . '/load_test_helper.php'; | ||
|
||
use Error; | ||
use Fratily\AttributeLoader\AttributeLoader; | ||
use Fratily\Tests\AttributeLoader\Helper\BarNotAttribute; | ||
use Fratily\Tests\AttributeLoader\Helper\BazAttribute; | ||
use Fratily\Tests\AttributeLoader\Helper\FooAttribute; | ||
use LogicException; | ||
use PHPUnit\Framework\TestCase; | ||
use ReflectionFunction; | ||
|
||
class LoadTest extends TestCase | ||
{ | ||
public function test_subclassWillNotBeDetectedIfAllowSubClassIsNone(): void | ||
{ | ||
$attributes = (new AttributeLoader(FooAttribute::class))->load( | ||
new ReflectionFunction('func_baz_and_foo_attribute') | ||
); | ||
|
||
$this->assertCount(1, $attributes); | ||
$this->assertSame(FooAttribute::class, get_class($attributes[0])); | ||
} | ||
|
||
public function test_subclassWillNotBeDetectedIfAllowSubClassIsFalse(): void | ||
{ | ||
$attributes = (new AttributeLoader(FooAttribute::class, null, false))->load( | ||
new ReflectionFunction('func_baz_and_foo_attribute') | ||
); | ||
|
||
$this->assertCount(1, $attributes); | ||
$this->assertSame(FooAttribute::class, get_class($attributes[0])); | ||
} | ||
|
||
public function test_subclassWillBeDetectedIfAllowSubClassIsTrue(): void | ||
{ | ||
$attributes = (new AttributeLoader(FooAttribute::class, null, true))->load( | ||
new ReflectionFunction('func_baz_and_foo_attribute') | ||
); | ||
|
||
$this->assertCount(2, $attributes); | ||
$this->assertSame(BazAttribute::class, get_class($attributes[0])); | ||
$this->assertSame(FooAttribute::class, get_class($attributes[1])); | ||
} | ||
|
||
/** | ||
* @dataProvider dataProvider_invalidBuilder | ||
* @phpstan-param callable(\ReflectionAttribute<FooAttribute>):FooAttribute $builder | ||
* @phpstan-param class-string<\Throwable> $exception | ||
*/ | ||
public function test_invalidBuilder( | ||
callable $builder, | ||
bool $allow_sub_class, | ||
string $exception, | ||
string $exception_message | ||
): void { | ||
$this->expectException($exception); | ||
$this->expectExceptionMessage($exception_message); | ||
|
||
(new AttributeLoader(FooAttribute::class, $builder, $allow_sub_class))->load( | ||
new ReflectionFunction('func_foo_attribute') | ||
); | ||
} | ||
/** | ||
* @phpstan-return array<string,array{callable(\ReflectionAttribute<\Attribute>):mixed,bool,class-string<\Throwable>,string}> | ||
*/ | ||
public function dataProvider_invalidBuilder(): array | ||
{ | ||
return [ | ||
'returned not object' => [ | ||
fn() => 'not object', | ||
false, | ||
LogicException::class, | ||
'The builder must return an instance of the specified attribute class.' | ||
. ' Expected instance of ' . FooAttribute::class . ', but string was returned.' | ||
], | ||
'returned sub class' => [ | ||
fn() => new BazAttribute(), | ||
true, | ||
LogicException::class, | ||
'The builder must return an instance of the specified attribute class.' | ||
. ' Expected instance of ' . FooAttribute::class . ', but instance of ' . BazAttribute::class . ' was returned.' | ||
], | ||
]; | ||
} | ||
|
||
public function test_notAttributeClassCannotMakeInstanceIfWithoutBuilder(): void | ||
{ | ||
$this->expectException(Error::class); | ||
$this->expectExceptionMessage( | ||
'Attempting to use non-attribute class "Fratily\Tests\AttributeLoader\Helper\BarNotAttribute" as attribute' | ||
); | ||
|
||
(new AttributeLoader(FooAttribute::class, null, true))->load( | ||
new ReflectionFunction('func_bar_not_attribute') | ||
); | ||
} | ||
|
||
public function test_notAttributeClassCanMakeInstanceIfWithBuilder(): void | ||
{ | ||
$attributes = (new AttributeLoader(FooAttribute::class, fn() => new BarNotAttribute(), true))->load( | ||
new ReflectionFunction('func_bar_not_attribute') | ||
); | ||
|
||
$this->assertCount(1, $attributes); | ||
$this->assertSame(BarNotAttribute::class, get_class($attributes[0])); | ||
} | ||
} |
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,21 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
use Fratily\Tests\AttributeLoader\Unit\LoadTest; | ||
|
||
use Fratily\Tests\AttributeLoader\Helper\FooAttribute; | ||
use Fratily\Tests\AttributeLoader\Helper\BarNotAttribute; | ||
use Fratily\Tests\AttributeLoader\Helper\BazAttribute; | ||
|
||
#[FooAttribute] | ||
function func_foo_attribute(): void {} | ||
|
||
// @phpstan-ignore-next-line not an Attribute class. | ||
#[BarNotAttribute] | ||
function func_bar_not_attribute(): void {} | ||
|
||
#[BazAttribute] | ||
function func_baz_attribute(): void {} | ||
|
||
#[BazAttribute, FooAttribute] | ||
function func_baz_and_foo_attribute(): void {} |