diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 4e8e41581..fd89b765d 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -41,7 +41,7 @@ jobs: # old PHPUnit versions - {php: 8.3, symfony: 7.4.*, phpunit: 9, database: mysql, use-phpunit-extension: 0} - - {php: 8.4, symfony: 7.4.*, phpunit: 10, database: mysql, use-phpunit-extension: 0} + - {php: 8.2, symfony: 7.4.*, phpunit: 10, database: mysql, use-phpunit-extension: 0} - {php: 8.4, symfony: 7.4.*, phpunit: 11, database: mysql, use-phpunit-extension: 0} - {php: 8.4, symfony: 7.4.*, phpunit: 11, database: mysql} - {php: 8.4, symfony: 7.4.*, phpunit: 12, database: mysql, use-phpunit-extension: 0} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 805c24dde..e7ea55728 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -12,6 +12,7 @@ $csFixerConfig->setFinder( $csFixerConfig->getFinder() ->notName('WebTestCaseWithBothTraitsInWrongOrderTest.php') + ->notName('GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest.php') ->in(__DIR__.'/utils') ->in(__DIR__.'/config') ); diff --git a/src/Test/Factories.php b/src/Test/Factories.php index 0ea70235e..d36fb8780 100644 --- a/src/Test/Factories.php +++ b/src/Test/Factories.php @@ -20,47 +20,68 @@ /** * @author Kevin Bond */ -trait Factories -{ - /** - * @internal - * @before - */ - #[Before(5)] - public function _beforeHook(): void +if (!\method_exists(Before::class, '__construct')) { // @phpstan-ignore function.alreadyNarrowedType + trait Factories { - if (FoundryExtension::isEnabled()) { - trigger_deprecation('zenstruck/foundry', '2.9', \sprintf('Trait %s is deprecated and will be removed in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.', Factories::class)); + use CommonFactories; - return; + /** + * @internal + * @before + */ + #[Before] + public function _beforeHook(): void + { + $this->_bootFoundry(); } - if (FoundryExtension::shouldBeEnabled()) { - trigger_deprecation('zenstruck/foundry', '2.9', 'Not using Foundry\'s PHPUnit extension is deprecated and will throw an error in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.'); + /** + * @internal + * @after + */ + #[After] + public static function _afterHook(): void + { + self::_shutdownFoundry(); + } + } +} else { + trait Factories + { + use CommonFactories; + + /** @internal */ + #[Before(5)] + public function _beforeHook(): void + { + $this->_bootFoundry(); } - $this->_bootFoundry(); + /** @internal */ + #[After(5)] + public static function _afterHook(): void + { + self::_shutdownFoundry(); + } } +} - /** - * @internal - * @after - */ - #[After(5)] - public static function _shutdownFoundry(): void +/** @internal */ +trait CommonFactories +{ + /** @internal */ + private function _bootFoundry(): void { if (FoundryExtension::isEnabled()) { + trigger_deprecation('zenstruck/foundry', '2.9', \sprintf('Trait %s is deprecated and will be removed in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.', Factories::class)); + return; } - Configuration::shutdown(); - } + if (FoundryExtension::shouldBeEnabled()) { + trigger_deprecation('zenstruck/foundry', '2.9', 'Not using Foundry\'s PHPUnit extension is deprecated and will throw an error in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.'); + } - /** - * @internal - */ - private function _bootFoundry(): void - { if (!\is_subclass_of(static::class, KernelTestCase::class)) { // @phpstan-ignore function.impossibleType, function.alreadyNarrowedType // unit test Configuration::boot(UnitTestConfig::build()); @@ -77,4 +98,14 @@ private function _bootFoundry(): void return static::getContainer()->get('.zenstruck_foundry.configuration'); // @phpstan-ignore staticMethod.notFound, return.type }); } + + /** @internal */ + private static function _shutdownFoundry(): void + { + if (FoundryExtension::isEnabled()) { + return; + } + + Configuration::shutdown(); + } } diff --git a/src/Test/ResetDatabase.php b/src/Test/ResetDatabase.php index 6e0cc4382..ddab3afda 100644 --- a/src/Test/ResetDatabase.php +++ b/src/Test/ResetDatabase.php @@ -23,7 +23,37 @@ /** * @author Kevin Bond */ -trait ResetDatabase +if (!\method_exists(Before::class, '__construct')) { // @phpstan-ignore function.alreadyNarrowedType + trait ResetDatabase + { + use CommonResetDatabase; + + /** + * @internal + * @before + */ + #[Before] + public static function _resetDatabaseBeforeEachTest(): void + { + self::_commonResetDatabaseBeforeEachTest(); + } + } +} else { + trait ResetDatabase + { + use CommonResetDatabase; + + /** @internal */ + #[Before(10)] + public static function _resetDatabaseBeforeEachTest(): void + { + self::_commonResetDatabaseBeforeEachTest(); + } + } +} + +/** @internal */ +trait CommonResetDatabase { /** * @internal @@ -45,32 +75,7 @@ public static function _resetDatabaseBeforeFirstTest(): void static::_shutdown(); // @phpstan-ignore staticClassAccess.privateMethod } - /** - * @internal - * @before - */ - #[Before(10)] - public static function _resetDatabaseBeforeEachTest(): void - { - if (FoundryExtension::isEnabled()) { - return; - } - - if (ResetDatabaseManager::canSkipSchemaReset()) { - // can fully skip booting the kernel - return; - } - - $kernel = static::_boot(); // @phpstan-ignore staticClassAccess.privateMethod - - ResetDatabaseManager::resetBeforeEachTest($kernel); - - static::_shutdown(); // @phpstan-ignore staticClassAccess.privateMethod - } - - /** - * @internal - */ + /** @internal */ private static function _boot(): KernelInterface { if (!\is_subclass_of(static::class, KernelTestCase::class)) { // @phpstan-ignore function.alreadyNarrowedType @@ -88,9 +93,7 @@ private static function _boot(): KernelInterface return $kernel; } - /** - * @internal - */ + /** @internal */ private static function _shutdown(): void { if (!\is_subclass_of(static::class, KernelTestCase::class)) { // @phpstan-ignore function.alreadyNarrowedType @@ -100,4 +103,23 @@ private static function _shutdown(): void Configuration::shutdown(); static::ensureKernelShutdown(); } + + /** @internal */ + private static function _commonResetDatabaseBeforeEachTest(): void + { + if (FoundryExtension::isEnabled()) { + return; + } + + if (ResetDatabaseManager::canSkipSchemaReset()) { + // can fully skip booting the kernel + return; + } + + $kernel = static::_boot(); // @phpstan-ignore staticClassAccess.privateMethod + + ResetDatabaseManager::resetBeforeEachTest($kernel); + + static::_shutdown(); // @phpstan-ignore staticClassAccess.privateMethod + } } diff --git a/tests/Integration/DataProvider/DataProviderWithInMemoryTest.php b/tests/Integration/DataProvider/DataProviderWithInMemoryTest.php index 034edc801..31faa53d9 100644 --- a/tests/Integration/DataProvider/DataProviderWithInMemoryTest.php +++ b/tests/Integration/DataProvider/DataProviderWithInMemoryTest.php @@ -111,7 +111,7 @@ public static function provideContact(): iterable #[DataProvider('provideContactWithLegacyProxy')] #[AsInMemoryTest] #[RequiresMethod(\Symfony\Component\VarExporter\LazyProxyTrait::class, 'createLazyProxy')] - #[IgnoreDeprecations('(p|P)roxy')] + #[IgnoreDeprecations] public function it_can_create_in_memory_objects_in_data_provider_with_legacy_proxy(?Contact $contact = null): void { self::assertInstanceOf(Contact::class, $contact); diff --git a/tests/Integration/Faker/ResetFakerTestTrait.php b/tests/Integration/Faker/ResetFakerTestTrait.php index 472eb00f6..24e24e9e1 100644 --- a/tests/Integration/Faker/ResetFakerTestTrait.php +++ b/tests/Integration/Faker/ResetFakerTestTrait.php @@ -14,43 +14,50 @@ namespace Zenstruck\Foundry\Tests\Integration\Faker; use PHPUnit\Framework\Attributes\AfterClass; +use PHPUnit\Framework\Attributes\Before; use PHPUnit\Framework\Attributes\BeforeClass; use Zenstruck\Foundry\FakerAdapter; -trait ResetFakerTestTrait -{ - private static ?string $savedServerSeed = null; - private static ?string $savedEnvSeed = null; - private static ?string $savedGetEnvSeed = null; - - private static ?int $currentSeed = null; - - #[BeforeClass(10)] - public static function __saveAndResetFakerSeed(): void +if (\method_exists(Before::class, '__construct')) { // @phpstan-ignore function.alreadyNarrowedType + trait ResetFakerTestTrait { - self::$savedServerSeed = $_SERVER['FOUNDRY_FAKER_SEED'] ?? null; - self::$savedEnvSeed = $_ENV['FOUNDRY_FAKER_SEED'] ?? null; - self::$savedGetEnvSeed = \getenv('FOUNDRY_FAKER_SEED') ?: null; + private static ?string $savedServerSeed = null; + private static ?string $savedEnvSeed = null; + private static ?string $savedGetEnvSeed = null; - $_SERVER['FOUNDRY_FAKER_SEED'] = null; - $_ENV['FOUNDRY_FAKER_SEED'] = null; - \putenv('FOUNDRY_FAKER_SEED'); + private static ?int $currentSeed = null; - FakerAdapter::resetFakerSeed(); - } + #[BeforeClass(10)] + public static function __saveAndResetFakerSeed(): void + { + self::$savedServerSeed = $_SERVER['FOUNDRY_FAKER_SEED'] ?? null; + self::$savedEnvSeed = $_ENV['FOUNDRY_FAKER_SEED'] ?? null; + self::$savedGetEnvSeed = \getenv('FOUNDRY_FAKER_SEED') ?: null; - #[AfterClass(-10)] - public static function __restoreFakerSeed(): void - { - $_SERVER['FOUNDRY_FAKER_SEED'] = self::$savedServerSeed; - $_ENV['FOUNDRY_FAKER_SEED'] = self::$savedEnvSeed; - if (null === self::$savedGetEnvSeed) { + $_SERVER['FOUNDRY_FAKER_SEED'] = null; + $_ENV['FOUNDRY_FAKER_SEED'] = null; \putenv('FOUNDRY_FAKER_SEED'); - } else { - \putenv('FOUNDRY_FAKER_SEED='.self::$savedGetEnvSeed); + + FakerAdapter::resetFakerSeed(); } - $savedValue = self::$savedServerSeed ?? self::$savedEnvSeed ?? self::$savedGetEnvSeed; - FakerAdapter::resetFakerSeed($savedValue ? (int) $savedValue : null); + #[AfterClass(-10)] + public static function __restoreFakerSeed(): void + { + $_SERVER['FOUNDRY_FAKER_SEED'] = self::$savedServerSeed; + $_ENV['FOUNDRY_FAKER_SEED'] = self::$savedEnvSeed; + if (null === self::$savedGetEnvSeed) { + \putenv('FOUNDRY_FAKER_SEED'); + } else { + \putenv('FOUNDRY_FAKER_SEED='.self::$savedGetEnvSeed); + } + + $savedValue = self::$savedServerSeed ?? self::$savedEnvSeed ?? self::$savedGetEnvSeed; + FakerAdapter::resetFakerSeed($savedValue ? (int) $savedValue : null); + } + } +} else { + trait ResetFakerTestTrait + { } } diff --git a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseAttributeTest.php b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseAttributeTest.php index cb7525286..1cee8fd22 100644 --- a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseAttributeTest.php +++ b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseAttributeTest.php @@ -9,13 +9,12 @@ * file that was distributed with this source code. */ -namespace Integration\Persistence; +namespace Zenstruck\Foundry\Tests\Integration\Persistence; use PHPUnit\Framework\Attributes\RequiresPhpunit; use PHPUnit\Framework\Attributes\RequiresPhpunitExtension; use Zenstruck\Foundry\Attribute\ResetDatabase; use Zenstruck\Foundry\PHPUnit\FoundryExtension; -use Zenstruck\Foundry\Tests\Integration\Persistence\GenericFactoryUsingBeforeHooksTestCase; /** * @author Nicolas PHILIPPE @@ -26,4 +25,5 @@ #[ResetDatabase] final class GenericFactoryUsingBeforeHooksAndResetDatabaseAttributeTest extends GenericFactoryUsingBeforeHooksTestCase { + use GenericFactoryUsingBeforeHooksTrait; } diff --git a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest.php b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest.php index 382c30b74..92c589094 100644 --- a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest.php +++ b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest.php @@ -11,13 +11,16 @@ namespace Zenstruck\Foundry\Tests\Integration\Persistence; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; /** * @author Nicolas PHILIPPE + * @group legacy */ +#[IgnoreDeprecations] final class GenericFactoryUsingBeforeHooksAndResetDatabaseTraitTest extends GenericFactoryUsingBeforeHooksTestCase { - use Factories, ResetDatabase; + use GenericFactoryUsingBeforeHooksTrait, Factories, ResetDatabase; } diff --git a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTestCase.php b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTestCase.php index 72f8fc776..d845d5517 100644 --- a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTestCase.php +++ b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTestCase.php @@ -11,11 +11,8 @@ namespace Zenstruck\Foundry\Tests\Integration\Persistence; -use PHPUnit\Framework\Attributes\Before; use PHPUnit\Framework\Attributes\Test; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; -use Zenstruck\Foundry\Test\Factories; -use Zenstruck\Foundry\Test\ResetDatabase; use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory; use Zenstruck\Foundry\Tests\Integration\RequiresORM; @@ -24,27 +21,13 @@ */ abstract class GenericFactoryUsingBeforeHooksTestCase extends KernelTestCase { - use Factories, RequiresORM, ResetDatabase; + use RequiresORM; protected function setUp(): void { GenericEntityFactory::createOne(); } - /** @before */ - #[Before(1)] - public function beforeSetup(): void - { - $this->setUp(); - } - - /** @before */ - #[Before(-1)] - public function afterSetup(): void - { - $this->setUp(); - } - /** * @test */ diff --git a/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTrait.php b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTrait.php new file mode 100644 index 000000000..a24f73715 --- /dev/null +++ b/tests/Integration/Persistence/GenericFactoryUsingBeforeHooksTrait.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Zenstruck\Foundry\Tests\Integration\Persistence; + +use PHPUnit\Framework\Attributes\Before; + +if (!\method_exists(Before::class, '__construct')) { // @phpstan-ignore function.alreadyNarrowedType + trait GenericFactoryUsingBeforeHooksTrait + { + /** @before */ + #[Before] + public function beforeSetup(): void + { + $this->setUp(); + } + + /** @before */ + #[Before] + public function afterSetup(): void + { + $this->setUp(); + } + } +} else { + trait GenericFactoryUsingBeforeHooksTrait + { + #[Before(1)] + public function beforeSetup(): void + { + $this->setUp(); + } + + #[Before(-1)] + public function afterSetup(): void + { + $this->setUp(); + } + } +} diff --git a/tests/Integration/ResetDatabase/EarlyBootedKernelWithTraitsTest.php b/tests/Integration/ResetDatabase/EarlyBootedKernelWithTraitsTest.php index fa0981ccb..31e1fb150 100644 --- a/tests/Integration/ResetDatabase/EarlyBootedKernelWithTraitsTest.php +++ b/tests/Integration/ResetDatabase/EarlyBootedKernelWithTraitsTest.php @@ -17,7 +17,7 @@ use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; -#[IgnoreDeprecations('In order to use Foundry correctly, you must use the trait')] +#[IgnoreDeprecations()] final class EarlyBootedKernelWithTraitsTest extends EarlyBootedKernelTestCase { use Factories, ResetDatabase; diff --git a/tests/Integration/ResetDatabase/GlobalStoryWithTraitsTest.php b/tests/Integration/ResetDatabase/GlobalStoryWithTraitsTest.php index 6ca06984a..3bdf71524 100644 --- a/tests/Integration/ResetDatabase/GlobalStoryWithTraitsTest.php +++ b/tests/Integration/ResetDatabase/GlobalStoryWithTraitsTest.php @@ -17,7 +17,7 @@ use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; -#[IgnoreDeprecations('In order to use Foundry correctly, you must use the trait')] +#[IgnoreDeprecations()] final class GlobalStoryWithTraitsTest extends GlobalStoryTestCase { use Factories, ResetDatabase; diff --git a/tests/Integration/ResetDatabase/OrmEdgeCaseWithTraitsTest.php b/tests/Integration/ResetDatabase/OrmEdgeCaseWithTraitsTest.php index caf79e8e2..a87a03dd9 100644 --- a/tests/Integration/ResetDatabase/OrmEdgeCaseWithTraitsTest.php +++ b/tests/Integration/ResetDatabase/OrmEdgeCaseWithTraitsTest.php @@ -17,7 +17,7 @@ use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; -#[IgnoreDeprecations('In order to use Foundry correctly, you must use the trait')] +#[IgnoreDeprecations()] final class OrmEdgeCaseWithTraitsTest extends OrmEdgeCaseTestCase { use Factories, ResetDatabase; diff --git a/tests/Integration/ResetDatabase/ResetDatabaseWithTraitsTest.php b/tests/Integration/ResetDatabase/ResetDatabaseWithTraitsTest.php index 3da9239c3..137ec0128 100644 --- a/tests/Integration/ResetDatabase/ResetDatabaseWithTraitsTest.php +++ b/tests/Integration/ResetDatabase/ResetDatabaseWithTraitsTest.php @@ -22,7 +22,7 @@ /** * @author Nicolas PHILIPPE */ -#[IgnoreDeprecations('In order to use Foundry correctly, you must use the trait')] +#[IgnoreDeprecations()] final class ResetDatabaseWithTraitsTest extends ResetDatabaseTestCase { use Factories, ResetDatabase;