Skip to content

Commit

Permalink
feat: throw an error if Factories trait is not used in a KernelTestCase
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil committed Dec 21, 2024
1 parent 9810cbb commit 4192bc3
Show file tree
Hide file tree
Showing 21 changed files with 469 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/.phpunit.cache
/vendor/
/bin/tools/*/vendor/
/bin/tools/php-cs-fixer/composer.lock
/bin/tools/csfixer
/build/
/.php-cs-fixer.cache
/.phpunit.result.cache
Expand Down
5 changes: 5 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
\file_get_contents('https://raw.githubusercontent.com/zenstruck/.github/main/.php-cs-fixer.dist.php')
);

$finder = PhpCsFixer\Finder::create()
->in([__DIR__.'/src', __DIR__.'/tests'])
->notPath('ForceFactoriesTraitUsage')
;

try {
return require $file;
} finally {
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ parameters:
- identifier: missingType.callable
path: tests/Fixture/Maker/expected/

# not relevant for factories in EndToEnd tests
- message: '#Call to static method PHPUnit\\Framework\\Assert::assertTrue\(\) with true will always evaluate to true#'
path: tests/Fixture/ForceFactoriesTraitUsage/

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
1 change: 1 addition & 0 deletions phpunit-10.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<testsuite name="main">
<directory>tests</directory>
<exclude>tests/Integration/Migration/ResetDatabaseWithMigrationTest.php</exclude>
<exclude>tests/Fixture</exclude>
</testsuite>
<testsuite name="migrate">
<file>tests/Integration/Migration/ResetDatabaseWithMigrationTest.php</file>
Expand Down
1 change: 1 addition & 0 deletions phpunit-paratest.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<testsuite name="main">
<directory>tests</directory>
<exclude>tests/Integration/Migration/ResetDatabaseWithMigrationTest.php</exclude>
<exclude>tests/Fixture</exclude>
</testsuite>
</testsuites>
<source ignoreSuppressionOfDeprecations="true">
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<testsuite name="main">
<directory>tests</directory>
<exclude>tests/Integration/Migration/ResetDatabaseWithMigrationTest.php</exclude>
<exclude>tests/Fixture</exclude>
</testsuite>
<testsuite name="migrate">
<file>tests/Integration/Migration/ResetDatabaseWithMigrationTest.php</file>
Expand Down
21 changes: 21 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
namespace Zenstruck\Foundry;

use Faker;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Exception\FoundryNotBooted;
use Zenstruck\Foundry\Exception\PersistenceDisabled;
use Zenstruck\Foundry\Exception\PersistenceNotAvailable;
use Zenstruck\Foundry\Persistence\PersistenceManager;
use Zenstruck\Foundry\Test\Factories;

/**
* @author Kevin Bond <kevinbond@gmail.com>
Expand Down Expand Up @@ -96,6 +98,8 @@ public static function isBooted(): bool
/** @param \Closure():self|self $configuration */
public static function boot(\Closure|self $configuration): void
{
self::throwIfComingFromKernelTestCaseWithoutFactoriesTrait();

self::$instance = $configuration;
}

Expand All @@ -111,4 +115,21 @@ public static function shutdown(): void
StoryRegistry::reset();
self::$instance = null;
}

private static function throwIfComingFromKernelTestCaseWithoutFactoriesTrait(): void
{
$backTrace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); // @phpstan-ignore ekinoBannedCode.function

foreach ($backTrace as $trace) {
if (
/*'->' === ($trace['type'] ?? null)
&&*/ isset($trace['class'])
&& KernelTestCase::class !== $trace['class']
&& \is_a($trace['class'], KernelTestCase::class, true)
&& !(new \ReflectionClass($trace['class']))->hasMethod('_bootFoundry')
) {
throw new \LogicException(\sprintf('You must use the trait "%s" in "%s" in order to use Foundry.', Factories::class, $trace['class']));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = '--filter';
$_SERVER['argv'][] = 'KernelTestCaseWithBothTraits';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

.... 4 / 4 (100%)

Time: %s, Memory: %s MB

OK (4 tests, 4 assertions)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage/KernelTestCaseWithFactoriesTraitTest.php';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

.. 2 / 2 (100%)

Time: %s, Memory: %s MB

OK (2 tests, 2 assertions)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage/KernelTestCaseWithoutFactoriesTraitTest.php';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

EE 2 / 2 (100%)

Time: %s, Memory: %s MB

There were 2 errors:

1) Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\KernelTestCaseWithoutFactoriesTraitTest::test_using_foundry_without_trait_should_throw
Zenstruck\Foundry\Exception\FoundryNotBooted: Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.

%s/src/Configuration.php:%d
%s/src/ObjectFactory.php:%d
%s/src/Factory.php:%d
%s/tests/Fixture/ForceFactoriesTraitUsage/KernelTestCaseWithoutFactoriesTraitTest.php:%d

2) Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\KernelTestCaseWithoutFactoriesTraitTest::test_using_foundry_without_trait_should_throw_even_when_kernel_is_booted
LogicException: You must use the trait "Zenstruck\Foundry\Test\Factories" in "Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\KernelTestCaseWithoutFactoriesTraitTest" in order to use Foundry.

%s/src/Configuration.php:%d
%s/src/Configuration.php:%d
%s/src/ZenstruckFoundryBundle.php:%d
%s/vendor/symfony/http-kernel/Kernel.php:%d
%s/vendor/symfony/framework-bundle/Test/KernelTestCase.php:%d
%s/vendor/symfony/framework-bundle/Test/KernelTestCase.php:%d
%s/tests/Fixture/ForceFactoriesTraitUsage/KernelTestCaseWithoutFactoriesTraitTest.php:%d

ERRORS!
Tests: 2, Assertions: 0, Errors: 2.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage/KernelTestCaseWithoutFactoriesButWithResetDatabaseTraitTest.php';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

E

Time: %s, Memory: %s MB

There was 1 error:

1) Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\KernelTestCaseWithoutFactoriesButWithResetDatabaseTraitTest
LogicException: You must use the trait "Zenstruck\Foundry\Test\Factories" in "Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\KernelTestCaseWithoutFactoriesButWithResetDatabaseTraitTest" in order to use Foundry.

%s/src/Configuration.php:%d
%s/src/Configuration.php:%d
%s/src/ZenstruckFoundryBundle.php:%d
%s/vendor/symfony/http-kernel/Kernel.php:%d
%s/vendor/symfony/framework-bundle/Test/KernelTestCase.php:%d
%s/src/Test/ResetDatabase.php:%d
%s/src/Persistence/ResetDatabase/ResetDatabaseManager.php:%d
%s/src/Test/ResetDatabase.php:%d

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage/UnitTestCaseWithFactoriesTraitTest.php';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

. 1 / 1 (100%)

Time: %s, Memory: %s MB

OK (1 test, 1 assertion)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
phpunit --version
--FILE--
<?php
$_ENV['KERNEL_CLASS'] = 'Zenstruck\Foundry\Tests\Fixture\TestKernel';
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../Fixture/ForceFactoriesTraitUsage/UnitTestCaseWithoutFactoriesTraitTest.php';

require __DIR__ . '/../../bootstrap.php';

(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
?>
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.

Runtime: PHP %s

E 1 / 1 (100%)

Time: %s, Memory: %s MB

There was 1 error:

1) Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage\UnitTestCaseWithoutFactoriesTraitTest::test_should_throw
Zenstruck\Foundry\Exception\FoundryNotBooted: Foundry is not yet booted. Ensure ZenstruckFoundryBundle is enabled. If in a test, ensure your TestCase has the Factories trait.

%s/src/Configuration.php:%d
%s/src/ObjectFactory.php:%d
%s/src/Factory.php:%d
%s/tests/Fixture/ForceFactoriesTraitUsage/UnitTestCaseWithoutFactoriesTraitTest.php:%d

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

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

namespace Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;

final class KernelTestCaseWithBothTraitsInWrongOrderTest extends KernelTestCase
{
use ResetDatabase, Factories;

public function test_should_not_throw(): void
{
Object1Factory::createOne();

self::assertTrue(true);
}

public function test_should_not_throw_even_when_kernel_is_booted(): void
{
self::getContainer();

Object1Factory::createOne();

self::assertTrue(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

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

namespace Zenstruck\Foundry\Tests\Fixture\ForceFactoriesTraitUsage;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;

final class KernelTestCaseWithBothTraitsTest extends KernelTestCase
{
use Factories, ResetDatabase;

public function test_should_not_throw(): void
{
Object1Factory::createOne();

self::assertTrue(true);
}

public function test_should_not_throw_even_when_kernel_is_booted(): void
{
self::getContainer();

Object1Factory::createOne();

self::assertTrue(true);
}
}
Loading

0 comments on commit 4192bc3

Please sign in to comment.