Skip to content

Commit

Permalink
feat: allow WithStory attribute on parent class
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil committed Dec 2, 2024
1 parent 7e09d56 commit 3918446
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/PHPUnit/BootFoundryOnDataProviderMethodCalled.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class BootFoundryOnDataProviderMethodCalled implements Event\Test\DataProv
public function notify(Event\Test\DataProviderMethodCalled $event): void
{
if (\method_exists($event->testMethod()->className(), '_bootForDataProvider')) {
\call_user_func([$event->testMethod()->className(), '_bootForDataProvider']);
$event->testMethod()->className()::_bootForDataProvider();
}
}
}
33 changes: 31 additions & 2 deletions src/PHPUnit/BuildStoryOnTestPrepared.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
namespace Zenstruck\Foundry\PHPUnit;

use PHPUnit\Event;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Attribute\WithStory;
use Zenstruck\Foundry\Exception\CannotUseServiceStory;

/**
* @internal
Expand All @@ -32,17 +34,44 @@ public function notify(Event\Test\Prepared $event): void

/** @var Event\Code\TestMethod $test */

$reflectionClass = new \ReflectionClass($test->className());
$withStoryAttributes = [
...(new \ReflectionClass($test->className()))->getAttributes(WithStory::class),
...(new \ReflectionMethod($test->className(), $test->methodName()))->getAttributes(WithStory::class),
...$this->collectWithStoryAttributesFromClassAndParents($reflectionClass),
...$reflectionClass->getMethod($test->methodName())->getAttributes(WithStory::class),
];

if (!$withStoryAttributes) {
return;
}

if (!is_subclass_of($test->className(), KernelTestCase::class)) {
throw new \InvalidArgumentException(
\sprintf(
'The test class "%s" must extend "%s" to use the "%s" attribute.',
$test->className(),
KernelTestCase::class,
WithStory::class
)
);
}

foreach ($withStoryAttributes as $withStoryAttribute) {
$withStoryAttribute->newInstance()->story::load();
}
}

/**
* @return list<\ReflectionAttribute<WithStory>>
*/
private function collectWithStoryAttributesFromClassAndParents(\ReflectionClass $class): array // @phpstan-ignore missingType.generics
{
return [
...$class->getAttributes(WithStory::class),
...(
$class->getParentClass()
? $this->collectWithStoryAttributesFromClassAndParents($class->getParentClass())
: []
)
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class ShutdownFoundryOnDataProviderMethodFinished implements Event\Test\Da
public function notify(Event\Test\DataProviderMethodFinished $event): void
{
if (\method_exists($event->testMethod()->className(), '_shutdownAfterDataProvider')) {
\call_user_func([$event->testMethod()->className(), '_shutdownAfterDataProvider']);
$event->testMethod()->className()::_shutdownAfterDataProvider();
}
}
}
35 changes: 35 additions & 0 deletions tests/Fixture/Stories/ServiceStory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the zenstruck/foundry package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Foundry\Tests\Fixture\Stories;

use Symfony\Component\HttpKernel\KernelInterface;
use Zenstruck\Foundry\Story;
use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory;

/**
* @author Nicolas PHILIPPE <[email protected]>
*/
final class ServiceStory extends Story
{
public function __construct(
private readonly KernelInterface $kernel
) {
}

public function build(): void
{
$this->addState(
'foo',
GenericEntityFactory::createOne(['prop1' => $this->kernel->getEnvironment()])
);
}
}
2 changes: 2 additions & 0 deletions tests/Fixture/TestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;
use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalInvokableService;
use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory;
use Zenstruck\Foundry\Tests\Fixture\Stories\ServiceStory;
use Zenstruck\Foundry\ZenstruckFoundryBundle;

/**
Expand Down Expand Up @@ -162,6 +163,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
$c->register(GlobalInvokableService::class);
$c->register(ArrayFactory::class)->setAutowired(true)->setAutoconfigured(true);
$c->register(Object1Factory::class)->setAutowired(true)->setAutoconfigured(true);
$c->register(ServiceStory::class)->setAutowired(true)->setAutoconfigured(true);
}

protected function configureRoutes(RoutingConfigurator $routes): void
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Zenstruck\Foundry\Tests\Integration\Attribute\WithStory;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Attribute\WithStory;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityStory;

/**
* @author Nicolas PHILIPPE <[email protected]>
*/
#[WithStory(EntityStory::class)]
abstract class ParentClassWithStoryAttributeTestCase extends KernelTestCase
{
use Factories, ResetDatabase;
}
11 changes: 10 additions & 1 deletion tests/Integration/Attribute/WithStory/WithStoryOnClassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@

declare(strict_types=1);

namespace Integration\Attribute\WithStory;
namespace Zenstruck\Foundry\Tests\Integration\Attribute\WithStory;

use PHPUnit\Framework\Attributes\RequiresPhpunit;
use PHPUnit\Framework\Attributes\RequiresPhpunitExtension;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Attribute\WithStory;
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityPoolStory;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityStory;

/**
* @author Nicolas PHILIPPE <[email protected]>
* @requires PHPUnit 11.4
*/
#[RequiresPhpunit('11.4')]
#[RequiresPhpunitExtension(FoundryExtension::class)]
#[WithStory(EntityStory::class)]
final class WithStoryOnClassTest extends KernelTestCase
{
Expand Down
21 changes: 20 additions & 1 deletion tests/Integration/Attribute/WithStory/WithStoryOnMethodTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

declare(strict_types=1);

namespace Integration\Attribute\WithStory;
namespace Zenstruck\Foundry\Tests\Integration\Attribute\WithStory;

use PHPUnit\Framework\Attributes\RequiresPhpunit;
use PHPUnit\Framework\Attributes\RequiresPhpunitExtension;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Attribute\WithStory;
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityPoolStory;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityStory;
use Zenstruck\Foundry\Tests\Fixture\Stories\ServiceStory;

/**
* @author Nicolas PHILIPPE <[email protected]>
* @requires PHPUnit 11.4
*/
#[RequiresPhpunit('11.4')]
#[RequiresPhpunitExtension(FoundryExtension::class)]
final class WithStoryOnMethodTest extends KernelTestCase
{
use Factories, ResetDatabase;
Expand All @@ -37,4 +47,13 @@ public function can_use_multiple_story_in_attribute(): void
{
GenericEntityFactory::assert()->count(5);
}

/**
* @test
*/
#[WithStory(ServiceStory::class)]
public function can_use_service_story(): void
{
$this->assertSame('dev', ServiceStory::get('foo')->getProp1());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Zenstruck\Foundry\Tests\Integration\Attribute\WithStory;

use PHPUnit\Framework\Attributes\RequiresPhpunit;
use PHPUnit\Framework\Attributes\RequiresPhpunitExtension;
use Zenstruck\Foundry\Attribute\WithStory;
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory;
use Zenstruck\Foundry\Tests\Fixture\Stories\EntityPoolStory;

/**
* @author Nicolas PHILIPPE <[email protected]>
* @requires PHPUnit 11.4
*/
#[RequiresPhpunit('11.4')]
#[RequiresPhpunitExtension(FoundryExtension::class)]
#[WithStory(EntityPoolStory::class)]
final class WithStoryOnParentClassTest extends ParentClassWithStoryAttributeTestCase
{
/**
* @test
*/
public function can_use_story_in_attribute_from_parent_class(): void
{
GenericEntityFactory::assert()->count(5);
}
}

0 comments on commit 3918446

Please sign in to comment.