Skip to content

Commit 2d28e67

Browse files
authored
test: ensure no deprecation when Factories used in parent class (#922)
1 parent b25eb60 commit 2d28e67

11 files changed

+175
-27
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"php": ">=8.1",
2020
"fakerphp/faker": "^1.23",
2121
"symfony/deprecation-contracts": "^2.2|^3.0",
22+
"symfony/polyfill-php84": "^1.32",
2223
"symfony/property-access": "^6.4|^7.0",
2324
"symfony/property-info": "^6.4|^7.0",
2425
"symfony/var-exporter": "^6.4.9|~7.0.9|^7.1.2",

phpunit-deprecation-baseline.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<file path="vendor/symfony/deprecation-contracts/function.php">
44
<line number="25" hash="c6af5d66288d0667e424978000f29571e4954b81">
55
<issue><![CDATA[Since symfony/framework-bundle 6.4: Not setting the "framework.php_errors.log" config option is deprecated. It will default to "true" in 7.0.]]></issue>
6+
<issue><![CDATA[Since symfony/var-exporter 7.3: Generating lazy proxy for class "Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage\SomeObject" is deprecated; leverage native lazy objects instead.]]></issue>
67
</line>
78
</file>
89
</files>

src/Exception/FactoriesTraitNotUsed.php

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,43 @@ public static function throwIfComingFromKernelTestCaseWithoutFactoriesTrait(): v
3535
{
3636
$backTrace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); // @phpstan-ignore ekinoBannedCode.function
3737

38-
foreach ($backTrace as $trace) {
39-
if (
40-
'->' === ($trace['type'] ?? null)
41-
&& isset($trace['class'])
42-
&& KernelTestCase::class !== $trace['class']
43-
&& \is_a($trace['class'], KernelTestCase::class, allow_string: true)
44-
) {
45-
self::throwIfClassDoesNotHaveFactoriesTrait($trace['class']);
46-
}
38+
$testClassesExtendingKernelTestCase = \array_column(
39+
\array_filter(
40+
$backTrace,
41+
static fn(array $trace): bool => '->' === ($trace['type'] ?? null)
42+
&& isset($trace['class'])
43+
&& KernelTestCase::class !== $trace['class']
44+
&& \is_a($trace['class'], KernelTestCase::class, allow_string: true)
45+
),
46+
'class'
47+
);
48+
49+
if (!$testClassesExtendingKernelTestCase) {
50+
// no KernelTestCase found in backtrace, so nothing to check
51+
return;
4752
}
53+
54+
self::throwIfClassDoesNotHaveFactoriesTrait(...$testClassesExtendingKernelTestCase);
4855
}
4956

5057
/**
51-
* @param class-string<KernelTestCase> $class
58+
* @param class-string<KernelTestCase> $classes
5259
*/
53-
public static function throwIfClassDoesNotHaveFactoriesTrait(string $class): void
60+
public static function throwIfClassDoesNotHaveFactoriesTrait(string ...$classes): void
5461
{
55-
if (!(new \ReflectionClass($class))->hasMethod('_bootFoundry')) {
56-
// throw new self($class);
57-
trigger_deprecation(
58-
'zenstruck/foundry',
59-
'2.4',
60-
'In order to use Foundry correctly, you must use the trait "%s" in your "%s" tests. This will throw an exception in 3.0.',
61-
Factories::class,
62-
$class
63-
);
62+
if (array_any($classes, static fn(string $class): bool => (new \ReflectionClass($class))->hasMethod('_beforeHook'))) {
63+
// at least one KernelTestCase class in the backtrace uses Factories trait, nothing to do
64+
return;
6465
}
66+
67+
// throw new self($class);
68+
69+
trigger_deprecation(
70+
'zenstruck/foundry',
71+
'2.4',
72+
'In order to use Foundry correctly, you must use the trait "%s" in your "%s" tests. This will throw an exception in 3.0.',
73+
Factories::class,
74+
$classes[\array_key_last($classes)]
75+
);
6576
}
6677
}

tests/Fixture/DoctrineCascadeRelationship/ChangesEntityRelationshipCascadePersist.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Doctrine\ORM\Mapping\MappingException;
1818
use PHPUnit\Framework\Attributes\Before;
1919
use PHPUnit\Framework\Attributes\DataProvider;
20+
use PHPUnit\Metadata\Version\ConstraintRequirement;
21+
use PHPUnit\Runner\Version as PHPunitVersion;
2022
use Psr\Cache\CacheItemPoolInterface;
2123
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
2224
use Zenstruck\Foundry\Configuration;
@@ -73,9 +75,11 @@ public function setUpCascadePersistMetadata(): void
7375
*/
7476
public static function provideCascadeRelationshipsCombinations(): iterable
7577
{
76-
yield []; // @phpstan-ignore generator.valueType
78+
if (ConstraintRequirement::from('>=12')->isSatisfiedBy(PHPunitVersion::id())) {
79+
yield []; // @phpstan-ignore generator.valueType
80+
return;
81+
}
7782

78-
return;
7983

8084
// @phpstan-ignore deadCode.unreachable
8185
if (!\getenv('DATABASE_URL') || !self::$methodName) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the zenstruck/foundry package.
7+
*
8+
* (c) Kevin Bond <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage;
15+
16+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
17+
use Zenstruck\Foundry\Persistence\Proxy;
18+
19+
abstract class AnotherBaseTestCase extends KernelTestCase
20+
{
21+
// @phpstan-ignore missingType.generics
22+
public function useProxyClass(Proxy $proxy): void
23+
{
24+
$proxy->_real();
25+
}
26+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the zenstruck/foundry package.
7+
*
8+
* (c) Kevin Bond <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage;
15+
16+
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
17+
use PHPUnit\Framework\Attributes\RequiresPhpunit;
18+
use PHPUnit\Framework\Attributes\Test;
19+
20+
use function Zenstruck\Foundry\factory;
21+
use function Zenstruck\Foundry\Persistence\proxy;
22+
23+
#[RequiresPhpunit('>=11.0')]
24+
final class ClassExtendingBaseTestCaseNotUsingFactoriesTest extends AnotherBaseTestCase
25+
{
26+
use KernelTestCaseWithoutFactoriesTrait;
27+
28+
#[Test]
29+
#[IgnoreDeprecations]
30+
public function using_foundry_should_trigger_deprecation(): void
31+
{
32+
$this->assertDeprecation();
33+
34+
$proxyObject = proxy(factory(SomeObject2::class)->create());
35+
$this->useProxyClass($proxyObject);
36+
}
37+
}
38+
39+
class SomeObject2
40+
{
41+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the zenstruck/foundry package.
7+
*
8+
* (c) Kevin Bond <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage;
15+
16+
use PHPUnit\Framework\Attributes\RequiresPhpunit;
17+
use PHPUnit\Framework\Attributes\Test;
18+
19+
use function Zenstruck\Foundry\factory;
20+
use function Zenstruck\Foundry\Persistence\proxy;
21+
22+
#[RequiresPhpunit('>=11.0')]
23+
final class ClassExtendingBaseTestCaseUsingFactoriesTest extends KernelTestCaseWithFactoriesTraitBaseTestCase
24+
{
25+
#[Test]
26+
public function not_using_foundry_should_not_throw(): void
27+
{
28+
$this->expectNotToPerformAssertions();
29+
30+
$proxyObject = proxy(factory(SomeObject::class)->create());
31+
$this->useProxyClass($proxyObject);
32+
}
33+
}
34+
35+
class SomeObject
36+
{
37+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the zenstruck/foundry package.
7+
*
8+
* (c) Kevin Bond <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage;
15+
16+
use Zenstruck\Foundry\Test\Factories;
17+
18+
abstract class KernelTestCaseWithFactoriesTraitBaseTestCase extends AnotherBaseTestCase
19+
{
20+
use Factories;
21+
}

tests/Integration/ForceFactoriesTraitUsage/KernelTestCaseWithOnlyResetDatabaseTraitTest.php renamed to tests/Integration/ForceFactoriesTraitUsage/KernelTestCaseWithOnlyResetDatabaseTraitTestWithoutFactoriesTrait.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
namespace Zenstruck\Foundry\Tests\Integration\ForceFactoriesTraitUsage;
1515

1616
use PHPUnit\Framework\Attributes\RequiresPhpunit;
17+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1718
use Zenstruck\Foundry\Test\ResetDatabase;
1819

1920
#[RequiresPhpunit('>=11.0')]
20-
final class KernelTestCaseWithOnlyResetDatabaseTraitTest extends KernelTestCaseWithoutFactoriesTraitTestCase
21+
final class KernelTestCaseWithOnlyResetDatabaseTraitTestWithoutFactoriesTrait extends KernelTestCase
2122
{
23+
use KernelTestCaseWithoutFactoriesTrait;
2224
use ResetDatabase;
2325
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
1919
use PHPUnit\Framework\Attributes\RequiresPhpunitExtension;
2020
use PHPUnit\Framework\Attributes\Test;
21-
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
2221
use Zenstruck\Foundry\Configuration;
2322
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
2423
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;
2524
use Zenstruck\Foundry\Tests\Fixture\Stories\ObjectStory;
2625

27-
abstract class KernelTestCaseWithoutFactoriesTraitTestCase extends KernelTestCase
26+
/**
27+
* @require-extends KernelTestCase
28+
*/
29+
trait KernelTestCaseWithoutFactoriesTrait
2830
{
2931
#[Test]
3032
public function not_using_foundry_should_not_throw(): void
@@ -76,7 +78,7 @@ public function using_a_story_without_factories_trait_should_throw(): void
7678
* In user land, Foundry can work without the trait, because it may have been booted in a previous test.
7779
*/
7880
#[Before]
79-
public function _beforeHook(): void
81+
public function _bootFoundry(): void
8082
{
8183
Configuration::boot(static function(): Configuration {
8284
return static::getContainer()->get('.zenstruck_foundry.configuration'); // @phpstan-ignore return.type

0 commit comments

Comments
 (0)