Skip to content

Commit 7ff5ca8

Browse files
committed
feat: deprecate ResetDatabase trait
1 parent c5183af commit 7ff5ca8

25 files changed

+511
-143
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ USE_DAMA_DOCTRINE_TEST_BUNDLE="0"
1111
USE_FOUNDRY_PHPUNIT_EXTENSION="0"
1212
USE_PHP_84_LAZY_OBJECTS="0"
1313
PHPUNIT_VERSION="12" # allowed values: 9, 10, 11, 12
14+
15+
# Only relevant for "reset-database" testsuite
16+
DATABASE_RESET_MODE="schema" # allowed values: schema, migrate

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ jobs:
133133
DATABASE_RESET_MODE: ${{ matrix.reset-database-mode == 1 && 1 || 0 }}
134134
MIGRATION_CONFIGURATION_FILE: ${{ matrix.migration-configuration-file == 'no' && '' || format('tests/Fixture/MigrationTests/configs/{0}.php', matrix.migration-configuration-file) }}
135135
PHPUNIT_VERSION: 11
136+
USE_FOUNDRY_PHPUNIT_EXTENSION: 1
136137
services:
137138
postgres:
138139
image: ${{ contains(matrix.database, 'pgsql') && 'postgres:15' || '' }}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ $ composer update
5151
# run main testsuite (with "schema" reset database strategy)
5252
$ ./phpunit
5353

54-
# run "migrate" testsuite (with "migrate" reset database strategy)
54+
# run "reset-database" testsuite
5555
$ ./phpunit --testsuite reset-database
5656
```
5757

@@ -73,6 +73,7 @@ PHPUNIT_VERSION="11" # possible values: 9, 10, 11, 11.4
7373

7474
# test reset database with migrations,
7575
# only relevant for "reset-database" testsuite
76+
DATABASE_RESET_MODE="migrate"
7677
MIGRATION_CONFIGURATION_FILE="tests/Fixture/MigrationTests/configs/migration-configuration.php"
7778

7879
# run test suite with postgreSQL

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 `ResetDatabase` trait, in favor of a `#[ResetDatabase]` attribute,
4+
along with the [PHPUnit extension](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#phpunit-extension)
5+
shipped by Foundry.
6+
7+
The trait will be removed in Foundry 3.0, and the usage of the attribute will be mandatory to reset the database in your tests.
8+
9+
> [!WARNING]
10+
> The PHPUnit extension mechanism was introduced in PHPUnit 10. This means that Foundry 3 won't be compatible
11+
> with PHPUnit 9 anymore (but Foundry 2 will remain compatible with PHPUnit 9).
12+
13+
## How to
14+
15+
> [!IMPORTANT]
16+
> If you're still not using PHPUnit 10 or grater, there is nothing to do (yet!)
17+
18+
Enable Foundry's [PHPUnit extension](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#phpunit-extension)
19+
in your `phpunit.xml` file:
20+
21+
```xml
22+
<phpunit>
23+
<extensions>
24+
<bootstrap class="Zenstruck\Foundry\PHPUnit\FoundryExtension"/>
25+
</extensions>
26+
</phpunit>
27+
```
28+
29+
And then, replace all the `use ResetDatabase;` statements by a `#[\Zenstruck\Foundry\Attribute\ResetDatabase]` attribute
30+
on your test classes. Note that you can put the attribute on a parent class, it will be inherited by all its children.
31+
32+
## Rector rules
33+
34+
A Rector set is available to automatically replace the trait by the attribute 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: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,33 +1665,46 @@ Add Foundry's `PHPUnit Extension`_ in your `phpunit.xml` file:
16651665
Database Reset
16661666
~~~~~~~~~~~~~~
16671667

1668-
This library requires that your database be reset before each test. The packaged ``ResetDatabase`` trait handles
1668+
This library requires that your database be reset before each test. The packaged ``ResetDatabase`` attribute handles
16691669
this for you.
16701670

16711671
::
16721672

16731673
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1674-
use Zenstruck\Foundry\Test\Factories;
1675-
use Zenstruck\Foundry\Test\ResetDatabase;
1674+
use Zenstruck\Foundry\Attribute\ResetDatabase;
16761675

1676+
#{ResetDatabase]
16771677
class MyTest extends WebTestCase
16781678
{
1679-
use ResetDatabase, Factories;
1680-
16811679
// ...
16821680
}
16831681

1684-
Before the first test using the ``ResetDatabase`` trait, it drops (if exists) and creates the test database.
1682+
Before the first test using the ``ResetDatabase`` attribute, it drops (if exists) and creates the test database.
16851683
Then, by default, before each test, it resets the schema using ``doctrine:schema:drop``/``doctrine:schema:create``.
16861684

1685+
.. note::
1686+
1687+
If you're still using PHPUnit 9, the database can be reset by adding the trait ``Zenstruck\Foundry\Test\ResetDatabase``::
1688+
1689+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1690+
use Zenstruck\Foundry\Test\Factories;
1691+
use Zenstruck\Foundry\Test\ResetDatabase;
1692+
1693+
class MyTest extends WebTestCase
1694+
{
1695+
use ResetDatabase, Factories;
1696+
1697+
// ...
1698+
}
1699+
16871700
.. tip::
16881701

1689-
Create a base TestCase for tests using factories to avoid adding the traits to every TestCase.
1702+
Create a base TestCase for tests using factories to avoid adding the attribute to every TestCase.
16901703

16911704
.. tip::
16921705

16931706
If your tests :ref:`are not persisting <without-persisting>` the objects they create, the ``ResetDatabase``
1694-
trait is not required.
1707+
attribute is not required.
16951708

16961709
By default, ``ResetDatabase`` resets the default configured connection's database and default configured object manager's
16971710
schema. To customize the connection's and object manager's to be reset (or reset multiple connections/managers), use the
@@ -2063,7 +2076,7 @@ Global State
20632076

20642077
If you have an initial database state you want for all tests, you can set this in the config of the bundle. Accepted
20652078
values are: stories as service, "global" stories and invokable services. Global state is loaded before each test using
2066-
the ``ResetDatabase`` trait. If you are using `DamaDoctrineTestBundle`_, it is only loaded once for the entire
2079+
the ``ResetDatabase`` attribute. If you are using `DamaDoctrineTestBundle`_, it is only loaded once for the entire
20672080
test suite.
20682081

20692082
.. configuration-block::
@@ -2086,7 +2099,7 @@ test suite.
20862099

20872100
.. note::
20882101

2089-
The :ref:`ResetDatabase <enable-foundry-in-your-testcase>` trait is required when using global state.
2102+
The :ref:`ResetDatabase <enable-foundry-in-your-testcase>` attribute is required when using global state.
20902103

20912104
.. warning::
20922105

@@ -2282,7 +2295,7 @@ This library integrates seamlessly with `DAMADoctrineTestBundle <https://github.
22822295
wrap each test in a transaction which dramatically reduces test time. This library's test suite runs 5x faster with
22832296
this bundle enabled.
22842297

2285-
Follow its documentation to install. Foundry's ``ResetDatabase`` trait detects when using the bundle and adjusts
2298+
Follow its documentation to install. Foundry's ``ResetDatabase`` attribute detects when using the bundle and adjusts
22862299
accordingly. Your database is still reset before running your test suite but the schema isn't reset before each test
22872300
(just the first).
22882301

@@ -2398,10 +2411,10 @@ Non-Kernel Tests
23982411
~~~~~~~~~~~~~~~~
23992412

24002413
Foundry can be used in standard PHPUnit unit tests (TestCase's that just extend ``PHPUnit\Framework\TestCase`` and not
2401-
``Symfony\Bundle\FrameworkBundle\Test\KernelTestCase``). These tests still require using the ``Factories`` trait to boot
2402-
Foundry but will not have doctrine available. Factories created in these tests will not be persisted (calling
2403-
``->withoutPersisting()`` is not necessary). Because the bundle is not available in these tests,
2404-
any bundle configuration you have will not be picked up.
2414+
``Symfony\Bundle\FrameworkBundle\Test\KernelTestCase``). These tests still require enabling Foundry with the PHPUnit extension
2415+
(or using the ``Factories`` trait if you still use PHPUnit 9) to boot Foundry but will not have doctrine available.
2416+
Factories created in these tests will not be persisted (calling ``->withoutPersisting()`` is not necessary). Because
2417+
the bundle is not available in these tests, any bundle configuration you have will not be picked up.
24052418

24062419
::
24072420

@@ -2627,19 +2640,19 @@ Full Default Bundle Configuration
26272640
orm:
26282641
reset:
26292642
2630-
# DBAL connections to reset with ResetDatabase trait
2643+
# DBAL connections to reset with ResetDatabase attribute
26312644
connections:
26322645
26332646
# Default:
26342647
- default
26352648
2636-
# Entity Managers to reset with ResetDatabase trait
2649+
# Entity Managers to reset with ResetDatabase attribute
26372650
entity_managers:
26382651
26392652
# Default:
26402653
- default
26412654
2642-
# Reset mode to use with ResetDatabase trait
2655+
# Reset mode to use with ResetDatabase attribute
26432656
mode: schema # One of "schema"; "migrate"
26442657
migrations:
26452658
@@ -2649,7 +2662,7 @@ Full Default Bundle Configuration
26492662
mongo:
26502663
reset:
26512664
2652-
# Document Managers to reset with ResetDatabase trait
2665+
# Document Managers to reset with ResetDatabase attribute
26532666
document_managers:
26542667
26552668
# Default:

phpunit-deprecation-baseline.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@
77
<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>
88
<issue><![CDATA[Since symfony/var-exporter 7.3: Using ProxyHelper::generateLazyGhost() is deprecated, use native lazy objects instead.]]></issue>
99
<issue><![CDATA[Since symfony/var-exporter 7.3: The "Symfony\Component\VarExporter\LazyGhostTrait" trait is deprecated, use native lazy objects instead.]]></issue>
10+
<issue><![CDATA[Since symfony/var-exporter 7.3: The "Symfony\Component\VarExporter\LazyProxyTrait" trait is deprecated, use native lazy objects instead.]]></issue>
11+
<issue><![CDATA[Since symfony/var-exporter 7.3: Generating lazy proxy for class "Zenstruck\Foundry\Tests\Fixture\Entity\GlobalEntity" is deprecated; leverage native lazy objects instead.]]></issue>
1012

1113
<issue><![CDATA[Since zenstruck/foundry 2.7: Proxy usage is deprecated in PHP 8.4. Use directly PersistentObjectFactory, Foundry now leverages the native PHP lazy system to auto-refresh objects.]]></issue>
1214
<issue><![CDATA[Since zenstruck/foundry 2.7: Proxy usage is deprecated in PHP 8.4. You should extend directly PersistentObjectFactory in your factories.
1315
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).
16+
See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.7.md to upgrade.]]></issue>
17+
<issue><![CDATA[Since zenstruck/foundry 2.7: Function proxy() is deprecated and will be removed in Foundry 3.
18+
Proxy usage is deprecated in PHP 8.4. You should extend directly PersistentObjectFactory in your factories.
19+
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).
1420
See https://github.com/zenstruck/foundry/blob/2.x/UPGRADE-2.7.md to upgrade.]]></issue>
1521

1622
<issue><![CDATA[Since zenstruck/foundry 2.8: 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.8.md to upgrade.]]></issue>

src/Attribute/ResetDatabase.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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\Attribute;
15+
16+
#[\Attribute(\Attribute::TARGET_CLASS)]
17+
final class ResetDatabase
18+
{
19+
}

src/Configuration.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +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;
2422
use Zenstruck\Foundry\Persistence\Proxy\PersistedObjectsTracker;
23+
use Zenstruck\Foundry\PHPUnit\FoundryExtension;
2524

2625
/**
2726
* @author Kevin Bond <kevinbond@gmail.com>

src/PHPUnit/AttributeReader.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the zenstruck/foundry package.
5+
*
6+
* (c) Kevin Bond <kevinbond@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Zenstruck\Foundry\PHPUnit;
13+
14+
/**
15+
* @internal
16+
* @author Nicolas PHILIPPE <nikophil@gmail.com>
17+
*/
18+
final class AttributeReader
19+
{
20+
private function __construct()
21+
{
22+
}
23+
24+
/**
25+
* @template T of object
26+
*
27+
* @param class-string<T> $attributeClass
28+
*
29+
* @return list<\ReflectionAttribute<T>>
30+
*/
31+
public static function collectAttributesFromClassAndParents(string $attributeClass, \ReflectionClass $class): array // @phpstan-ignore missingType.generics
32+
{
33+
return [
34+
...$class->getAttributes($attributeClass),
35+
...(
36+
$class->getParentClass()
37+
? self::collectAttributesFromClassAndParents($attributeClass, $class->getParentClass())
38+
: []
39+
),
40+
];
41+
}
42+
}

src/PHPUnit/BootFoundryOnPreparationStarted.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public function notify(Event\Test\PreparationStarted $event): void
3333
return;
3434
}
3535
/** @var Event\Code\TestMethod $test */
36-
3736
$this->bootFoundry($test->className());
3837
}
3938

@@ -55,11 +54,11 @@ private function bootFoundry(string $className): void
5554

5655
// integration test
5756
Configuration::boot(static function() use ($className): Configuration {
58-
if (!KernelTestCaseHelper::getContainerForTestClass($className)->has('.zenstruck_foundry.configuration')) {
57+
if (!KernelTestCaseHelper::getContainer($className)->has('.zenstruck_foundry.configuration')) {
5958
throw new \LogicException('ZenstruckFoundryBundle is not enabled. Ensure it is added to your config/bundles.php.');
6059
}
6160

62-
return KernelTestCaseHelper::getContainerForTestClass($className)->get('.zenstruck_foundry.configuration'); // @phpstan-ignore return.type
61+
return KernelTestCaseHelper::getContainer($className)->get('.zenstruck_foundry.configuration'); // @phpstan-ignore return.type
6362
});
6463
}
6564
}

0 commit comments

Comments
 (0)