Skip to content

Commit 486c21d

Browse files
committed
feat: deprecate ResetDatabase trait
1 parent bb8a6b1 commit 486c21d

26 files changed

+512
-145
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
@@ -1650,33 +1650,46 @@ Add Foundry's `PHPUnit Extension`_ in your `phpunit.xml` file:
16501650
Database Reset
16511651
~~~~~~~~~~~~~~
16521652

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

16561656
::
16571657

16581658
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1659-
use Zenstruck\Foundry\Test\Factories;
1660-
use Zenstruck\Foundry\Test\ResetDatabase;
1659+
use Zenstruck\Foundry\Attribute\ResetDatabase;
16611660

1661+
#{ResetDatabase]
16621662
class MyTest extends WebTestCase
16631663
{
1664-
use ResetDatabase, Factories;
1665-
16661664
// ...
16671665
}
16681666

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

1670+
.. note::
1671+
1672+
If you're still using PHPUnit 9, the database can be reset by adding the trait ``Zenstruck\Foundry\Test\ResetDatabase``::
1673+
1674+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
1675+
use Zenstruck\Foundry\Test\Factories;
1676+
use Zenstruck\Foundry\Test\ResetDatabase;
1677+
1678+
class MyTest extends WebTestCase
1679+
{
1680+
use ResetDatabase, Factories;
1681+
1682+
// ...
1683+
}
1684+
16721685
.. tip::
16731686

1674-
Create a base TestCase for tests using factories to avoid adding the traits to every TestCase.
1687+
Create a base TestCase for tests using factories to avoid adding the attribute to every TestCase.
16751688

16761689
.. tip::
16771690

16781691
If your tests :ref:`are not persisting <without-persisting>` the objects they create, the ``ResetDatabase``
1679-
trait is not required.
1692+
attribute is not required.
16801693

16811694
By default, ``ResetDatabase`` resets the default configured connection's database and default configured object manager's
16821695
schema. To customize the connection's and object manager's to be reset (or reset multiple connections/managers), use the
@@ -2048,7 +2061,7 @@ Global State
20482061

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

20542067
.. configuration-block::
@@ -2071,7 +2084,7 @@ test suite.
20712084

20722085
.. note::
20732086

2074-
The :ref:`ResetDatabase <enable-foundry-in-your-testcase>` trait is required when using global state.
2087+
The :ref:`ResetDatabase <enable-foundry-in-your-testcase>` attribute is required when using global state.
20752088

20762089
.. warning::
20772090

@@ -2267,7 +2280,7 @@ This library integrates seamlessly with `DAMADoctrineTestBundle <https://github.
22672280
wrap each test in a transaction which dramatically reduces test time. This library's test suite runs 5x faster with
22682281
this bundle enabled.
22692282

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

@@ -2383,10 +2396,10 @@ Non-Kernel Tests
23832396
~~~~~~~~~~~~~~~~
23842397

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

23912404
::
23922405

@@ -2612,19 +2625,19 @@ Full Default Bundle Configuration
26122625
orm:
26132626
reset:
26142627
2615-
# DBAL connections to reset with ResetDatabase trait
2628+
# DBAL connections to reset with ResetDatabase attribute
26162629
connections:
26172630
26182631
# Default:
26192632
- default
26202633
2621-
# Entity Managers to reset with ResetDatabase trait
2634+
# Entity Managers to reset with ResetDatabase attribute
26222635
entity_managers:
26232636
26242637
# Default:
26252638
- default
26262639
2627-
# Reset mode to use with ResetDatabase trait
2640+
# Reset mode to use with ResetDatabase attribute
26282641
mode: schema # One of "schema"; "migrate"
26292642
migrations:
26302643
@@ -2634,7 +2647,7 @@ Full Default Bundle Configuration
26342647
mongo:
26352648
reset:
26362649
2637-
# Document Managers to reset with ResetDatabase trait
2650+
# Document Managers to reset with ResetDatabase attribute
26382651
document_managers:
26392652
26402653
# 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
<issue><![CDATA[Since zenstruck/foundry 2.8: Trait Zenstruck\Foundry\Test\Factories is deprecated and will be removed in Foundry 3.]]></issue>
1622
<issue><![CDATA[Since zenstruck/foundry 2.8: Not using Foundry's PHPUnit extension is deprecated and will throw an error in Foundry 3.]]></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)