From 305d3a32436a897390f4e864dd714ed1067e66cb Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 1 Sep 2026 12:22:47 +0200 Subject: [PATCH 1/6] feat: honor factory state when a create helper is called on an instance --- src/Factory.php | 62 ++++++++++++++++-- .../PersistentProxyObjectFactory.php | 4 +- .../Persistence/GenericFactoryTestCase.php | 2 +- tests/Unit/ObjectFactoryTest.php | 65 +++++++++++++++++++ 4 files changed, 126 insertions(+), 7 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index 3a8b4eb35..0788f9a67 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -26,9 +26,16 @@ * @phpstan-type Parameters = array * @phpstan-type Attributes = Parameters|callable(int):Parameters * @phpstan-type Sequence = iterable|callable(): iterable + * + * @method static T createOne(Attributes $attributes = []) + * @method static ($number is positive-int ? non-empty-list : list) createMany(int $number, Attributes $attributes = []) + * @method static ($min is positive-int ? non-empty-list : list) createRange(int $min, int $max, Attributes $attributes = []) + * @method static list createSequence(Sequence $sequence) */ abstract class Factory { + private const CREATE_HELPERS = ['createOne', 'createMany', 'createRange', 'createSequence']; + /** @phpstan-var Attributes[] */ private array $attributes = []; @@ -68,7 +75,7 @@ final public static function new(array|callable $attributes = []): static * * @return T */ - public static function createOne(array|callable $attributes = []): mixed + protected static function doCreateOne(array|callable $attributes = []): mixed { return static::new()->create($attributes); } @@ -81,7 +88,7 @@ public static function createOne(array|callable $attributes = []): mixed * @return list * @phpstan-return ($number is positive-int ? non-empty-list : list) */ - final public static function createMany(int $number, array|callable $attributes = []): array + final protected static function doCreateMany(int $number, array|callable $attributes = []): array { return static::new()->many($number)->create($attributes); } @@ -94,7 +101,7 @@ final public static function createMany(int $number, array|callable $attributes * @return list * @phpstan-return ($min is positive-int ? non-empty-list : list) */ - final public static function createRange(int $min, int $max, array|callable $attributes = []): array + final protected static function doCreateRange(int $min, int $max, array|callable $attributes = []): array { return static::new()->range($min, $max)->create($attributes); } @@ -104,11 +111,58 @@ final public static function createRange(int $min, int $max, array|callable $att * * @return list */ - final public static function createSequence(iterable|callable $sequence): array + final protected static function doCreateSequence(iterable|callable $sequence): array { return static::new()->sequence($sequence)->create(); } + /** + * @param array $arguments + */ + final public static function __callStatic(string $name, array $arguments): mixed + { + if (!\in_array($name, self::CREATE_HELPERS, true)) { + throw new \BadMethodCallException(\sprintf('Call to undefined method %s::%s().', static::class, $name)); + } + + return static::{'do'.\ucfirst($name)}(...$arguments); + } + + /** + * The create helpers are static, so calling one on an instance used to silently discard + * everything set on that instance: `Factory::new()->someState()->createMany(2)` created + * two objects without the state. Routing them through __callStatic makes the instance + * call land here instead, where the state can be honored. + * + * @param array $arguments + */ + final public function __call(string $name, array $arguments): mixed + { + if (!\in_array($name, self::CREATE_HELPERS, true)) { + throw new \BadMethodCallException(\sprintf('Call to undefined method %s::%s().', static::class, $name)); + } + + trigger_deprecation('zenstruck/foundry', '2.13', 'Calling "%s()" on a factory instance is deprecated and will throw in Foundry 3. Use "%s" instead.', $name, self::instanceEquivalent($name)); + + return match ($name) { + 'createOne' => $this->create(...$arguments), + 'createMany' => $this->many($arguments[0])->create($arguments[1] ?? []), + 'createRange' => $this->range($arguments[0], $arguments[1])->create($arguments[2] ?? []), + 'createSequence' => $this->sequence($arguments[0])->create(), + }; + } + + private static function instanceEquivalent(string $name): string + { + return match ($name) { + 'createOne' => 'create()', + 'createMany' => 'many()->create()', + 'createRange' => 'range()->create()', + 'createSequence' => 'sequence()->create()', + default => throw new \LogicException(\sprintf('Unhandled create helper "%s".', $name)), + }; + } + /** * @param array|callable $attributes Property values for the object(s) to create * diff --git a/src/Persistence/PersistentProxyObjectFactory.php b/src/Persistence/PersistentProxyObjectFactory.php index 2da446a60..beb976fa3 100644 --- a/src/Persistence/PersistentProxyObjectFactory.php +++ b/src/Persistence/PersistentProxyObjectFactory.php @@ -51,9 +51,9 @@ final public function create(callable|array $attributes = []): object * @return T|Proxy * @phpstan-return T&Proxy */ - final public static function createOne(array|callable $attributes = []): mixed + final protected static function doCreateOne(array|callable $attributes = []): mixed { - return proxy(parent::createOne($attributes)); // @phpstan-ignore function.unresolvableReturnType + return proxy(parent::doCreateOne($attributes)); // @phpstan-ignore function.unresolvableReturnType } /** diff --git a/tests/Integration/Persistence/GenericFactoryTestCase.php b/tests/Integration/Persistence/GenericFactoryTestCase.php index 54b5a87e3..f8ce69819 100644 --- a/tests/Integration/Persistence/GenericFactoryTestCase.php +++ b/tests/Integration/Persistence/GenericFactoryTestCase.php @@ -196,7 +196,7 @@ public function repository_and_create_function(): void #[Test] public function create_many(): void { - $models = static::factory()->createMany(3, static fn(int $i) => ['prop1' => "value{$i}"]); + $models = static::factory()->many(3)->create(static fn(int $i) => ['prop1' => "value{$i}"]); static::factory()::repository()->assert()->count(3); diff --git a/tests/Unit/ObjectFactoryTest.php b/tests/Unit/ObjectFactoryTest.php index 629a499f9..f1382268d 100644 --- a/tests/Unit/ObjectFactoryTest.php +++ b/tests/Unit/ObjectFactoryTest.php @@ -12,6 +12,8 @@ namespace Zenstruck\Foundry\Tests\Unit; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; +use PHPUnit\Framework\Attributes\RequiresPhpunit; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Zenstruck\Foundry\Factory; @@ -525,4 +527,67 @@ public function as_data_provider(): void { $this->markTestIncomplete(); } + + /** + * @test + * @group legacy + */ + #[Test] + #[IgnoreDeprecations] + public function create_helpers_called_on_an_instance_keep_the_state(): void + { + $factory = SimpleObjectFactory::new()->with(['prop1' => 'from-state']); + + self::assertSame('from-state', $factory->createOne()->prop1); + self::assertSame(['from-state', 'from-state'], \array_column($factory->createMany(2), 'prop1')); + self::assertSame(['from-state', 'from-state'], \array_column($factory->createRange(2, 2), 'prop1')); + self::assertSame(['from-state'], \array_column($factory->createSequence([[]]), 'prop1')); + } + + /** + * @test + * @group legacy + */ + #[Test] + #[RequiresPhpunit('>=11.0.0')] + public function create_helpers_called_on_an_instance_are_deprecated(): void + { + $this->expectUserDeprecationMessageMatches('/Calling "createMany\(\)" on a factory instance is deprecated and will throw in Foundry 3\. Use "many\(\)->create\(\)" instead\./'); + + SimpleObjectFactory::new()->createMany(1); + } + + /** + * @test + */ + #[Test] + public function create_helpers_still_ignore_nothing_when_called_statically(): void + { + self::assertCount(2, SimpleObjectFactory::createMany(2, ['prop1' => 'static'])); + self::assertSame('static', SimpleObjectFactory::createOne(['prop1' => 'static'])->prop1); + } + + /** + * @test + */ + #[Test] + public function calling_an_undefined_method_statically_throws(): void + { + $this->expectException(\BadMethodCallException::class); + $this->expectExceptionMessage(\sprintf('Call to undefined method %s::doesNotExist().', SimpleObjectFactory::class)); + + SimpleObjectFactory::doesNotExist(); // @phpstan-ignore staticMethod.notFound + } + + /** + * @test + */ + #[Test] + public function calling_an_undefined_method_on_an_instance_throws(): void + { + $this->expectException(\BadMethodCallException::class); + $this->expectExceptionMessage(\sprintf('Call to undefined method %s::doesNotExist().', SimpleObjectFactory::class)); + + SimpleObjectFactory::new()->doesNotExist(); // @phpstan-ignore method.notFound + } } From 9bc1a507bc50c0da128322d18c1c06e47820b02d Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Mon, 7 Sep 2026 14:29:15 +0200 Subject: [PATCH 2/6] Ignore the deprecation in the test that asserts it --- tests/Unit/ObjectFactoryTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/ObjectFactoryTest.php b/tests/Unit/ObjectFactoryTest.php index f1382268d..033aef147 100644 --- a/tests/Unit/ObjectFactoryTest.php +++ b/tests/Unit/ObjectFactoryTest.php @@ -549,6 +549,7 @@ public function create_helpers_called_on_an_instance_keep_the_state(): void * @group legacy */ #[Test] + #[IgnoreDeprecations] #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_are_deprecated(): void { From d153f888fadbead57f46c8cc684e78c4ea78f932 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Mon, 7 Sep 2026 15:14:21 +0200 Subject: [PATCH 3/6] Guard the deprecation tests for PHPUnit 9 The RequiresPhpunit attribute does not exist there either, so the docblock annotation is what actually skips them, as the rest of the suite does. --- tests/Unit/ObjectFactoryTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Unit/ObjectFactoryTest.php b/tests/Unit/ObjectFactoryTest.php index 033aef147..51ba2a801 100644 --- a/tests/Unit/ObjectFactoryTest.php +++ b/tests/Unit/ObjectFactoryTest.php @@ -530,10 +530,13 @@ public function as_data_provider(): void /** * @test + * * @group legacy + * @requires PHPUnit >=11.0.0 */ #[Test] #[IgnoreDeprecations] + #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_keep_the_state(): void { $factory = SimpleObjectFactory::new()->with(['prop1' => 'from-state']); @@ -546,7 +549,9 @@ public function create_helpers_called_on_an_instance_keep_the_state(): void /** * @test + * * @group legacy + * @requires PHPUnit >=11.0.0 */ #[Test] #[IgnoreDeprecations] From 576c477c8f68c88d0008401a4a173a4a30550960 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 8 Sep 2026 14:53:36 +0200 Subject: [PATCH 4/6] Give Psalm the return types of the create helpers Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WUCMYykYqJHv67fmwiWZip --- src/Factory.php | 18 ++- utils/psalm/FixCreateHelpersReturnType.php | 140 +++++++++++++++++++++ utils/psalm/FoundryPlugin.php | 3 + 3 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 utils/psalm/FixCreateHelpersReturnType.php diff --git a/src/Factory.php b/src/Factory.php index 0788f9a67..f67700991 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -27,10 +27,20 @@ * @phpstan-type Attributes = Parameters|callable(int):Parameters * @phpstan-type Sequence = iterable|callable(): iterable * - * @method static T createOne(Attributes $attributes = []) - * @method static ($number is positive-int ? non-empty-list : list) createMany(int $number, Attributes $attributes = []) - * @method static ($min is positive-int ? non-empty-list : list) createRange(int $min, int $max, Attributes $attributes = []) - * @method static list createSequence(Sequence $sequence) + * The create helpers are routed through __callStatic(), so they are declared here. Psalm reads + * the "@method" tags but does not expand the aliases above inside them, it reads them as class + * names, hence the plain signatures; PHPStan reads the "@phpstan-method" ones. The return types + * Psalm uses come from FixCreateHelpersReturnType, not from the tags. + * + * @method static T createOne(array|callable $attributes = []) + * @method static list createMany(int $number, array|callable $attributes = []) + * @method static list createRange(int $min, int $max, array|callable $attributes = []) + * @method static list createSequence(iterable|callable $sequence) + * + * @phpstan-method static T createOne(Attributes $attributes = []) + * @phpstan-method static ($number is positive-int ? non-empty-list : list) createMany(int $number, Attributes $attributes = []) + * @phpstan-method static ($min is positive-int ? non-empty-list : list) createRange(int $min, int $max, Attributes $attributes = []) + * @phpstan-method static list createSequence(Sequence $sequence) */ abstract class Factory { diff --git a/utils/psalm/FixCreateHelpersReturnType.php b/utils/psalm/FixCreateHelpersReturnType.php new file mode 100644 index 000000000..ebf471759 --- /dev/null +++ b/utils/psalm/FixCreateHelpersReturnType.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Zenstruck\Foundry\Psalm; + +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\StaticCall; +use PhpParser\Node\Identifier; +use PhpParser\Node\Name; +use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Plugin\EventHandler\AfterExpressionAnalysisInterface; +use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent; +use Psalm\StatementsSource; +use Psalm\Type; +use Psalm\Type\Atomic\TIntRange; +use Psalm\Type\Atomic\TLiteralInt; +use Zenstruck\Foundry\Factory; +use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory; +use Zenstruck\Foundry\Persistence\Proxy; + +/** + * The create helpers are declared with "@method static" tags on Factory, and Psalm does not + * bind the class template when it resolves a pseudo method: it expands the return type with + * the declaring class as "self", so "T" stays "T:Zenstruck\Foundry\Factory as mixed". + * + * The return type is therefore rebuilt here, once the call has been analyzed. This also + * covers the proxy factories, which FixProxyFactoryMethodsReturnType cannot reach: it hooks + * AfterMethodCallAnalysisInterface, and that never fires for a magic static call. + */ +final class FixCreateHelpersReturnType implements AfterExpressionAnalysisInterface +{ + public static function afterExpressionAnalysis(AfterExpressionAnalysisEvent $event): ?bool + { + $expr = $event->getExpr(); + + if (!$expr instanceof StaticCall + || !$expr->name instanceof Identifier + || !$expr->class instanceof Name + ) { + return null; + } + + $method = \strtolower($expr->name->name); + + if (!\in_array($method, ['createone', 'createmany', 'createrange', 'createsequence'], true)) { + return null; + } + + $source = $event->getStatementsSource(); + $class = ClassLikeAnalyzer::getFQCLNFromNameObject($expr->class, $source->getAliases()); + $codebase = $event->getCodebase(); + + if (!$codebase->classExtends($class, Factory::class)) { + return null; + } + + $storage = $codebase->classlikes->getStorageFor($class); + + if (!$storage) { + return null; + } + + $isProxy = $codebase->classExtends($class, PersistentProxyObjectFactory::class); + $templateType = $storage->template_extended_params[$isProxy ? PersistentProxyObjectFactory::class : Factory::class]['T'] ?? null; + + if (!$templateType) { + return null; + } + + $type = $templateType->getId(); + + if ($isProxy) { + $proxyClass = Proxy::class; + $type = "{$type}&{$proxyClass}<{$type}>"; + } + + $source->getNodeTypeProvider()->setType( + $expr, + Type::parseString(self::returnType($method, $type, $expr, $source, $isProxy)), + ); + + return null; + } + + /** + * The list helpers are declared with a conditional return type, which Psalm does not + * evaluate for a pseudo method either, so the argument is read here. Proxy factories + * never had the conditional type, FixProxyFactoryMethodsReturnType always widened them + * to a plain list, and that is kept. + */ + private static function returnType( + string $method, + string $type, + StaticCall $expr, + StatementsSource $source, + bool $isProxy, + ): string { + if ('createone' === $method) { + return $type; + } + + if ('createsequence' === $method || $isProxy) { + return "list<{$type}>"; + } + + // createMany() is driven by its first argument, createRange() by its lowest bound + $argument = $expr->getArgs()[0]->value ?? null; + + return $argument && self::isPositiveInt($argument, $source) + ? "non-empty-list<{$type}>" + : "list<{$type}>"; + } + + private static function isPositiveInt(Expr $expr, StatementsSource $source): bool + { + $type = $source->getNodeTypeProvider()->getType($expr); + + if (!$type || !$type->isSingle()) { + return false; + } + + $atomic = $type->getSingleAtomic(); + + if ($atomic instanceof TLiteralInt) { + return $atomic->value > 0; + } + + return $atomic instanceof TIntRange && null !== $atomic->min_bound && $atomic->min_bound > 0; + } +} diff --git a/utils/psalm/FoundryPlugin.php b/utils/psalm/FoundryPlugin.php index 5dc972c69..1c6463773 100644 --- a/utils/psalm/FoundryPlugin.php +++ b/utils/psalm/FoundryPlugin.php @@ -20,5 +20,8 @@ public function __invoke(RegistrationInterface $registration, ?\SimpleXMLElement { \class_exists(FixProxyFactoryMethodsReturnType::class, true); $registration->registerHooksFromClass(FixProxyFactoryMethodsReturnType::class); + + \class_exists(FixCreateHelpersReturnType::class, true); + $registration->registerHooksFromClass(FixCreateHelpersReturnType::class); } } From bcf9f2b5574c532d8dc0fd08b3071cb26bd12a4b Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 8 Sep 2026 20:38:01 +0200 Subject: [PATCH 5/6] Apply the review: drop the redundant proxy override and lock the helpers down Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WUCMYykYqJHv67fmwiWZip --- src/Factory.php | 29 +++++++++++-------- .../PersistentProxyObjectFactory.php | 9 ------ tests/Unit/ObjectFactoryTest.php | 4 +-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Factory.php b/src/Factory.php index f67700991..1c7325f1e 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -27,15 +27,20 @@ * @phpstan-type Attributes = Parameters|callable(int):Parameters * @phpstan-type Sequence = iterable|callable(): iterable * - * The create helpers are routed through __callStatic(), so they are declared here. Psalm reads - * the "@method" tags but does not expand the aliases above inside them, it reads them as class - * names, hence the plain signatures; PHPStan reads the "@phpstan-method" ones. The return types - * Psalm uses come from FixCreateHelpersReturnType, not from the tags. + * The create helpers go through __callStatic(). One block per reader: PHPStorm and PHPStan get + * the real signatures, Psalm gets plain ones because it reads the aliases above as class names + * inside a "@method" tag, and inlining them makes it drop the tags entirely. Its return types + * come from FixCreateHelpersReturnType anyway. * - * @method static T createOne(array|callable $attributes = []) - * @method static list createMany(int $number, array|callable $attributes = []) - * @method static list createRange(int $min, int $max, array|callable $attributes = []) - * @method static list createSequence(iterable|callable $sequence) + * @psalm-method static T createOne(array|callable $attributes = []) + * @psalm-method static list createMany(int $number, array|callable $attributes = []) + * @psalm-method static list createRange(int $min, int $max, array|callable $attributes = []) + * @psalm-method static list createSequence(iterable|callable $sequence) + * + * @method static T createOne(Attributes $attributes = []) + * @method static ($number is positive-int ? non-empty-list : list) createMany(int $number, Attributes $attributes = []) + * @method static ($min is positive-int ? non-empty-list : list) createRange(int $min, int $max, Attributes $attributes = []) + * @method static list createSequence(Sequence $sequence) * * @phpstan-method static T createOne(Attributes $attributes = []) * @phpstan-method static ($number is positive-int ? non-empty-list : list) createMany(int $number, Attributes $attributes = []) @@ -85,7 +90,7 @@ final public static function new(array|callable $attributes = []): static * * @return T */ - protected static function doCreateOne(array|callable $attributes = []): mixed + private static function doCreateOne(array|callable $attributes = []): mixed { return static::new()->create($attributes); } @@ -98,7 +103,7 @@ protected static function doCreateOne(array|callable $attributes = []): mixed * @return list * @phpstan-return ($number is positive-int ? non-empty-list : list) */ - final protected static function doCreateMany(int $number, array|callable $attributes = []): array + private static function doCreateMany(int $number, array|callable $attributes = []): array { return static::new()->many($number)->create($attributes); } @@ -111,7 +116,7 @@ final protected static function doCreateMany(int $number, array|callable $attrib * @return list * @phpstan-return ($min is positive-int ? non-empty-list : list) */ - final protected static function doCreateRange(int $min, int $max, array|callable $attributes = []): array + private static function doCreateRange(int $min, int $max, array|callable $attributes = []): array { return static::new()->range($min, $max)->create($attributes); } @@ -121,7 +126,7 @@ final protected static function doCreateRange(int $min, int $max, array|callable * * @return list */ - final protected static function doCreateSequence(iterable|callable $sequence): array + private static function doCreateSequence(iterable|callable $sequence): array { return static::new()->sequence($sequence)->create(); } diff --git a/src/Persistence/PersistentProxyObjectFactory.php b/src/Persistence/PersistentProxyObjectFactory.php index beb976fa3..084278656 100644 --- a/src/Persistence/PersistentProxyObjectFactory.php +++ b/src/Persistence/PersistentProxyObjectFactory.php @@ -47,15 +47,6 @@ final public function create(callable|array $attributes = []): object return proxy(parent::create($attributes)); // @phpstan-ignore function.unresolvableReturnType } - /** - * @return T|Proxy - * @phpstan-return T&Proxy - */ - final protected static function doCreateOne(array|callable $attributes = []): mixed - { - return proxy(parent::doCreateOne($attributes)); // @phpstan-ignore function.unresolvableReturnType - } - /** * @return T|Proxy * @phpstan-return T&Proxy diff --git a/tests/Unit/ObjectFactoryTest.php b/tests/Unit/ObjectFactoryTest.php index 51ba2a801..61e3dda9d 100644 --- a/tests/Unit/ObjectFactoryTest.php +++ b/tests/Unit/ObjectFactoryTest.php @@ -535,7 +535,7 @@ public function as_data_provider(): void * @requires PHPUnit >=11.0.0 */ #[Test] - #[IgnoreDeprecations] + #[IgnoreDeprecations('on a factory instance is deprecated')] #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_keep_the_state(): void { @@ -554,7 +554,7 @@ public function create_helpers_called_on_an_instance_keep_the_state(): void * @requires PHPUnit >=11.0.0 */ #[Test] - #[IgnoreDeprecations] + #[IgnoreDeprecations('on a factory instance is deprecated')] #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_are_deprecated(): void { From 99ebe94db6773a4f609ac8c8a665c67e2992f104 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Sat, 12 Sep 2026 17:47:06 +0200 Subject: [PATCH 6/6] Fix the legacy PHPUnit job and the BC check `#[IgnoreDeprecations]` takes no argument, and passing one makes PHPUnit 10 fail while analyzing the attribute, which is what broke the legacy proxy job. The four create helpers and the proxy override are private now and routed through `__callStatic`, so the BC check reports them as removed: they join the other intended changes in the baseline. --- .roave-backward-compatibility-check.xml | 2 ++ tests/Unit/ObjectFactoryTest.php | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.roave-backward-compatibility-check.xml b/.roave-backward-compatibility-check.xml index d86f7d3a5..e8d21ed3f 100644 --- a/.roave-backward-compatibility-check.xml +++ b/.roave-backward-compatibility-check.xml @@ -11,5 +11,7 @@ #\[BC\] CHANGED: Method getIdentifierValues\(\) of class Zenstruck\\Foundry\\Persistence\\PersistenceStrategy became final# #"Zenstruck\\Foundry\\Test\\(CommonResetDatabase|CommonFactories)" could not be found in the located source(.*)# #Method Zenstruck\\Foundry\\ORM\\AbstractORMPersistenceStrategy\#withoutDoctrineEvents\(\) was removed# + #Method Zenstruck\\Foundry\\Factory::create(One|Many|Range|Sequence)\(\) was removed# + #Method Zenstruck\\Foundry\\Persistence\\PersistentProxyObjectFactory::createOne\(\) was removed# diff --git a/tests/Unit/ObjectFactoryTest.php b/tests/Unit/ObjectFactoryTest.php index 61e3dda9d..51ba2a801 100644 --- a/tests/Unit/ObjectFactoryTest.php +++ b/tests/Unit/ObjectFactoryTest.php @@ -535,7 +535,7 @@ public function as_data_provider(): void * @requires PHPUnit >=11.0.0 */ #[Test] - #[IgnoreDeprecations('on a factory instance is deprecated')] + #[IgnoreDeprecations] #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_keep_the_state(): void { @@ -554,7 +554,7 @@ public function create_helpers_called_on_an_instance_keep_the_state(): void * @requires PHPUnit >=11.0.0 */ #[Test] - #[IgnoreDeprecations('on a factory instance is deprecated')] + #[IgnoreDeprecations] #[RequiresPhpunit('>=11.0.0')] public function create_helpers_called_on_an_instance_are_deprecated(): void {