From bdbf06dc89c139ff6d6b9b53a8c15f86580b8551 Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Tue, 4 Feb 2025 18:44:32 +0100 Subject: [PATCH 1/3] feat(faker): deprecate faker.seed config --- src/ZenstruckFoundryBundle.php | 1 + tests/Fixture/config/legacy_faker_seed.yaml | 3 ++ tests/Integration/BundleTest.php | 32 +++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 tests/Fixture/config/legacy_faker_seed.yaml create mode 100644 tests/Integration/BundleTest.php diff --git a/src/ZenstruckFoundryBundle.php b/src/ZenstruckFoundryBundle.php index 3036897c..ca646d6f 100644 --- a/src/ZenstruckFoundryBundle.php +++ b/src/ZenstruckFoundryBundle.php @@ -61,6 +61,7 @@ public function configure(DefinitionConfigurator $definition): void ->defaultNull() ->end() ->scalarNode('seed') + ->setDeprecated('zenstruck/foundry', '2.4', 'The "faker.seed" configuration is deprecated and will be removed in 3.0.') ->info('Random number generator seed to produce the same fake values every run.') ->example(1234) ->defaultNull() diff --git a/tests/Fixture/config/legacy_faker_seed.yaml b/tests/Fixture/config/legacy_faker_seed.yaml new file mode 100644 index 00000000..a2d3950b --- /dev/null +++ b/tests/Fixture/config/legacy_faker_seed.yaml @@ -0,0 +1,3 @@ +zenstruck_foundry: + faker: + seed: 1234 diff --git a/tests/Integration/BundleTest.php b/tests/Integration/BundleTest.php new file mode 100644 index 00000000..8ee44720 --- /dev/null +++ b/tests/Integration/BundleTest.php @@ -0,0 +1,32 @@ +=11.0')] + #[IgnoreDeprecations] + public function test_faker_seed_by_configuration_is_deprecated(): void + { + self::expectUserDeprecationMessageMatches( + '/The "faker.seed" configuration is deprecated and will be removed in 3.0/' + ); + + self::bootKernel(['environment' => 'legacy_faker_seed']); + + self::assertSame('Baileyshire', AddressFactory::createOne()->getCity()); + } +} From 85231a9540b675e7466ea0018ccf2405dc9bdabe Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Wed, 5 Feb 2025 13:47:52 +0100 Subject: [PATCH 2/3] feat(faker): load faker seed from env var --- bin/console | 10 +++- config/services.php | 1 + src/Configuration.php | 15 ++++++ src/Test/UnitTestConfig.php | 1 + src/ZenstruckFoundryBundle.php | 6 +-- tests/Fixture/config/faker_seed_env_var.yaml | 2 + ...eed.yaml => faker_seed_legacy_config.yaml} | 0 tests/Integration/BundleTest.php | 32 ------------ .../FakerSeedAutomaticallySetKernelTest.php | 38 ++++++++++++++ .../FakerSeedAutomaticallySetUnitTest.php | 37 ++++++++++++++ .../FakerSeedSetFromEnvVarKernelTest.php | 44 ++++++++++++++++ .../Faker/FakerSeedSetFromEnvVarUnitTest.php | 51 +++++++++++++++++++ ...FakerSeedSetFromLegacyConfigKernelTest.php | 50 ++++++++++++++++++ tests/Integration/Faker/FakerTestTrait.php | 31 +++++++++++ 14 files changed, 281 insertions(+), 37 deletions(-) create mode 100644 tests/Fixture/config/faker_seed_env_var.yaml rename tests/Fixture/config/{legacy_faker_seed.yaml => faker_seed_legacy_config.yaml} (100%) delete mode 100644 tests/Integration/BundleTest.php create mode 100644 tests/Integration/Faker/FakerSeedAutomaticallySetKernelTest.php create mode 100644 tests/Integration/Faker/FakerSeedAutomaticallySetUnitTest.php create mode 100644 tests/Integration/Faker/FakerSeedSetFromEnvVarKernelTest.php create mode 100644 tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php create mode 100644 tests/Integration/Faker/FakerSeedSetFromLegacyConfigKernelTest.php create mode 100644 tests/Integration/Faker/FakerTestTrait.php diff --git a/bin/console b/bin/console index 9ff51b3b..3bd74f04 100755 --- a/bin/console +++ b/bin/console @@ -6,5 +6,13 @@ use Zenstruck\Foundry\Tests\Fixture\TestKernel; require_once __DIR__ . '/../tests/bootstrap.php'; -$application = new Application(new TestKernel('test', true)); +foreach ($argv ?? [] as $i => $arg) { + if (($arg === '--env' || $arg === '-e') && isset($argv[$i + 1])) { + $_ENV['APP_ENV'] = $argv[$i + 1]; + break; + } +} + +$application = new Application(new TestKernel($_ENV['APP_ENV'], true)); + $application->run(); diff --git a/config/services.php b/config/services.php index 94b92aa0..3f5d59d7 100644 --- a/config/services.php +++ b/config/services.php @@ -33,6 +33,7 @@ service('.zenstruck_foundry.story_registry'), service('.zenstruck_foundry.persistence_manager')->nullOnInvalid(), service('event_dispatcher'), + '%env(default:zenstruck_foundry.faker.seed:int:FOUNDRY_FAKER_SEED)%', ]) ->public() ; diff --git a/src/Configuration.php b/src/Configuration.php index 3bf88028..b9daeed5 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -43,6 +43,8 @@ final class Configuration /** @var \Closure():self|self|null */ private static \Closure|self|null $instance = null; + private static int|null $fakerSeed = null; + /** * @phpstan-param InstantiatorCallable $instantiator */ @@ -53,10 +55,23 @@ public function __construct( public readonly StoryRegistry $stories, private readonly ?PersistenceManager $persistence = null, private readonly ?EventDispatcherInterface $eventDispatcher = null, + int|null $forcedFakerSeed = null, ) { + $this->faker->seed(self::fakerSeed($forcedFakerSeed)); + $this->instantiator = $instantiator; } + public static function fakerSeed(int|null $forcedFakerSeed = null): int + { + return self::$fakerSeed ??= ($forcedFakerSeed ?? random_int(0, 1000000)); + } + + public static function resetFakerSeed(): void + { + self::$fakerSeed = null; + } + /** * @throws PersistenceNotAvailable */ diff --git a/src/Test/UnitTestConfig.php b/src/Test/UnitTestConfig.php index 145a7302..8b1c1a05 100644 --- a/src/Test/UnitTestConfig.php +++ b/src/Test/UnitTestConfig.php @@ -51,6 +51,7 @@ public static function build(): Configuration $faker, self::$instantiator ?? Instantiator::withConstructor(), new StoryRegistry([]), + forcedFakerSeed: $_SERVER['FOUNDRY_FAKER_SEED'] ?? $_ENV['FOUNDRY_FAKER_SEED'] ?? (getenv('FOUNDRY_FAKER_SEED') ?: null) ); } } diff --git a/src/ZenstruckFoundryBundle.php b/src/ZenstruckFoundryBundle.php index ca646d6f..247d7b05 100644 --- a/src/ZenstruckFoundryBundle.php +++ b/src/ZenstruckFoundryBundle.php @@ -61,7 +61,7 @@ public function configure(DefinitionConfigurator $definition): void ->defaultNull() ->end() ->scalarNode('seed') - ->setDeprecated('zenstruck/foundry', '2.4', 'The "faker.seed" configuration is deprecated and will be removed in 3.0.') + ->setDeprecated('zenstruck/foundry', '2.4', 'The "faker.seed" configuration is deprecated and will be removed in 3.0. Use environment variable "FOUNDRY_FAKER_SEED" instead.') ->info('Random number generator seed to produce the same fake values every run.') ->example(1234) ->defaultNull() @@ -405,8 +405,6 @@ private function configureFaker(array $config, ContainerBuilder $container): voi $definition->addArgument($config['locale']); } - if ($config['seed']) { - $definition->addMethodCall('seed', [$config['seed']]); - } + $container->setParameter('zenstruck_foundry.faker.seed', $config['seed']); } } diff --git a/tests/Fixture/config/faker_seed_env_var.yaml b/tests/Fixture/config/faker_seed_env_var.yaml new file mode 100644 index 00000000..4f91fccd --- /dev/null +++ b/tests/Fixture/config/faker_seed_env_var.yaml @@ -0,0 +1,2 @@ +parameters: + env(FOUNDRY_FAKER_SEED): 1234 diff --git a/tests/Fixture/config/legacy_faker_seed.yaml b/tests/Fixture/config/faker_seed_legacy_config.yaml similarity index 100% rename from tests/Fixture/config/legacy_faker_seed.yaml rename to tests/Fixture/config/faker_seed_legacy_config.yaml diff --git a/tests/Integration/BundleTest.php b/tests/Integration/BundleTest.php deleted file mode 100644 index 8ee44720..00000000 --- a/tests/Integration/BundleTest.php +++ /dev/null @@ -1,32 +0,0 @@ -=11.0')] - #[IgnoreDeprecations] - public function test_faker_seed_by_configuration_is_deprecated(): void - { - self::expectUserDeprecationMessageMatches( - '/The "faker.seed" configuration is deprecated and will be removed in 3.0/' - ); - - self::bootKernel(['environment' => 'legacy_faker_seed']); - - self::assertSame('Baileyshire', AddressFactory::createOne()->getCity()); - } -} diff --git a/tests/Integration/Faker/FakerSeedAutomaticallySetKernelTest.php b/tests/Integration/Faker/FakerSeedAutomaticallySetKernelTest.php new file mode 100644 index 00000000..cc0f95a1 --- /dev/null +++ b/tests/Integration/Faker/FakerSeedAutomaticallySetKernelTest.php @@ -0,0 +1,38 @@ + + * @requires PHPUnit >=11.0 + */ +#[RequiresPhpunit('>=11.0')] +final class FakerSeedAutomaticallySetKernelTest extends KernelTestCase +{ + use Factories, ResetDatabase, FakerTestTrait; + + #[Test] + public function faker_seed_does_not_change(): void + { + self::$currentSeed = Configuration::fakerSeed(); + + self::assertSame(self::$currentSeed, Configuration::fakerSeed()); + } + + #[Test] + #[Depends('faker_seed_does_not_change')] + public function faker_seed_does_not_change_between_tests(): void + { + self::assertSame(self::$currentSeed, Configuration::fakerSeed()); + } +} diff --git a/tests/Integration/Faker/FakerSeedAutomaticallySetUnitTest.php b/tests/Integration/Faker/FakerSeedAutomaticallySetUnitTest.php new file mode 100644 index 00000000..1e926c78 --- /dev/null +++ b/tests/Integration/Faker/FakerSeedAutomaticallySetUnitTest.php @@ -0,0 +1,37 @@ + + * @requires PHPUnit >=11.0 + */ +#[RequiresPhpunit('>=11.0')] +final class FakerSeedAutomaticallySetUnitTest extends TestCase +{ + use Factories, FakerTestTrait; + + #[Test] + public function faker_seed_does_not_change(): void + { + self::$currentSeed = Configuration::fakerSeed(); + + self::assertSame(self::$currentSeed, Configuration::fakerSeed()); + } + + #[Test] + #[Depends('faker_seed_does_not_change')] + public function faker_seed_does_not_change_between_tests(): void + { + self::assertSame(self::$currentSeed, Configuration::fakerSeed()); + } +} diff --git a/tests/Integration/Faker/FakerSeedSetFromEnvVarKernelTest.php b/tests/Integration/Faker/FakerSeedSetFromEnvVarKernelTest.php new file mode 100644 index 00000000..cb2ad826 --- /dev/null +++ b/tests/Integration/Faker/FakerSeedSetFromEnvVarKernelTest.php @@ -0,0 +1,44 @@ + + * @requires PHPUnit >=11.0 + */ +#[RequiresPhpunit('>=11.0')] +final class FakerSeedSetFromEnvVarKernelTest extends KernelTestCase +{ + use Factories, ResetDatabase, FakerTestTrait; + + #[Test] + public function faker_seed_can_be_set_by_environment_variable(): void + { + // let's fake, we're starting from a fresh kernel + $this->tearDown(); + Configuration::shutdown(); + Configuration::resetFakerSeed(); + + self::bootKernel(['environment' => 'faker_seed_env_var']); + + self::assertSame(1234, Configuration::fakerSeed()); + } + + #[Test] + #[Depends('faker_seed_can_be_set_by_environment_variable')] + public function faker_seed_is_already_set(): void + { + self::assertSame(1234, Configuration::fakerSeed()); + } +} diff --git a/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php b/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php new file mode 100644 index 00000000..456c3bbd --- /dev/null +++ b/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php @@ -0,0 +1,51 @@ + + * @requires PHPUnit >=11.0 + */ +#[RequiresPhpunit('>=11.0')] +final class FakerSeedSetFromEnvVarUnitTest extends TestCase +{ + use Factories, FakerTestTrait; + + #[Before(10)] + public static function __setEnv(): void + { + $_ENV['FOUNDRY_FAKER_SEED'] = $_SERVER['FOUNDRY_FAKER_SEED'] = '1234'; + } + + #[Test] + public function faker_seed_is_set_from_env_var(): void + { + self::assertSame(1234, Configuration::fakerSeed()); + } + + #[Test] + #[Depends('faker_seed_is_set_from_env_var')] + public function faker_seed_does_not_change(): void + { + self::assertSame(1234, Configuration::fakerSeed()); + } + + #[AfterClass(-9)] // @phpstan-ignore argument.type (negative priority should be allowed) + public static function __resetFakerSeedEnv(): void + { + unset($_ENV['FOUNDRY_FAKER_SEED'], $_SERVER['FOUNDRY_FAKER_SEED']); + } +} diff --git a/tests/Integration/Faker/FakerSeedSetFromLegacyConfigKernelTest.php b/tests/Integration/Faker/FakerSeedSetFromLegacyConfigKernelTest.php new file mode 100644 index 00000000..91c9c80e --- /dev/null +++ b/tests/Integration/Faker/FakerSeedSetFromLegacyConfigKernelTest.php @@ -0,0 +1,50 @@ + + * @requires PHPUnit >=11.0 + */ +#[RequiresPhpunit('>=11.0')] +final class FakerSeedSetFromLegacyConfigKernelTest extends KernelTestCase +{ + use Factories, ResetDatabase, FakerTestTrait; + + #[Test] + #[IgnoreDeprecations] + public function test_faker_seed_by_configuration_is_deprecated(): void + { + // let's fake, we're starting from a fresh kernel + $this->tearDown(); + Configuration::shutdown(); + Configuration::resetFakerSeed(); + + self::bootKernel(['environment' => 'faker_seed_legacy_config']); + + self::expectUserDeprecationMessageMatches( + '/The "faker.seed" configuration is deprecated and will be removed in 3.0/' + ); + + self::assertSame(1234, Configuration::fakerSeed()); + } + + #[Test] + #[Depends('test_faker_seed_by_configuration_is_deprecated')] + public function faker_seed_is_already_set(): void + { + self::assertSame(1234, Configuration::fakerSeed()); + } +} diff --git a/tests/Integration/Faker/FakerTestTrait.php b/tests/Integration/Faker/FakerTestTrait.php new file mode 100644 index 00000000..adfc83e0 --- /dev/null +++ b/tests/Integration/Faker/FakerTestTrait.php @@ -0,0 +1,31 @@ + Date: Wed, 5 Feb 2025 19:04:32 +0100 Subject: [PATCH 3/3] feat(faker): display faker seed after test finished --- .../DisplayFakerSeedOnTestSuiteFinished.php | 17 +++++++++++++++++ src/PHPUnit/FoundryExtension.php | 2 +- .../Faker/FakerSeedSetFromEnvVarUnitTest.php | 4 +--- tests/Integration/Faker/FakerTestTrait.php | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 src/PHPUnit/DisplayFakerSeedOnTestSuiteFinished.php diff --git a/src/PHPUnit/DisplayFakerSeedOnTestSuiteFinished.php b/src/PHPUnit/DisplayFakerSeedOnTestSuiteFinished.php new file mode 100644 index 00000000..d4658c6f --- /dev/null +++ b/src/PHPUnit/DisplayFakerSeedOnTestSuiteFinished.php @@ -0,0 +1,17 @@ +=11.4')->isSatisfiedBy(Runner\Version::id())) { // those deal with data provider events which can be useful only if PHPUnit >=11.4 is used diff --git a/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php b/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php index 456c3bbd..4999dda9 100644 --- a/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php +++ b/tests/Integration/Faker/FakerSeedSetFromEnvVarUnitTest.php @@ -6,14 +6,12 @@ use PHPUnit\Framework\Attributes\AfterClass; use PHPUnit\Framework\Attributes\Before; -use PHPUnit\Framework\Attributes\BeforeClass; use PHPUnit\Framework\Attributes\Depends; use PHPUnit\Framework\Attributes\RequiresPhpunit; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Zenstruck\Foundry\Configuration; use Zenstruck\Foundry\Test\Factories; -use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\Address\AddressFactory; /** * @author Nicolas PHILIPPE @@ -43,7 +41,7 @@ public function faker_seed_does_not_change(): void self::assertSame(1234, Configuration::fakerSeed()); } - #[AfterClass(-9)] // @phpstan-ignore argument.type (negative priority should be allowed) + #[AfterClass(-9)] public static function __resetFakerSeedEnv(): void { unset($_ENV['FOUNDRY_FAKER_SEED'], $_SERVER['FOUNDRY_FAKER_SEED']); diff --git a/tests/Integration/Faker/FakerTestTrait.php b/tests/Integration/Faker/FakerTestTrait.php index adfc83e0..1cdf4a6a 100644 --- a/tests/Integration/Faker/FakerTestTrait.php +++ b/tests/Integration/Faker/FakerTestTrait.php @@ -22,7 +22,7 @@ public static function __saveAndResetFakerSeed(): void Configuration::resetFakerSeed(); } - #[AfterClass(-10)] // @phpstan-ignore argument.type (negative priority should be allowed) + #[AfterClass(-10)] public static function __restoreSeed(): void { Configuration::resetFakerSeed();