Skip to content

Commit 08da3d3

Browse files
committed
feat: force PHPUnit extension usage
1 parent 0685fa8 commit 08da3d3

File tree

51 files changed

+1103
-578
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1103
-578
lines changed

.github/workflows/phpunit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ jobs:
213213
strategy:
214214
fail-fast: false
215215
matrix:
216-
php: [ 8.1, 8.2, 8.3, 8.4 ]
216+
php: [ 8.2, 8.3, 8.4 ]
217217
steps:
218218
- name: Checkout code
219219
uses: actions/checkout@v3
@@ -244,7 +244,7 @@ jobs:
244244
245245
- name: Test
246246
run: |
247-
vendor/bin/phpunit tests/Unit --exclude-group legacy-proxy
247+
vendor/bin/phpunit tests/Unit
248248
249249
test-with-paratest:
250250
name: Test with paratest

UPGRADE-2.7.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ return RectorConfig::configure()
5252
'src',
5353
'tests'
5454
])
55-
->withSets([FoundrySetList::REMOVE_PROXIES])
55+
->withSets([FoundrySetList::FOUNDRY_2_7])
5656
;
5757
```
5858

UPGRADE-2.9.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Migration guide from Foundry 2.8 to 2.9
2+
3+
The main feature of Foundry 2.9 is the deprecation of the `Factories` trait, in favor of the [PHPUnit extension](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#phpunit-extension)
4+
shipped by Foundry. It was necessary to remember to add the trait in every test class. And in some cases, Foundry could
5+
still work even if the trait wasn’t added to the test, which could lead to subtle bugs. Now, Foundry is globally enabled
6+
once for all.
7+
8+
The trait will be removed in Foundry 3.0, and the extension will be mandatory.
9+
10+
> [!WARNING]
11+
> The PHPUnit extension mechanism was introduced in PHPUnit 10. This means that Foundry 3 won't be compatible
12+
> with PHPUnit 9 anymore (but Foundry 2 will remain compatible with PHPUnit 9).
13+
14+
## How to
15+
16+
> [!IMPORTANT]
17+
> If you're still not using PHPUnit 10 or grater, there is nothing to do (yet!)
18+
19+
Enable Foundry's [PHPUnit extension](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#phpunit-extension)
20+
in your `phpunit.xml` file:
21+
22+
```xml
23+
<phpunit>
24+
<extensions>
25+
<bootstrap class="Zenstruck\Foundry\PHPUnit\FoundryExtension"/>
26+
</extensions>
27+
</phpunit>
28+
```
29+
30+
And then, remove all the `use Factories;` statements from your factories.
31+
32+
## Rector rules
33+
34+
A Rector set is available to automatically remove the usage of the trait in all your tests.
35+
36+
First, you'll need to install `rector/rector`:
37+
```shell
38+
composer require --dev rector/rector
39+
```
40+
41+
Then, create a `rector.php` file:
42+
43+
```php
44+
<?php
45+
46+
use Rector\Config\RectorConfig;
47+
use Zenstruck\Foundry\Utils\Rector\FoundrySetList;
48+
49+
return RectorConfig::configure()
50+
->withPaths(['tests'])
51+
->withSets([FoundrySetList::FOUNDRY_2_9])
52+
;
53+
```

docs/index.rst

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,28 +1683,46 @@ Let's look at an example:
16831683

16841684
.. _enable-foundry-in-your-testcase:
16851685

1686-
Enable Foundry in your TestCase
1687-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1686+
Globally Enable Foundry In PHPUnit
1687+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16881688

1689-
Add the ``Factories`` trait for tests using factories:
1689+
Add Foundry's `PHPUnit Extension`_ in your `phpunit.xml` file:
16901690

1691-
::
1691+
.. configuration-block::
16921692

1693-
use App\Factory\PostFactory;
1694-
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1695-
use Zenstruck\Foundry\Test\Factories;
1693+
.. code-block:: xml
16961694
1697-
class MyTest extends WebTestCase
1698-
{
1699-
use Factories;
1695+
<phpunit>
1696+
<extensions>
1697+
<bootstrap class="Zenstruck\Foundry\PHPUnit\FoundryExtension"/>
1698+
</extensions>
1699+
</phpunit>
1700+
1701+
.. versionadded:: 2.9
17001702

1701-
public function test_1(): void
1703+
The ability to globally enable Foundry with PHPUnit extension was introduced in Foundry 2.9 and requires at least
1704+
PHPUnit 10.
1705+
1706+
.. note::
1707+
1708+
If you're still using PHPUnit 9, Foundry can be enabled by adding the trait ``Zenstruck\Foundry\Test\Factories``
1709+
in each test::
1710+
1711+
use App\Factory\PostFactory;
1712+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1713+
use Zenstruck\Foundry\Test\Factories;
1714+
1715+
class MyTest extends WebTestCase
17021716
{
1703-
$post = PostFactory::createOne();
1717+
use Factories;
17041718

1705-
// ...
1719+
public function test_something(): void
1720+
{
1721+
$post = PostFactory::createOne();
1722+
1723+
// ...
1724+
}
17061725
}
1707-
}
17081726

17091727
Database Reset
17101728
~~~~~~~~~~~~~~
@@ -1857,7 +1875,7 @@ Foundry provides a mechanism to automatically refresh inside a functional test t
18571875

18581876
class MyTest extends WebTestCase
18591877
{
1860-
use Factories, ResetDatabase;
1878+
use ResetDatabase;
18611879

18621880
public function test_with_autorefresh(): void
18631881
{
@@ -2455,8 +2473,6 @@ any bundle configuration you have will not be picked up.
24552473

24562474
class MyUnitTest extends TestCase
24572475
{
2458-
use Factories;
2459-
24602476
public function some_test(): void
24612477
{
24622478
$post = PostFactory::createOne();

phpstan.neon

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ parameters:
3030
- identifier: missingType.iterableValue
3131
path: tests/
3232

33-
# We support both PHPUnit versions (this method changed in PHPUnit 10)
34-
- identifier: function.impossibleType
35-
path: src/Test/Factories.php
36-
3733
# PHPStan does not understand PHP version checks
3834
- message: '#Comparison operation "(<|>|<=|>=)" between int<80\d+, 80\d+> and 80\d+ is always (false|true).#'
3935

phpunit

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,6 @@ check_phpunit_version() {
1717
fi
1818
}
1919

20-
can_use_legacy_proxies() {
21-
INSTALLED_SYMFONY_VERSION=$(${COMPOSER_BIN} info symfony/var-exporter | grep versions | cut -c 15-)
22-
23-
if [[ "${INSTALLED_SYMFONY_VERSION}" == "8"* ]]; then
24-
echo 0;
25-
else
26-
echo 1;
27-
fi
28-
}
29-
3020
### >> load env vars from .env files if not in CI and not from a composer script
3121
if [ -z "${CI:-}" ] ; then
3222
source .env

phpunit-deprecation-baseline.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
Foundry now leverages the native PHP lazy system to auto-refresh objects (it can be enabled with "zenstruck_foundry.enable_auto_refresh_with_lazy_objects" configuration).
1515
See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.7.md to upgrade.]]></issue>
1616

17-
<issue><![CDATA[Support for MySQL < 8 is deprecated and will be removed in DBAL 5 (AbstractMySQLDriver.php:75 called by AbstractDriverMiddleware.php:32, https://github.com/doctrine/dbal/pull/6343, package doctrine/dbal)]]></issue>
17+
<issue><![CDATA[Since zenstruck/foundry 2.9: Trait Zenstruck\Foundry\Test\Factories is deprecated and will be removed in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.]]></issue>
18+
<issue><![CDATA[Since zenstruck/foundry 2.9: Not using Foundry's PHPUnit extension is deprecated and will throw an error in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.]]></issue>
19+
1820
<issue><![CDATA[Since doctrine/mongodb-odm 2.14: Not using native lazy objects is deprecated and will be impossible in Doctrine MongoDB ODM 3.0.]]></issue>
1921
<issue><![CDATA[Since symfony/framework-bundle 7.3: Not setting the "property_info.with_constructor_extractor" option explicitly is deprecated because its default value will change in version 8.0.]]></issue>
2022
<issue><![CDATA[Since symfony/console 7.4: The "Symfony\Component\Console\Application::add()" method is deprecated and will be removed in Symfony 8.0, use "Symfony\Component\Console\Application::addCommand()" instead.]]></issue>

src/Configuration.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Zenstruck\Foundry\InMemory\InMemoryRepositoryRegistry;
2222
use Zenstruck\Foundry\Persistence\PersistedObjectsTracker;
2323
use Zenstruck\Foundry\Persistence\PersistenceManager;
24+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
2425

2526
/**
2627
* @author Kevin Bond <[email protected]>
@@ -129,7 +130,9 @@ public static function instance(): self
129130
throw new FoundryNotBooted();
130131
}
131132

132-
FactoriesTraitNotUsed::throwIfComingFromKernelTestCaseWithoutFactoriesTrait();
133+
if (!FoundryExtension::isEnabled()) {
134+
FactoriesTraitNotUsed::throwIfComingFromKernelTestCaseWithoutFactoriesTrait();
135+
}
133136

134137
return \is_callable(self::$instance) ? (self::$instance)() : self::$instance;
135138
}
@@ -143,6 +146,10 @@ public static function isBooted(): bool
143146
public static function boot(\Closure|self $configuration): void
144147
{
145148
self::$instance = $configuration;
149+
150+
if (FoundryExtension::shouldBeEnabled()) {
151+
trigger_deprecation('zenstruck/foundry', '2.9', 'Not using Foundry\'s PHPUnit extension is deprecated and will throw an error in Foundry 3. See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.9.md to upgrade.');
152+
}
146153
}
147154

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

src/Exception/FoundryNotBooted.php

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

1212
namespace Zenstruck\Foundry\Exception;
1313

14+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
15+
1416
/**
1517
* @author Kevin Bond <[email protected]>
1618
*/
1719
final class FoundryNotBooted extends \LogicException
1820
{
1921
public function __construct()
2022
{
21-
parent::__construct('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
23+
$message = FoundryExtension::shouldBeEnabled()
24+
? 'Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure Foundry\'s PHPUnit extension is enabled.'
25+
: 'Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.';
26+
27+
parent::__construct($message);
2228
}
2329
}

src/FactoryCollection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public static function range(Factory $factory, int $min, int $max): self
125125
throw new \InvalidArgumentException('Min must be less than max.');
126126
}
127127

128+
if ($factory instanceof PersistentObjectFactory && $factory->isPersisting() && Configuration::instance()->inADataProvider()) {
129+
throw new \InvalidArgumentException('Using randomized "range" factory in data provider is not supported.');
130+
}
131+
128132
return new self($factory, static fn() => \array_fill(0, \mt_rand($min, $max), []));
129133
}
130134

0 commit comments

Comments
 (0)