Skip to content

Commit

Permalink
テストを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
kento-oka committed Jan 31, 2022
1 parent 79a0b8f commit fb26944
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 0 deletions.
3 changes: 3 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ parameters:
-
message: '#Method Fratily\\AttributeLoader\\AttributeLoader::load\(\) has parameter \$reflection with generic class ReflectionClass but does not specify its types: T#'
path: src/AttributeLoader.php
-
message: '#Dynamic call to static method PHPUnit\\Framework\\Assert::.+#'
path: tests
6 changes: 6 additions & 0 deletions tests/Helper/BarNotAttribute.php
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 {}
9 changes: 9 additions & 0 deletions tests/Helper/BazAttribute.php
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 {}
9 changes: 9 additions & 0 deletions tests/Helper/FooAttribute.php
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 {}
55 changes: 55 additions & 0 deletions tests/Unit/ConstructTest.php
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,
],
];
}
}
112 changes: 112 additions & 0 deletions tests/Unit/LoadTest.php
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]));
}
}
21 changes: 21 additions & 0 deletions tests/Unit/load_test_helper.php
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 {}

0 comments on commit fb26944

Please sign in to comment.