Skip to content

Commit 15eba47

Browse files
committed
feat: force PHPUnit extension usage
1 parent a0857c5 commit 15eba47

12 files changed

+186
-47
lines changed

phpunit-deprecation-baseline.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
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>
66
<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>
7+
<issue><![CDATA[Since zenstruck/foundry 2.7: Trait Zenstruck\Foundry\Test\Factories is deprecated and will be removed in Foundry 3.]]></issue>
8+
<issue><![CDATA[Since zenstruck/foundry 2.7: Not using Foundry's PHPUnit extension is deprecated and will throw an error in Foundry 3.]]></issue>
79
</line>
810
</file>
911
</files>

src/Configuration.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Zenstruck\Foundry\InMemory\CannotEnableInMemory;
2020
use Zenstruck\Foundry\InMemory\InMemoryRepositoryRegistry;
2121
use Zenstruck\Foundry\Persistence\PersistenceManager;
22+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
23+
use Zenstruck\Foundry\Test\Factories;
2224

2325
/**
2426
* @author Kevin Bond <kevinbond@gmail.com>
@@ -128,6 +130,10 @@ public static function isBooted(): bool
128130
public static function boot(\Closure|self $configuration): void
129131
{
130132
self::$instance = $configuration;
133+
134+
if (FoundryExtension::shouldBeEnabled()) {
135+
trigger_deprecation('zenstruck/foundry', '2.7', 'Not using Foundry\'s PHPUnit extension is deprecated and will throw an error in Foundry 3.');
136+
}
131137
}
132138

133139
/** @param \Closure():self|self $configuration */

src/Exception/FoundryNotBooted.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@
1111

1212
namespace Zenstruck\Foundry\Exception;
1313

14+
use PHPUnit\Metadata\Version\ConstraintRequirement;
15+
use PHPUnit\Runner;
16+
1417
/**
1518
* @author Kevin Bond <kevinbond@gmail.com>
1619
*/
1720
final class FoundryNotBooted extends \LogicException
1821
{
1922
public function __construct()
2023
{
21-
parent::__construct('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
24+
$message = ConstraintRequirement::from('>=10')->isSatisfiedBy(Runner\Version::id())
25+
? 'Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure Foundry\'s PHPUnit extension is enabled.'
26+
: 'Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.';
27+
28+
parent::__construct($message);
2229
}
2330
}

src/PHPUnit/BootFoundryOnDataProviderMethodCalled.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
namespace Zenstruck\Foundry\PHPUnit;
1515

1616
use PHPUnit\Event;
17+
use PHPUnit\Framework\TestCase;
18+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1719
use Zenstruck\Foundry\Configuration;
1820
use Zenstruck\Foundry\InMemory\AsInMemoryTest;
21+
use Zenstruck\Foundry\Test\UnitTestConfig;
1922

2023
/**
2124
* @internal
@@ -25,14 +28,38 @@ final class BootFoundryOnDataProviderMethodCalled implements Event\Test\DataProv
2528
{
2629
public function notify(Event\Test\DataProviderMethodCalled $event): void
2730
{
28-
if (\method_exists($event->testMethod()->className(), '_bootForDataProvider')) {
29-
$event->testMethod()->className()::_bootForDataProvider();
30-
}
31+
$this->bootFoundryForDataProvider($event->testMethod()->className());
3132

3233
$testMethod = $event->testMethod();
3334

3435
if (AsInMemoryTest::shouldEnableInMemory($testMethod->className(), $testMethod->methodName())) {
3536
Configuration::instance()->enableInMemory();
3637
}
3738
}
39+
40+
/**
41+
* @param class-string $className
42+
*/
43+
private function bootFoundryForDataProvider(string $className): void
44+
{
45+
if (!\is_subclass_of($className, TestCase::class)) {
46+
return;
47+
}
48+
49+
// unit test
50+
if (!\is_subclass_of($className, KernelTestCase::class)) {
51+
Configuration::bootForDataProvider(UnitTestConfig::build());
52+
53+
return;
54+
}
55+
56+
// integration test
57+
Configuration::bootForDataProvider(static function(): Configuration {
58+
if (!KernelTestCaseHelper::getContainer()->has('.zenstruck_foundry.configuration')) {
59+
throw new \LogicException('ZenstruckFoundryBundle is not enabled. Ensure it is added to your config/bundles.php.');
60+
}
61+
62+
return KernelTestCaseHelper::getContainer()->get('.zenstruck_foundry.configuration'); // @phpstan-ignore return.type
63+
});
64+
}
3865
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 <kevinbond@gmail.com>
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\PHPUnit;
15+
16+
use PHPUnit\Event;
17+
use PHPUnit\Framework\TestCase;
18+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
19+
use Zenstruck\Foundry\Configuration;
20+
use Zenstruck\Foundry\Test\UnitTestConfig;
21+
22+
/**
23+
* @internal
24+
* @author Nicolas PHILIPPE <nikophil@gmail.com>
25+
*/
26+
final class BootFoundryOnPreparationStarted implements Event\Test\PreparationStartedSubscriber
27+
{
28+
public function notify(Event\Test\PreparationStarted $event): void
29+
{
30+
if (!$event->test()->isTestMethod()) {
31+
return;
32+
}
33+
34+
$this->bootFoundry($event->test()->className());
35+
}
36+
37+
/**
38+
* @param class-string $className
39+
*/
40+
private function bootFoundry(string $className): void
41+
{
42+
if (!\is_subclass_of($className, TestCase::class)) {
43+
return;
44+
}
45+
46+
// unit test
47+
if (!\is_subclass_of($className, KernelTestCase::class)) {
48+
Configuration::boot(UnitTestConfig::build());
49+
50+
return;
51+
}
52+
53+
// integration test
54+
Configuration::boot(static function(): Configuration {
55+
if (!KernelTestCaseHelper::getContainer()->has('.zenstruck_foundry.configuration')) {
56+
throw new \LogicException('ZenstruckFoundryBundle is not enabled. Ensure it is added to your config/bundles.php.');
57+
}
58+
59+
return KernelTestCaseHelper::getContainer()->get('.zenstruck_foundry.configuration'); // @phpstan-ignore return.type
60+
});
61+
}
62+
}

src/PHPUnit/FoundryExtension.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
final class FoundryExtension implements Runner\Extension\Extension
2626
{
27+
private static bool $enabled = false;
28+
2729
public function bootstrap(
2830
TextUI\Configuration\Configuration $configuration,
2931
Runner\Extension\Facade $facade,
@@ -38,6 +40,8 @@ public function bootstrap(
3840
new BuildStoryOnTestPrepared(),
3941
new EnableInMemoryBeforeTest(),
4042
new DisplayFakerSeedOnTestSuiteFinished(),
43+
new BootFoundryOnPreparationStarted(),
44+
new ShutdownFoundryOnTestFinished(),
4145
];
4246

4347
if (ConstraintRequirement::from('>=11.4')->isSatisfiedBy(Runner\Version::id())) {
@@ -47,5 +51,17 @@ public function bootstrap(
4751
}
4852

4953
$facade->registerSubscribers(...$subscribers);
54+
55+
self::$enabled = true;
56+
}
57+
58+
public static function shouldBeEnabled(): bool
59+
{
60+
return !self::isEnabled() && ConstraintRequirement::from('>=10')->isSatisfiedBy(Runner\Version::id());
61+
}
62+
63+
public static function isEnabled(): bool
64+
{
65+
return self::$enabled;
5066
}
5167
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Zenstruck\Foundry\PHPUnit;
4+
5+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
6+
use Symfony\Component\DependencyInjection\Container;
7+
8+
final class KernelTestCaseHelper extends KernelTestCase
9+
{
10+
public static function getContainer(): Container
11+
{
12+
return parent::getContainer();
13+
}
14+
}

src/PHPUnit/ShutdownFoundryOnDataProviderMethodFinished.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace Zenstruck\Foundry\PHPUnit;
1515

1616
use PHPUnit\Event;
17+
use Zenstruck\Foundry\Configuration;
1718

1819
/**
1920
* @internal
@@ -23,8 +24,8 @@ final class ShutdownFoundryOnDataProviderMethodFinished implements Event\Test\Da
2324
{
2425
public function notify(Event\Test\DataProviderMethodFinished $event): void
2526
{
26-
if (\method_exists($event->testMethod()->className(), '_shutdownAfterDataProvider')) {
27-
$event->testMethod()->className()::_shutdownAfterDataProvider();
28-
}
27+
KernelTestCaseHelper::tearDownAfterClass();
28+
29+
Configuration::shutdown();
2930
}
3031
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 <kevinbond@gmail.com>
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\PHPUnit;
15+
16+
use PHPUnit\Event;
17+
use Zenstruck\Foundry\Configuration;
18+
19+
/**
20+
* @internal
21+
* @author Nicolas PHILIPPE <nikophil@gmail.com>
22+
*/
23+
final class ShutdownFoundryOnTestFinished implements Event\Test\FinishedSubscriber
24+
{
25+
public function notify(Event\Test\Finished $event): void
26+
{
27+
Configuration::shutdown();
28+
}
29+
}

src/Test/Factories.php

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1717
use Zenstruck\Foundry\Configuration;
1818

19+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
20+
1921
use function Zenstruck\Foundry\Persistence\initialize_proxy_object;
2022

2123
/**
@@ -27,58 +29,31 @@ trait Factories
2729
* @internal
2830
* @before
2931
*/
30-
#[Before]
32+
#[Before(10)]
3133
public function _beforeHook(): void
3234
{
33-
$this->_bootFoundry();
34-
$this->_loadDataProvidedProxies();
35-
}
35+
$this->_loadDataProvidedProxies(); // todo remove
3636

37-
/**
38-
* @internal
39-
* @after
40-
*/
41-
#[After]
42-
public static function _shutdownFoundry(): void
43-
{
44-
Configuration::shutdown();
45-
}
46-
47-
/**
48-
* @see \Zenstruck\Foundry\PHPUnit\BootFoundryOnDataProviderMethodCalled
49-
* @internal
50-
*/
51-
public static function _bootForDataProvider(): void
52-
{
53-
if (!\is_subclass_of(static::class, KernelTestCase::class)) { // @phpstan-ignore function.impossibleType, function.alreadyNarrowedType
54-
// unit test
55-
Configuration::bootForDataProvider(UnitTestConfig::build());
37+
if (FoundryExtension::isEnabled()) {
38+
trigger_deprecation('zenstruck/foundry', '2.7', sprintf('Trait %s is deprecated and will be removed in Foundry 3.', Factories::class));
5639

5740
return;
5841
}
5942

60-
// integration test
61-
Configuration::bootForDataProvider(static function(): Configuration {
62-
if (!static::getContainer()->has('.zenstruck_foundry.configuration')) { // @phpstan-ignore staticMethod.notFound
63-
throw new \LogicException('ZenstruckFoundryBundle is not enabled. Ensure it is added to your config/bundles.php.');
64-
}
65-
66-
return static::getContainer()->get('.zenstruck_foundry.configuration'); // @phpstan-ignore staticMethod.notFound, return.type
67-
});
43+
$this->_bootFoundry();
6844
}
6945

7046
/**
7147
* @internal
72-
* @see \Zenstruck\Foundry\PHPUnit\ShutdownFoundryOnDataProviderMethodFinished
48+
* @after
7349
*/
74-
public static function _shutdownAfterDataProvider(): void
50+
#[After(10)]
51+
public static function _shutdownFoundry(): void
7552
{
76-
if (\is_subclass_of(static::class, KernelTestCase::class)) { // @phpstan-ignore function.impossibleType, function.alreadyNarrowedType
77-
self::ensureKernelShutdown(); // @phpstan-ignore staticMethod.notFound
78-
static::$class = null; // @phpstan-ignore staticProperty.notFound
79-
static::$kernel = null; // @phpstan-ignore staticProperty.notFound
80-
static::$booted = false; // @phpstan-ignore staticProperty.notFound
53+
if (FoundryExtension::isEnabled()) {
54+
return;
8155
}
56+
8257
Configuration::shutdown();
8358
}
8459

0 commit comments

Comments
 (0)