From 3cd6e8954280a715937ad6fcf415348127dededb Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Tue, 9 Jan 2024 13:55:21 +0100 Subject: [PATCH 1/2] refactor: deprecate Factory::faker() outisde of a factory --- src/Factory.php | 7 ++ src/functions.php | 2 +- tests/Functional/FakerTest.php | 5 +- tests/Unit/FactoryTest.php | 5 +- utils/rector/.phpunit.result.cache | 2 +- utils/rector/config/foundry-set.php | 2 + .../src/ChangeStaticFactoryFakerCalls.php | 74 +++++++++++++++++++ .../AllRules/Fixtures/object-factory.php.inc | 4 +- .../tests/AllRules/Fixtures/test-case.php.inc | 5 ++ .../ChangeStaticFactoryFakerCallsTest.php | 28 +++++++ ...-function-when-in-kernel-test-case.php.inc | 41 ++++++++++ .../Fixtures/skip-calls-from-factory.php.inc | 24 ++++++ .../ChangeStaticFactoryFakerCalls/config.php | 10 +++ 13 files changed, 201 insertions(+), 8 deletions(-) create mode 100644 utils/rector/src/ChangeStaticFactoryFakerCalls.php create mode 100644 utils/rector/tests/ChangeStaticFactoryFakerCalls/ChangeStaticFactoryFakerCallsTest.php create mode 100644 utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/change-legacy-function-when-in-kernel-test-case.php.inc create mode 100644 utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/skip-calls-from-factory.php.inc create mode 100644 utils/rector/tests/ChangeStaticFactoryFakerCalls/config.php diff --git a/src/Factory.php b/src/Factory.php index 6790ec68a..db265045a 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -354,6 +354,13 @@ final public static function isBooted(): bool final public static function faker(): Faker\Generator { + if ( + null === ($calledClass = \debug_backtrace(options: \DEBUG_BACKTRACE_IGNORE_ARGS, limit: 2)[1]['class'] ?? null) + || !is_a($calledClass, self::class, allow_string: true) + ) { + trigger_deprecation('zenstruck\foundry', '1.37.0', 'Method "%s()" will be protected in Foundry 2.0 and should not be called from outside of a factory. Use function "Zenstruck\Foundry\faker()" instead.', __METHOD__); + } + try { return self::configuration()->faker(); } catch (FoundryBootException) { diff --git a/src/functions.php b/src/functions.php index 990d433a4..1ab9584b5 100644 --- a/src/functions.php +++ b/src/functions.php @@ -168,7 +168,7 @@ function repository(object|string $objectOrClass): RepositoryDecorator */ function faker(): Faker\Generator { - return Factory::faker(); + return Factory::configuration()->faker(); } /** diff --git a/tests/Functional/FakerTest.php b/tests/Functional/FakerTest.php index 515a01eaf..f1687cd3a 100644 --- a/tests/Functional/FakerTest.php +++ b/tests/Functional/FakerTest.php @@ -12,9 +12,10 @@ namespace Zenstruck\Foundry\Tests\Functional; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; -use Zenstruck\Foundry\Factory; use Zenstruck\Foundry\Test\Factories; +use function Zenstruck\Foundry\faker; + /** * @author Kevin Bond */ @@ -34,6 +35,6 @@ protected function setUp(): void */ public function can_use_custom_provider(): void { - $this->assertSame('custom-value', Factory::faker()->customValue()); + $this->assertSame('custom-value', faker()->customValue()); } } diff --git a/tests/Unit/FactoryTest.php b/tests/Unit/FactoryTest.php index 4db7dabdb..0e588fad0 100644 --- a/tests/Unit/FactoryTest.php +++ b/tests/Unit/FactoryTest.php @@ -25,6 +25,7 @@ use Zenstruck\Foundry\Tests\Fixtures\Entity\Post; use Zenstruck\Foundry\Tests\Fixtures\Factories\LegacyPostFactory; +use function Zenstruck\Foundry\faker; use function Zenstruck\Foundry\lazy; use function Zenstruck\Foundry\Persistence\persistent_factory; use function Zenstruck\Foundry\Persistence\proxy_factory; @@ -260,10 +261,10 @@ public function can_add_after_instantiate_events(): void */ public function can_register_custom_faker(): void { - $defaultFaker = Factory::faker(); + $defaultFaker = faker(); Factory::configuration()->setFaker(Faker\Factory::create()); - $this->assertNotSame(\spl_object_id(Factory::faker()), \spl_object_id($defaultFaker)); + $this->assertNotSame(\spl_object_id(faker()), \spl_object_id($defaultFaker)); } /** diff --git a/utils/rector/.phpunit.result.cache b/utils/rector/.phpunit.result.cache index 249ebc1df..f5a2ec044 100644 --- a/utils/rector/.phpunit.result.cache +++ b/utils/rector/.phpunit.result.cache @@ -1 +1 @@ -{"version":1,"defects":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":7},"times":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#0":0.288,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#1":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#0":0.015,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#1":0.02,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":0.027,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":0.021,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":0.02,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":0.016,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":0.056,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":0.054,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#0":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#1":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#2":0.011,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeLegacyClassImportsTest::test#0":0.005,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#0":0.014,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#1":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":0.47,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":0.136,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":2.79,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":0.016,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":0.016,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":0.048,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":0.041}} \ No newline at end of file +{"version":1,"defects":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#1":8},"times":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#0":0.268,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#1":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#0":0.016,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#1":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":0.021,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":0.015,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":0.057,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":0.053,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#0":0.02,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#1":0.019,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#2":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeLegacyClassImportsTest::test#0":0.005,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#0":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#1":0.011,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":0.551,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":0.152,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":0.968,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":0.053,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":0.071,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#0":0.024,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#1":0.021}} \ No newline at end of file diff --git a/utils/rector/config/foundry-set.php b/utils/rector/config/foundry-set.php index 0ab7a5bf4..733c32749 100644 --- a/utils/rector/config/foundry-set.php +++ b/utils/rector/config/foundry-set.php @@ -11,6 +11,7 @@ use Zenstruck\Foundry\Utils\Rector\ChangeInstantiatorMethodCalls; use Zenstruck\Foundry\Utils\Rector\ChangeLegacyClassImports; use Zenstruck\Foundry\Utils\Rector\ChangeProxyMethodCalls; +use Zenstruck\Foundry\Utils\Rector\ChangeStaticFactoryFakerCalls; use Zenstruck\Foundry\Utils\Rector\PersistenceResolver; use Zenstruck\Foundry\Utils\Rector\RemoveProxyRealObjectMethodCallsForNotProxifiedObjects; use Zenstruck\Foundry\Utils\Rector\RuleRequirementsChecker; @@ -34,5 +35,6 @@ ChangeFactoryMethodCalls::class, ChangeFunctionsCalls::class, ChangeProxyMethodCalls::class, + ChangeStaticFactoryFakerCalls::class, ]); }; diff --git a/utils/rector/src/ChangeStaticFactoryFakerCalls.php b/utils/rector/src/ChangeStaticFactoryFakerCalls.php new file mode 100644 index 000000000..64cc2e689 --- /dev/null +++ b/utils/rector/src/ChangeStaticFactoryFakerCalls.php @@ -0,0 +1,74 @@ +> + */ + public function getNodeTypes(): array + { + return [Node\Expr\StaticCall::class]; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Change Factory::faker() calls, outside from a factory (method is not protected.', + [ + new CodeSample( + <<<'CODE_SAMPLE' + // not in a factory class + Factory::faker(); + CODE_SAMPLE, + <<<'CODE_SAMPLE' + // not in a factory class + \Zenstruck\Foundry\faker(); + CODE_SAMPLE + ), + ] + ); + } + + /** + * @param Node\Expr\StaticCall $node + */ + public function refactor(Node $node): Node|int|null + { + // if method name is not faker, then do nothing + if ((string)$node->name !== 'faker') { + return null; + } + + // if method is not called on a Factory class, then do nothing + if ( + !$node->class instanceof Node\Name + || !is_a((string)$node->class, Factory::class, allow_string: true) + ) { + return null; + } + + /** @var MutatingScope */ + $mutatingScope = $node->getAttribute('scope'); + + // if the Factory::faker() was called from a Factory, then do nothing + if ( + null !== ($classReflection = $mutatingScope->getClassReflection()) + && is_a($classReflection->getName(), Factory::class, allow_string: true) + ) { + return null; + } + + return new Node\Expr\FuncCall(new Node\Name('\Zenstruck\Foundry\faker')); + } +} diff --git a/utils/rector/tests/AllRules/Fixtures/object-factory.php.inc b/utils/rector/tests/AllRules/Fixtures/object-factory.php.inc index f54d780a6..90bb68be3 100644 --- a/utils/rector/tests/AllRules/Fixtures/object-factory.php.inc +++ b/utils/rector/tests/AllRules/Fixtures/object-factory.php.inc @@ -19,7 +19,7 @@ final class DummyObjectModelFactory extends ModelFactory { protected function getDefaults(): array { - return []; + return ['field' => self::faker()]; } public function published(): static @@ -62,7 +62,7 @@ final class DummyObjectModelFactory extends \Zenstruck\Foundry\ObjectFactory { protected function defaults(): array { - return []; + return ['field' => self::faker()]; } public function published(): static diff --git a/utils/rector/tests/AllRules/Fixtures/test-case.php.inc b/utils/rector/tests/AllRules/Fixtures/test-case.php.inc index 0eb34e804..f3d830c70 100644 --- a/utils/rector/tests/AllRules/Fixtures/test-case.php.inc +++ b/utils/rector/tests/AllRules/Fixtures/test-case.php.inc @@ -3,6 +3,7 @@ namespace Zenstruck\Foundry\Utils\Rector\Tests\Fixtures; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Zenstruck\Foundry\Factory; use Zenstruck\Foundry\Proxy; use Zenstruck\Foundry\Utils\Rector\Tests\Fixtures\DummyObject; use Zenstruck\Foundry\Utils\Rector\Tests\Fixtures\DummyPersistentObject; @@ -40,6 +41,8 @@ class DummyKernelTestCase extends KernelTestCase \Zenstruck\Foundry\Factory::delayFlush(static fn() => true); \Zenstruck\Foundry\Test\TestState::configure(faker: null); + + Factory::faker(); } } @@ -87,6 +90,8 @@ class DummyKernelTestCase extends KernelTestCase \Zenstruck\Foundry\Persistence\flush_after(static fn() => true); \Zenstruck\Foundry\Test\UnitTestConfig::configure(faker: null); + + \Zenstruck\Foundry\faker(); } } diff --git a/utils/rector/tests/ChangeStaticFactoryFakerCalls/ChangeStaticFactoryFakerCallsTest.php b/utils/rector/tests/ChangeStaticFactoryFakerCalls/ChangeStaticFactoryFakerCallsTest.php new file mode 100644 index 000000000..a4e4c64b8 --- /dev/null +++ b/utils/rector/tests/ChangeStaticFactoryFakerCalls/ChangeStaticFactoryFakerCallsTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): \Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixtures'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config.php'; + } +} diff --git a/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/change-legacy-function-when-in-kernel-test-case.php.inc b/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/change-legacy-function-when-in-kernel-test-case.php.inc new file mode 100644 index 000000000..f8fb1057d --- /dev/null +++ b/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/change-legacy-function-when-in-kernel-test-case.php.inc @@ -0,0 +1,41 @@ + +----- + diff --git a/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/skip-calls-from-factory.php.inc b/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/skip-calls-from-factory.php.inc new file mode 100644 index 000000000..f4261fedd --- /dev/null +++ b/utils/rector/tests/ChangeStaticFactoryFakerCalls/Fixtures/skip-calls-from-factory.php.inc @@ -0,0 +1,24 @@ + self::faker(), + 'field2' => Factory::faker() + ]; + } + + protected static function getClass(): string + { + return DummyObject::class; + } +} diff --git a/utils/rector/tests/ChangeStaticFactoryFakerCalls/config.php b/utils/rector/tests/ChangeStaticFactoryFakerCalls/config.php new file mode 100644 index 000000000..550cb1211 --- /dev/null +++ b/utils/rector/tests/ChangeStaticFactoryFakerCalls/config.php @@ -0,0 +1,10 @@ +rule(ChangeStaticFactoryFakerCalls::class); +}; From fcd23bb46a11543f9d7d71c9196440195debbcd8 Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Tue, 9 Jan 2024 14:15:11 +0100 Subject: [PATCH 2/2] refactor: deprecate FactoryCollection::set() --- .gitignore | 1 + phpstan-baseline.neon | 2 +- src/Factory.php | 2 +- src/FactoryCollection.php | 10 ++++++ src/Object/Instantiator.php | 32 ++++++++++++++++--- src/Proxy.php | 6 ++-- tests/Unit/FactoryCollectionTest.php | 2 +- tests/Unit/InstantiatorTest.php | 5 +-- utils/rector/.phpunit.result.cache | 1 - utils/rector/config/foundry-set.php | 13 ++++++++ .../src/ChangeStaticFactoryFakerCalls.php | 2 +- .../tests/AllRules/Fixtures/test-case.php.inc | 4 +++ 12 files changed, 66 insertions(+), 14 deletions(-) delete mode 100644 utils/rector/.phpunit.result.cache diff --git a/.gitignore b/.gitignore index ff18046be..edcde177f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ /.env.local /docker-compose.override.yaml /tests/Fixtures/Migrations/ + /utils/rector/vendor /utils/rector/.phpunit.result.cache /utils/rector/composer.lock diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e5739f3a8..bbd33cdbc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -17,7 +17,7 @@ parameters: - message: "#^Should not use function \"debug_backtrace\", please change the code\\.$#" - count: 1 + count: 2 path: src/Factory.php - diff --git a/src/Factory.php b/src/Factory.php index db265045a..bf4431d6c 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -190,7 +190,7 @@ public function create( final public function many(int $min, ?int $max = null): FactoryCollection { if (!$max) { - return FactoryCollection::set($this, $min); + return FactoryCollection::many($this, $min); } return FactoryCollection::range($this, $min, $max); diff --git a/src/FactoryCollection.php b/src/FactoryCollection.php index 133e0274d..0fe2ab6fb 100644 --- a/src/FactoryCollection.php +++ b/src/FactoryCollection.php @@ -46,7 +46,17 @@ public function __construct(private Factory $factory, ?int $min = null, ?int $ma $this->max = $max ?? $min; } + /** + * @deprecated Use FactoryCollection::many() instead + */ public static function set(Factory $factory, int $count): self + { + trigger_deprecation('zenstruck/foundry', '1.37.0', 'Method %s() is deprecated and will be removed in 2.0. Use "%s::many()" instead.', __METHOD__, __CLASS__); + + return self::many($factory, $count); + } + + public static function many(Factory $factory, int $count): self { return new self($factory, $count, null, null, true); } diff --git a/src/Object/Instantiator.php b/src/Object/Instantiator.php index fca621c67..6d73c93cc 100644 --- a/src/Object/Instantiator.php +++ b/src/Object/Instantiator.php @@ -67,7 +67,7 @@ public function __invoke(array $attributes, string $class): object if ($this->alwaysForceProperties || \in_array($attribute, $this->forceProperties, true)) { try { - self::forceSet($object, $attribute, $value); + self::forceSet($object, $attribute, $value, calledInternally: true); } catch (\InvalidArgumentException $e) { if (!$this->allowExtraAttributes) { throw $e; @@ -80,7 +80,7 @@ public function __invoke(array $attributes, string $class): object if (0 === \mb_strpos($attribute, 'force:')) { trigger_deprecation('zenstruck\foundry', '1.5.0', 'Using "force:" property prefixes is deprecated, use Instantiator::alwaysForce() instead (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#instantiation).'); - self::forceSet($object, \mb_substr($attribute, 6), $value); + self::forceSet($object, \mb_substr($attribute, 6), $value, calledInternally: true); continue; } @@ -195,18 +195,42 @@ public function alwaysForce(string ...$properties): self } /** + * @deprecated * @throws \InvalidArgumentException if property does not exist for $object */ - public static function forceSet(object $object, string $property, mixed $value): void + public static function forceSet( + object $object, + string $property, + mixed $value, + /** + * @internal + */ + bool $calledInternally = false): void { + if (!$calledInternally) { + trigger_deprecation('zenstruck\foundry', '1.37.0', 'Method "%s()" is deprecated with no replacement.', __METHOD__); + } + self::accessibleProperty($object, $property)->setValue($object, $value); } /** + * @deprecated * @return mixed */ - public static function forceGet(object $object, string $property) + public static function forceGet( + object $object, + string $property, + /** + * @internal + */ + bool $calledInternally = false + ) { + if (!$calledInternally) { + trigger_deprecation('zenstruck\foundry', '1.37.0', 'Method "%s()" is deprecated with no replacement.', __METHOD__); + } + return self::accessibleProperty($object, $property)->getValue($object); } diff --git a/src/Proxy.php b/src/Proxy.php index 607c235ec..dc288291e 100644 --- a/src/Proxy.php +++ b/src/Proxy.php @@ -256,7 +256,7 @@ public function _set(string $property, mixed $value): static { $object = $this->_real(); - Instantiator::forceSet($object, $property, $value); + Instantiator::forceSet($object, $property, $value, calledInternally: true); return $this; } @@ -271,7 +271,7 @@ public function forceSetAll(array $properties): static $object = $this->_real(); foreach ($properties as $property => $value) { - Instantiator::forceSet($object, $property, $value); + Instantiator::forceSet($object, $property, $value, calledInternally: true); } return $this; @@ -289,7 +289,7 @@ public function get(string $property): mixed public function _get(string $property): mixed { - return Instantiator::forceGet($this->_real(), $property); + return Instantiator::forceGet($this->_real(), $property, calledInternally: true); } /** diff --git a/tests/Unit/FactoryCollectionTest.php b/tests/Unit/FactoryCollectionTest.php index 042c7054a..b4a8a2680 100644 --- a/tests/Unit/FactoryCollectionTest.php +++ b/tests/Unit/FactoryCollectionTest.php @@ -30,7 +30,7 @@ final class FactoryCollectionTest extends TestCase */ public function can_create_with_static_size(): void { - $collection = FactoryCollection::set(persistent_factory(Category::class), 2); + $collection = FactoryCollection::many(persistent_factory(Category::class), 2); $this->assertCount(2, $collection->create()); $this->assertCount(2, $collection->create()); diff --git a/tests/Unit/InstantiatorTest.php b/tests/Unit/InstantiatorTest.php index 289f69648..87a875376 100644 --- a/tests/Unit/InstantiatorTest.php +++ b/tests/Unit/InstantiatorTest.php @@ -399,6 +399,7 @@ public function prefixing_invalid_attribute_key_with_force_throws_exception(): v /** * @test + * @group legacy */ public function can_use_force_set_and_get(): void { @@ -457,6 +458,7 @@ public function force_set_throws_exception_for_invalid_property(): void /** * @test + * @group legacy */ public function force_get_throws_exception_for_invalid_property(): void { @@ -612,7 +614,6 @@ public function always_force_mode_can_set_parent_class_properties(): void $this->assertSame('constructor B', $object->getPropB()); $this->assertSame('constructor C', $object->getPropC()); $this->assertSame('D', $object->getPropD()); - $this->assertSame('E', Instantiator::forceGet($object, 'propE')); } /** @@ -645,7 +646,7 @@ public function can_set_variadic_constructor_attributes(): void /** * @test */ - public function missing_variadic_argument_thtrows(): void + public function missing_variadic_argument_throws(): void { $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Missing constructor argument "propB" for "Zenstruck\Foundry\Tests\Unit\VariadicInstantiatorDummy".'); diff --git a/utils/rector/.phpunit.result.cache b/utils/rector/.phpunit.result.cache deleted file mode 100644 index f5a2ec044..000000000 --- a/utils/rector/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -{"version":1,"defects":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#0":7,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#1":8},"times":{"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#0":0.268,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AddProxyToFactoryCollectionTypeInPhpDocTest::test#1":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#0":0.016,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeDisableEnablePersistTest::test#1":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#0":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassTest::test#1":0.021,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#0":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryBaseClass\\ChangeFactoryBaseClassWithObjectManagerTest::test#1":0.015,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#0":0.057,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#1":0.053,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#0":0.02,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#1":0.019,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeInstantiatorMethodCalls\\ChangeInstantiatorMethodCallsTest::test#2":0.01,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeLegacyClassImportsTest::test#0":0.005,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#0":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\RemoveProxyRealObjectMethodCallsForNotProxifiedObjectsTest::test#1":0.011,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#0":0.551,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#1":0.152,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\AddProxyToFactoryCollectionTypeInPhpDoc\\AllRulesTest::test#2":0.968,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#0":0.017,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFunctionsCalls\\ChangeFunctionsCallsTest::test#1":0.018,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeFactoryMethodCalls\\ChangeFactoryMethodCallsTest::test#2":0.053,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeLegacyClassUses\\ChangeProxyMethodCallsTest::test#0":0.071,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#0":0.024,"Zenstruck\\Foundry\\Utils\\Rector\\Tests\\ChangeDisableEnablePersist\\ChangeStaticFactoryFakerCallsTest::test#1":0.021}} \ No newline at end of file diff --git a/utils/rector/config/foundry-set.php b/utils/rector/config/foundry-set.php index 733c32749..571c69d98 100644 --- a/utils/rector/config/foundry-set.php +++ b/utils/rector/config/foundry-set.php @@ -3,6 +3,12 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\Renaming\Contract\MethodCallRenameInterface; +use Rector\Renaming\Rector\MethodCall\RenameMethodRector; +use Rector\Renaming\ValueObject\MethodCallRename; +use Rector\Transform\Rector\MethodCall\MethodCallToPropertyFetchRector; +use Rector\Transform\ValueObject\MethodCallToPropertyFetch; +use Zenstruck\Foundry\FactoryCollection; use Zenstruck\Foundry\Utils\Rector\AddProxyToFactoryCollectionTypeInPhpDoc; use Zenstruck\Foundry\Utils\Rector\ChangeDisableEnablePersist; use Zenstruck\Foundry\Utils\Rector\ChangeFactoryBaseClass; @@ -37,4 +43,11 @@ ChangeProxyMethodCalls::class, ChangeStaticFactoryFakerCalls::class, ]); + + $rectorConfig->ruleWithConfiguration( + RenameMethodRector::class, + [ + new MethodCallRename(FactoryCollection::class, 'set', 'many') + ] + ); }; diff --git a/utils/rector/src/ChangeStaticFactoryFakerCalls.php b/utils/rector/src/ChangeStaticFactoryFakerCalls.php index 64cc2e689..1546f350e 100644 --- a/utils/rector/src/ChangeStaticFactoryFakerCalls.php +++ b/utils/rector/src/ChangeStaticFactoryFakerCalls.php @@ -58,7 +58,7 @@ public function refactor(Node $node): Node|int|null return null; } - /** @var MutatingScope */ + /** @var MutatingScope $mutatingScope */ $mutatingScope = $node->getAttribute('scope'); // if the Factory::faker() was called from a Factory, then do nothing diff --git a/utils/rector/tests/AllRules/Fixtures/test-case.php.inc b/utils/rector/tests/AllRules/Fixtures/test-case.php.inc index f3d830c70..d2faaa265 100644 --- a/utils/rector/tests/AllRules/Fixtures/test-case.php.inc +++ b/utils/rector/tests/AllRules/Fixtures/test-case.php.inc @@ -43,6 +43,8 @@ class DummyKernelTestCase extends KernelTestCase \Zenstruck\Foundry\Test\TestState::configure(faker: null); Factory::faker(); + + FactoryCollection::set(DummyObjectModelFactory::new(), 5); } } @@ -92,6 +94,8 @@ class DummyKernelTestCase extends KernelTestCase \Zenstruck\Foundry\Test\UnitTestConfig::configure(faker: null); \Zenstruck\Foundry\faker(); + + FactoryCollection::many(DummyObjectModelFactory::new(), 5); } }