Skip to content

Commit

Permalink
feat: allow to use Factory::create() in data provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil committed Oct 23, 2024
1 parent 68b807b commit c475210
Show file tree
Hide file tree
Showing 31 changed files with 838 additions and 190 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ DATABASE_URL="mysql://root:[email protected]:3307/foundry_test?serverVersion=5.7.42
MONGO_URL="mongodb://127.0.0.1:27018/dbName?compressors=disabled&gssapiServiceName=mongodb"
DATABASE_RESET_MODE="schema"
USE_DAMA_DOCTRINE_TEST_BUNDLE="0"
USE_FOUNDRY_PHPUNIT_EXTENSION="0"
PHPUNIT_VERSION="9"
25 changes: 23 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
tests:
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)' }}
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)' || '' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -19,6 +19,7 @@ jobs:
database: [ mysql, mongo ]
use-dama: [ 1 ]
use-migrate: [ 0 ]
use-phpunit-extension: [ 0 ]
phpunit: [ 9 ]
exclude:
- php: 8.1
Expand All @@ -32,74 +33,93 @@ jobs:
database: none
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: mysql|mongo
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: pgsql|mongo
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: pgsql
use-dama: 0
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: sqlite
use-dama: 0
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: lowest
symfony: '*'
database: sqlite
use-dama: 0
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: lowest
symfony: '*'
database: mysql
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: mysql
use-dama: 1
use-migrate: 1
use-phpunit-extension: 0
phpunit: 9
- php: 8.3
deps: highest
symfony: '*'
database: mysql|mongo
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 10
- php: 8.3
deps: highest
symfony: '*'
database: mysql|mongo
use-dama: 1
use-migrate: 0
use-phpunit-extension: 0
phpunit: 11
- php: 8.3
deps: highest
symfony: '*'
database: mysql|mongo
use-dama: 1
use-migrate: 0
use-phpunit-extension: 1
phpunit: 11
env:
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' || '' }}
MONGO_URL: ${{ contains(matrix.database, 'mongo') && 'mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb' || '' }}
USE_DAMA_DOCTRINE_TEST_BUNDLE: ${{ matrix.use-dama == 1 && contains(matrix.database, 'sql') && 1 || 0 }}
USE_FOUNDRY_PHPUNIT_EXTENSION: ${{ matrix.use-phpunit-extension }}
PHPUNIT_VERSION: ${{ matrix.phpunit }}
services:
postgres:
Expand Down Expand Up @@ -155,7 +175,8 @@ jobs:
DATABASE_URL: postgresql://root:root@localhost:5432/foundry?serverVersion=15
MONGO_URL: mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb
USE_DAMA_DOCTRINE_TEST_BUNDLE: 1
PHPUNIT_VERSION: 9
USE_FOUNDRY_PHPUNIT_EXTENSION: 1
PHPUNIT_VERSION: 11
services:
mongo:
image: mongo:4
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ parameters:
- identifier: missingType.iterableValue
path: tests/

# We support both PHPUnit versions (this method changed in PHPUnit 10)
- message: '#Call to function method_exists\(\) with .* will always evaluate to false#'
path: src/Test/Factories.php

excludePaths:
- tests/Fixture/Maker/expected/can_create_factory_with_auto_activated_not_persisted_option.php
- tests/Fixture/Maker/expected/can_create_factory_interactively.php
Expand Down
52 changes: 24 additions & 28 deletions phpunit
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ check_phpunit_version() {

REQUIRED_PHPUNIT_VERSION="${1?}"

if [[ "${INSTALLED_PHPUNIT_VERSION}" == *"dev"* ]] && [ "${REQUIRED_PHPUNIT_VERSION}" != "11.4" ]; then
echo 0;
elif [[ "${INSTALLED_PHPUNIT_VERSION}" == "${REQUIRED_PHPUNIT_VERSION}"* ]]; then
if [[ "${INSTALLED_PHPUNIT_VERSION}" == "${REQUIRED_PHPUNIT_VERSION}"* ]]; then
echo 1;
else
echo 0;
Expand All @@ -28,42 +26,34 @@ fi
### <<

### >> update PHPUnit if needed
if [[ " 9 10 11 11.4 " != *" ${PHPUNIT_VERSION-9} "* ]]; then
echo "❌ PHPUNIT_VERSION should be one of 9, 10, 11, 11.4";
if [[ " 9 10 11 " != *" ${PHPUNIT_VERSION-9} "* ]]; then
echo "❌ PHPUNIT_VERSION should be one of 9, 10, 11";
exit 1;
fi

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

if [ "${SHOULD_UPDATE_PHPUNIT}" = "0" ]; then
echo "ℹ️ Upgrading PHPUnit to ${PHPUNIT_VERSION}"
if [ "${PHPUNIT_VERSION}" = "9" ]; then
composer update phpunit/phpunit:^9 -W --dev
else
if [ "${PHPUNIT_VERSION}" = "11.4" ]; then
composer update phpunit/phpunit:11.4.x-dev -W --dev
else
composer update "phpunit/phpunit:^${PHPUNIT_VERSION}" -W --dev
fi
fi
composer update "phpunit/phpunit:^${PHPUNIT_VERSION}" -W
fi
### <<

### >> guess extensions
EXTENSION=""
### >> actually execute PHPUnit with the right options
DAMA_EXTENSION="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"
FOUNDRY_EXTENSION="Zenstruck\Foundry\PHPUnit\FoundryExtension"

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

### >> actually execute PHPUnit with the right options
case ${PHPUNIT_VERSION} in
"9")
if [ -z "${EXTENSION}" ]; then
vendor/bin/phpunit -c phpunit.xml.dist "$@"
if [ "${USE_DAMA_DOCTRINE_TEST_BUNDLE:-0}" = "1" ]; then
vendor/bin/phpunit -c phpunit.xml.dist --extensions "${DAMA_EXTENSION}" "$@"
else
vendor/bin/phpunit -c phpunit.xml.dist --extensions "${EXTENSION}" "$@"
vendor/bin/phpunit -c phpunit.xml.dist "$@"
fi
;;

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

"11"|"11.4")
if [ -z "${EXTENSION}" ]; then
vendor/bin/phpunit -c phpunit-10.xml.dist "$@"
else
vendor/bin/phpunit -c phpunit-10.xml.dist --extension "${EXTENSION}" "$@"
"11")
PHPUNIT_EXEC="vendor/bin/phpunit -c phpunit-10.xml.dist $@"
if [ "${USE_DAMA_DOCTRINE_TEST_BUNDLE:-0}" = "1" ]; then
PHPUNIT_EXEC="${PHPUNIT_EXEC} --extension "${DAMA_EXTENSION}""
fi

if [ "${USE_FOUNDRY_PHPUNIT_EXTENSION:-0}" = "1" ]; then
PHPUNIT_EXEC="${PHPUNIT_EXEC} --extension "${FOUNDRY_EXTENSION}""
fi

echo $PHPUNIT_EXEC
$PHPUNIT_EXEC
;;
esac
### <<
2 changes: 1 addition & 1 deletion phpunit-10.xml.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.4/phpunit.xsd"
bootstrap="tests/bootstrap.php"
colors="true"
failOnRisky="true"
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
bootstrap="tests/bootstrap.php"
colors="true"
failOnRisky="true"
Expand Down
18 changes: 17 additions & 1 deletion src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ final class Configuration
*/
public $instantiator;

/**
* This property is only filled if the PHPUnit extension is used!
*/
private bool $bootedForDataProvider = false;

/** @var \Closure():self|self|null */
private static \Closure|self|null $instance = null;

Expand Down Expand Up @@ -69,10 +74,15 @@ public function assertPersistanceEnabled(): void
}
}

public function inADataProvider(): bool
{
return $this->bootedForDataProvider;
}

public static function instance(): self
{
if (!self::$instance) {
throw new FoundryNotBooted('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
throw new FoundryNotBooted();
}

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

public static function bootForDataProvider(\Closure|self $configuration): void
{
self::$instance = \is_callable($configuration) ? ($configuration)() : $configuration;
self::$instance->bootedForDataProvider = true;
}

public static function shutdown(): void
{
StoryRegistry::reset();
Expand Down
4 changes: 4 additions & 0 deletions src/Exception/FoundryNotBooted.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
*/
final class FoundryNotBooted extends \LogicException
{
public function __construct()
{
parent::__construct('Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.');
}
}
30 changes: 30 additions & 0 deletions src/PHPUnit/BootFoundryOnDataProviderMethodCalled.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/*
* This file is part of the zenstruck/foundry package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Foundry\PHPUnit;

use PHPUnit\Event;

/**
* @internal
* @author Nicolas PHILIPPE <[email protected]>
*/
final class BootFoundryOnDataProviderMethodCalled implements Event\Test\DataProviderMethodCalledSubscriber
{
public function notify(Event\Test\DataProviderMethodCalled $event): void
{
if (method_exists($event->testMethod()->className(), '_bootForDataProvider')) {
call_user_func([$event->testMethod()->className(), '_bootForDataProvider']);
}
}
}
50 changes: 50 additions & 0 deletions src/PHPUnit/FoundryExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

/*
* This file is part of the zenstruck/foundry package.
*
* (c) Kevin Bond <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Foundry\PHPUnit;

use PHPUnit\Metadata\Version\ConstraintRequirement;
use PHPUnit\Runner;
use PHPUnit\TextUI;
use Zenstruck\Foundry\Configuration;

/**
* @internal
* @author Nicolas PHILIPPE <[email protected]>
*/
final class FoundryExtension implements Runner\Extension\Extension
{
public const MIN_PHPUNIT_VERSION = '11.4';

public function bootstrap(
TextUI\Configuration\Configuration $configuration,
Runner\Extension\Facade $facade,
Runner\Extension\ParameterCollection $parameters,
): void {
if (!ConstraintRequirement::from(self::MIN_PHPUNIT_VERSION)->isSatisfiedBy(Runner\Version::id())) {
throw new \LogicException(
\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)
);
}

// shutdown Foundry if for some reason it has been booted before
if (Configuration::isBooted()) {
Configuration::shutdown();
}

$facade->registerSubscribers(
new BootFoundryOnDataProviderMethodCalled(),
new ShutdownFoundryOnTestSuiteLoaded(),
);
}
}
Loading

0 comments on commit c475210

Please sign in to comment.