Skip to content

Commit c475210

Browse files
committed
feat: allow to use Factory::create() in data provider
1 parent 68b807b commit c475210

31 files changed

+838
-190
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ DATABASE_URL="mysql://root:[email protected]:3307/foundry_test?serverVersion=5.7.42
22
MONGO_URL="mongodb://127.0.0.1:27018/dbName?compressors=disabled&gssapiServiceName=mongodb"
33
DATABASE_RESET_MODE="schema"
44
USE_DAMA_DOCTRINE_TEST_BUNDLE="0"
5+
USE_FOUNDRY_PHPUNIT_EXTENSION="0"
56
PHPUNIT_VERSION="9"

.github/workflows/ci.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
jobs:
1010
tests:
11-
name: P:${{ matrix.php }}, S:${{ matrix.symfony }}, D:${{ matrix.database }}, PU:${{ matrix.phpunit }}${{ matrix.deps == 'lowest' && ' (lowest)' || '' }}${{ matrix.use-dama == 1 && contains(matrix.database, 'sql') && ' (dama)' || '' }}${{ !contains(matrix.database, 'sql') && '' || matrix.use-migrate == 1 && ' (migrate)' || ' (schema)' }}
11+
name: P:${{ matrix.php }}, S:${{ matrix.symfony }}, D:${{ matrix.database }}, PU:${{ matrix.phpunit }}${{ matrix.deps == 'lowest' && ' (lowest)' || '' }}${{ matrix.use-dama == 1 && contains(matrix.database, 'sql') && ' (dama)' || '' }}${{ !contains(matrix.database, 'sql') && '' || matrix.use-migrate == 1 && ' (migrate)' || ' (schema)' }}${{ matrix.use-phpunit-extension == 1 && ' (phpunit extension)' || '' }}
1212
runs-on: ubuntu-latest
1313
strategy:
1414
fail-fast: false
@@ -19,6 +19,7 @@ jobs:
1919
database: [ mysql, mongo ]
2020
use-dama: [ 1 ]
2121
use-migrate: [ 0 ]
22+
use-phpunit-extension: [ 0 ]
2223
phpunit: [ 9 ]
2324
exclude:
2425
- php: 8.1
@@ -32,74 +33,93 @@ jobs:
3233
database: none
3334
use-dama: 1
3435
use-migrate: 0
36+
use-phpunit-extension: 0
3537
phpunit: 9
3638
- php: 8.3
3739
deps: highest
3840
symfony: '*'
3941
database: mysql|mongo
4042
use-dama: 1
4143
use-migrate: 0
44+
use-phpunit-extension: 0
4245
phpunit: 9
4346
- php: 8.3
4447
deps: highest
4548
symfony: '*'
4649
database: pgsql|mongo
4750
use-dama: 1
4851
use-migrate: 0
52+
use-phpunit-extension: 0
4953
phpunit: 9
5054
- php: 8.3
5155
deps: highest
5256
symfony: '*'
5357
database: pgsql
5458
use-dama: 0
5559
use-migrate: 0
60+
use-phpunit-extension: 0
5661
phpunit: 9
5762
- php: 8.3
5863
deps: highest
5964
symfony: '*'
6065
database: sqlite
6166
use-dama: 0
6267
use-migrate: 0
68+
use-phpunit-extension: 0
6369
phpunit: 9
6470
- php: 8.3
6571
deps: lowest
6672
symfony: '*'
6773
database: sqlite
6874
use-dama: 0
6975
use-migrate: 0
76+
use-phpunit-extension: 0
7077
phpunit: 9
7178
- php: 8.3
7279
deps: lowest
7380
symfony: '*'
7481
database: mysql
7582
use-dama: 1
7683
use-migrate: 0
84+
use-phpunit-extension: 0
7785
phpunit: 9
7886
- php: 8.3
7987
deps: highest
8088
symfony: '*'
8189
database: mysql
8290
use-dama: 1
8391
use-migrate: 1
92+
use-phpunit-extension: 0
8493
phpunit: 9
8594
- php: 8.3
8695
deps: highest
8796
symfony: '*'
8897
database: mysql|mongo
8998
use-dama: 1
9099
use-migrate: 0
100+
use-phpunit-extension: 0
91101
phpunit: 10
92102
- php: 8.3
93103
deps: highest
94104
symfony: '*'
95105
database: mysql|mongo
96106
use-dama: 1
97107
use-migrate: 0
108+
use-phpunit-extension: 0
109+
phpunit: 11
110+
- php: 8.3
111+
deps: highest
112+
symfony: '*'
113+
database: mysql|mongo
114+
use-dama: 1
115+
use-migrate: 0
116+
use-phpunit-extension: 1
98117
phpunit: 11
99118
env:
100119
DATABASE_URL: ${{ contains(matrix.database, 'mysql') && 'mysql://root:root@localhost:3306/foundry?serverVersion=5.7.42' || contains(matrix.database, 'pgsql') && 'postgresql://root:root@localhost:5432/foundry?serverVersion=15' || contains(matrix.database, 'sqlite') && 'sqlite:///%kernel.project_dir%/var/data.db' || '' }}
101120
MONGO_URL: ${{ contains(matrix.database, 'mongo') && 'mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb' || '' }}
102121
USE_DAMA_DOCTRINE_TEST_BUNDLE: ${{ matrix.use-dama == 1 && contains(matrix.database, 'sql') && 1 || 0 }}
122+
USE_FOUNDRY_PHPUNIT_EXTENSION: ${{ matrix.use-phpunit-extension }}
103123
PHPUNIT_VERSION: ${{ matrix.phpunit }}
104124
services:
105125
postgres:
@@ -155,7 +175,8 @@ jobs:
155175
DATABASE_URL: postgresql://root:root@localhost:5432/foundry?serverVersion=15
156176
MONGO_URL: mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb
157177
USE_DAMA_DOCTRINE_TEST_BUNDLE: 1
158-
PHPUNIT_VERSION: 9
178+
USE_FOUNDRY_PHPUNIT_EXTENSION: 1
179+
PHPUNIT_VERSION: 11
159180
services:
160181
mongo:
161182
image: mongo:4

phpstan.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ parameters:
1414
- identifier: missingType.iterableValue
1515
path: tests/
1616

17+
# We support both PHPUnit versions (this method changed in PHPUnit 10)
18+
- message: '#Call to function method_exists\(\) with .* will always evaluate to false#'
19+
path: src/Test/Factories.php
20+
1721
excludePaths:
1822
- tests/Fixture/Maker/expected/can_create_factory_with_auto_activated_not_persisted_option.php
1923
- tests/Fixture/Maker/expected/can_create_factory_interactively.php

phpunit

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ check_phpunit_version() {
88

99
REQUIRED_PHPUNIT_VERSION="${1?}"
1010

11-
if [[ "${INSTALLED_PHPUNIT_VERSION}" == *"dev"* ]] && [ "${REQUIRED_PHPUNIT_VERSION}" != "11.4" ]; then
12-
echo 0;
13-
elif [[ "${INSTALLED_PHPUNIT_VERSION}" == "${REQUIRED_PHPUNIT_VERSION}"* ]]; then
11+
if [[ "${INSTALLED_PHPUNIT_VERSION}" == "${REQUIRED_PHPUNIT_VERSION}"* ]]; then
1412
echo 1;
1513
else
1614
echo 0;
@@ -28,42 +26,34 @@ fi
2826
### <<
2927

3028
### >> update PHPUnit if needed
31-
if [[ " 9 10 11 11.4 " != *" ${PHPUNIT_VERSION-9} "* ]]; then
32-
echo "❌ PHPUNIT_VERSION should be one of 9, 10, 11, 11.4";
29+
if [[ " 9 10 11 " != *" ${PHPUNIT_VERSION-9} "* ]]; then
30+
echo "❌ PHPUNIT_VERSION should be one of 9, 10, 11";
3331
exit 1;
3432
fi
3533

3634
SHOULD_UPDATE_PHPUNIT=$(check_phpunit_version "${PHPUNIT_VERSION}")
3735

3836
if [ "${SHOULD_UPDATE_PHPUNIT}" = "0" ]; then
3937
echo "ℹ️ Upgrading PHPUnit to ${PHPUNIT_VERSION}"
40-
if [ "${PHPUNIT_VERSION}" = "9" ]; then
41-
composer update phpunit/phpunit:^9 -W --dev
42-
else
43-
if [ "${PHPUNIT_VERSION}" = "11.4" ]; then
44-
composer update phpunit/phpunit:11.4.x-dev -W --dev
45-
else
46-
composer update "phpunit/phpunit:^${PHPUNIT_VERSION}" -W --dev
47-
fi
48-
fi
38+
composer update "phpunit/phpunit:^${PHPUNIT_VERSION}" -W
4939
fi
5040
### <<
5141

52-
### >> guess extensions
53-
EXTENSION=""
42+
### >> actually execute PHPUnit with the right options
43+
DAMA_EXTENSION="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"
44+
FOUNDRY_EXTENSION="Zenstruck\Foundry\PHPUnit\FoundryExtension"
5445

55-
if [ "${USE_DAMA_DOCTRINE_TEST_BUNDLE:-0}" = "1" ]; then
56-
EXTENSION="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"
46+
if [ "${USE_FOUNDRY_PHPUNIT_EXTENSION:-0}" = "1" ] && [ "${PHPUNIT_VERSION}" != "11" ]; then
47+
echo "❌ USE_FOUNDRY_PHPUNIT_EXTENSION could only be used with PHPUNIT_VERSION=11";
48+
exit 1;
5749
fi
58-
### <<
5950

60-
### >> actually execute PHPUnit with the right options
6151
case ${PHPUNIT_VERSION} in
6252
"9")
63-
if [ -z "${EXTENSION}" ]; then
64-
vendor/bin/phpunit -c phpunit.xml.dist "$@"
53+
if [ "${USE_DAMA_DOCTRINE_TEST_BUNDLE:-0}" = "1" ]; then
54+
vendor/bin/phpunit -c phpunit.xml.dist --extensions "${DAMA_EXTENSION}" "$@"
6555
else
66-
vendor/bin/phpunit -c phpunit.xml.dist --extensions "${EXTENSION}" "$@"
56+
vendor/bin/phpunit -c phpunit.xml.dist "$@"
6757
fi
6858
;;
6959

@@ -72,12 +62,18 @@ case ${PHPUNIT_VERSION} in
7262
vendor/bin/phpunit -c phpunit-10.xml.dist "$@"
7363
;;
7464

75-
"11"|"11.4")
76-
if [ -z "${EXTENSION}" ]; then
77-
vendor/bin/phpunit -c phpunit-10.xml.dist "$@"
78-
else
79-
vendor/bin/phpunit -c phpunit-10.xml.dist --extension "${EXTENSION}" "$@"
65+
"11")
66+
PHPUNIT_EXEC="vendor/bin/phpunit -c phpunit-10.xml.dist $@"
67+
if [ "${USE_DAMA_DOCTRINE_TEST_BUNDLE:-0}" = "1" ]; then
68+
PHPUNIT_EXEC="${PHPUNIT_EXEC} --extension "${DAMA_EXTENSION}""
8069
fi
70+
71+
if [ "${USE_FOUNDRY_PHPUNIT_EXTENSION:-0}" = "1" ]; then
72+
PHPUNIT_EXEC="${PHPUNIT_EXEC} --extension "${FOUNDRY_EXTENSION}""
73+
fi
74+
75+
echo $PHPUNIT_EXEC
76+
$PHPUNIT_EXEC
8177
;;
8278
esac
8379
### <<

phpunit-10.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
33
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
4+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.4/phpunit.xsd"
55
bootstrap="tests/bootstrap.php"
66
colors="true"
77
failOnRisky="true"

phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
44
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
5+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
66
bootstrap="tests/bootstrap.php"
77
colors="true"
88
failOnRisky="true"

src/Configuration.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ final class Configuration
3333
*/
3434
public $instantiator;
3535

36+
/**
37+
* This property is only filled if the PHPUnit extension is used!
38+
*/
39+
private bool $bootedForDataProvider = false;
40+
3641
/** @var \Closure():self|self|null */
3742
private static \Closure|self|null $instance = null;
3843

@@ -69,10 +74,15 @@ public function assertPersistanceEnabled(): void
6974
}
7075
}
7176

77+
public function inADataProvider(): bool
78+
{
79+
return $this->bootedForDataProvider;
80+
}
81+
7282
public static function instance(): self
7383
{
7484
if (!self::$instance) {
75-
throw new FoundryNotBooted('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
85+
throw new FoundryNotBooted();
7686
}
7787

7888
return \is_callable(self::$instance) ? (self::$instance)() : self::$instance;
@@ -88,6 +98,12 @@ public static function boot(\Closure|self $configuration): void
8898
self::$instance = $configuration;
8999
}
90100

101+
public static function bootForDataProvider(\Closure|self $configuration): void
102+
{
103+
self::$instance = \is_callable($configuration) ? ($configuration)() : $configuration;
104+
self::$instance->bootedForDataProvider = true;
105+
}
106+
91107
public static function shutdown(): void
92108
{
93109
StoryRegistry::reset();

src/Exception/FoundryNotBooted.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@
1616
*/
1717
final class FoundryNotBooted extends \LogicException
1818
{
19+
public function __construct()
20+
{
21+
parent::__construct('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
22+
}
1923
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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\PHPUnit;
15+
16+
use PHPUnit\Event;
17+
18+
/**
19+
* @internal
20+
* @author Nicolas PHILIPPE <[email protected]>
21+
*/
22+
final class BootFoundryOnDataProviderMethodCalled implements Event\Test\DataProviderMethodCalledSubscriber
23+
{
24+
public function notify(Event\Test\DataProviderMethodCalled $event): void
25+
{
26+
if (method_exists($event->testMethod()->className(), '_bootForDataProvider')) {
27+
call_user_func([$event->testMethod()->className(), '_bootForDataProvider']);
28+
}
29+
}
30+
}

src/PHPUnit/FoundryExtension.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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\PHPUnit;
15+
16+
use PHPUnit\Metadata\Version\ConstraintRequirement;
17+
use PHPUnit\Runner;
18+
use PHPUnit\TextUI;
19+
use Zenstruck\Foundry\Configuration;
20+
21+
/**
22+
* @internal
23+
* @author Nicolas PHILIPPE <[email protected]>
24+
*/
25+
final class FoundryExtension implements Runner\Extension\Extension
26+
{
27+
public const MIN_PHPUNIT_VERSION = '11.4';
28+
29+
public function bootstrap(
30+
TextUI\Configuration\Configuration $configuration,
31+
Runner\Extension\Facade $facade,
32+
Runner\Extension\ParameterCollection $parameters,
33+
): void {
34+
if (!ConstraintRequirement::from(self::MIN_PHPUNIT_VERSION)->isSatisfiedBy(Runner\Version::id())) {
35+
throw new \LogicException(
36+
\sprintf('Your PHPUnit version (%s) is not compatible with the minimum version (%s) needed to use this extension.', Runner\Version::id(), self::MIN_PHPUNIT_VERSION)
37+
);
38+
}
39+
40+
// shutdown Foundry if for some reason it has been booted before
41+
if (Configuration::isBooted()) {
42+
Configuration::shutdown();
43+
}
44+
45+
$facade->registerSubscribers(
46+
new BootFoundryOnDataProviderMethodCalled(),
47+
new ShutdownFoundryOnTestSuiteLoaded(),
48+
);
49+
}
50+
}

0 commit comments

Comments
 (0)