Merge remote-tracking branch 'origin/3.6.x' into 4.0.x

This commit is contained in:
Grégoire Paris
2024-05-02 21:24:41 +02:00
35 changed files with 134 additions and 82 deletions

2
.gitattributes vendored
View File

@@ -1,7 +1,7 @@
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/Tests export-ignore
/tests export-ignore
/phpcs.xml.dist export-ignore
/phpunit.xml.dist export-ignore
/phpstan.neon.dist export-ignore

View File

@@ -12,4 +12,4 @@ on:
jobs:
coding-standards:
name: "Coding Standards"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@3.1.0"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@4.0.0"

View File

@@ -8,7 +8,7 @@ on:
jobs:
release:
name: "Git tag, release & create merge-up PR"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@3.1.0"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@4.0.0"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}

View File

@@ -11,4 +11,4 @@ on:
jobs:
static-analysis:
uses: "doctrine/.github/.github/workflows/static-analysis.yml@3.1.0"
uses: "doctrine/.github/.github/workflows/static-analysis.yml@4.0.0"

View File

@@ -1,4 +1,4 @@
branches: ["3.3.x", "3.4.x", "3.5.x", "3.6.x"]
maintained_branches: ["3.5.x", "3.6.x"]
doc_dir: "Resources/doc/"
doc_dir: {"3.5.x": "Resources/doc/", "3.6.x": "docs/"}
dev_branch: "3.6.x"

View File

@@ -1,14 +0,0 @@
CHANGELOG for 3.1.x
===================
This changelog references the relevant changes (bug and security fixes) done in
3.1 minor versions.
3.1.0 (2018-12-21)
------------------
- [270: Show the name of the database being purged when loading fixtures](https://github.com/doctrine/DoctrineFixturesBundle/pull/270) thanks to @alcaeus
- [265: Drop support for PHP < 7.1 and older versions of data-fixtures](https://github.com/doctrine/DoctrineFixturesBundle/pull/265) thanks to @alcaeus
- [260: Add fixture groups via a static method interface or service tags](https://github.com/doctrine/DoctrineFixturesBundle/pull/260) thanks to @weaverryan
- [269: Apply Doctrine Coding Standard](https://github.com/doctrine/DoctrineFixturesBundle/pull/269) thanks to @carusogabriel
- [219: Dynamic namespace](https://github.com/doctrine/DoctrineFixturesBundle/issues/219) thanks to @MassiveHiggsField

View File

@@ -43,7 +43,10 @@
"doctrine/dbal": "< 3"
},
"autoload": {
"psr-4": { "Doctrine\\Bundle\\FixturesBundle\\": "" }
"psr-4": { "Doctrine\\Bundle\\FixturesBundle\\": "src" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Bundle\\FixturesBundle\\Tests\\": "tests" }
},
"config": {
"sort-packages": true,

View File

@@ -412,7 +412,7 @@ First, add a new ``PSR-4`` autoload-entry in the ``composer.json`` with the new
.. note::
You need to dump the autoloader with ``composer dump-autoloader``
You need to dump the autoloader with ``composer dump-autoload``
Then, enable Dependency Injection for the ``fixtures`` directory:

View File

@@ -11,22 +11,22 @@
<!-- Ignore warnings and show progress of the run -->
<arg value="nps"/>
<file>.</file>
<exclude-pattern>/vendor</exclude-pattern>
<file>src</file>
<file>tests</file>
<rule ref="Doctrine" />
<rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix">
<exclude-pattern>FixtureGroupInterface.php</exclude-pattern>
<exclude-pattern>ORMFixtureInterface.php</exclude-pattern>
<exclude-pattern>src/FixtureGroupInterface.php</exclude-pattern>
<exclude-pattern>src/ORMFixtureInterface.php</exclude-pattern>
</rule>
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>Loader/SymfonyBridgeLoader.php</exclude-pattern>
<exclude-pattern>Command/CommandCompatibility.php</exclude-pattern>
<exclude-pattern>Tests/IntegrationTest.php</exclude-pattern>
<exclude-pattern>src/Loader/SymfonyBridgeLoader.php</exclude-pattern>
<exclude-pattern>src/Command/CommandCompatibility.php</exclude-pattern>
<exclude-pattern>tests/IntegrationTest.php</exclude-pattern>
</rule>
<rule ref="Squiz.Classes.ClassFileName.NoMatch">
<exclude-pattern>Tests/IntegrationTest.php</exclude-pattern>
<exclude-pattern>tests/IntegrationTest.php</exclude-pattern>
</rule>
</ruleset>

View File

@@ -1,7 +1,30 @@
parameters:
excludePaths:
# Contains an error that is impossible to ignore
- tests/IntegrationTest.php
ignoreErrors:
-
message: "#^Call to an undefined method Doctrine\\\\Bundle\\\\FixturesBundle\\\\Loader\\\\SymfonyFixturesLoader\\:\\:getFixture\\(\\)\\.$#"
count: 1
path: src/Loader/SymfonyFixturesLoader.php
-
message: "#^Call to an undefined static method Doctrine\\\\Bundle\\\\FixturesBundle\\\\Loader\\\\SymfonyBridgeLoader\\:\\:addFixture\\(\\)\\.$#"
count: 1
path: src/Loader/SymfonyFixturesLoader.php
-
message: "#^Call to an undefined static method Doctrine\\\\Bundle\\\\FixturesBundle\\\\Loader\\\\SymfonyBridgeLoader\\:\\:getFixtures\\(\\)\\.$#"
count: 1
path: src/Loader/SymfonyFixturesLoader.php
-
message: "#^Class Doctrine\\\\Bundle\\\\FixturesBundle\\\\Loader\\\\SymfonyFixturesLoader does not have a constructor and must be instantiated without any parameters\\.$#"
count: 2
path: tests/Command/LoadDataFixturesDoctrineCommandTest.php
-
message: "#^Constructor of class Doctrine\\\\Bundle\\\\FixturesBundle\\\\Tests\\\\Fixtures\\\\FooBundle\\\\DataFixtures\\\\RequiredConstructorArgsFixtures has an unused parameter \\$fooRequiredArg\\.$#"
count: 1
path: Tests/Fixtures/FooBundle/DataFixtures/RequiredConstructorArgsFixtures.php
path: tests/Fixtures/FooBundle/DataFixtures/RequiredConstructorArgsFixtures.php

View File

@@ -2,9 +2,8 @@ parameters:
phpVersion: 80100
level: 3
paths:
- .
excludePaths:
- vendor
- src
- tests
includes:
- phpstan-baseline.neon

View File

@@ -3,18 +3,13 @@
<phpunit colors="true" bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="DoctrineFixturesBundle for the Symfony Framework">
<directory>./Tests</directory>
<directory>./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>.</directory>
<exclude>
<directory>./Resources</directory>
<directory>./Tests</directory>
<directory>./vendor</directory>
</exclude>
<directory>src</directory>
</whitelist>
</filter>

View File

@@ -10,15 +10,8 @@
findUnusedCode="false"
>
<projectFiles>
<directory name="Command" />
<directory name="DependencyInjection" />
<directory name="Loader" />
<directory name="Purger" />
<directory name="Tests" />
<file name="DoctrineFixturesBundle.php" />
<file name="Fixture.php" />
<file name="FixtureGroupInterface.php" />
<file name="ORMFixtureInterface.php" />
<directory name="src" />
<directory name="tests" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>

View File

@@ -20,7 +20,7 @@ class DoctrineFixturesExtension extends Extension
*/
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__) . '/Resources/config'));
$loader = new XmlFileLoader($container, new FileLocator(dirname(__DIR__) . '/../config'));
$loader->load('services.xml');

View File

@@ -9,6 +9,8 @@ use Doctrine\Bundle\FixturesBundle\DependencyInjection\CompilerPass\PurgerFactor
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use function dirname;
class DoctrineFixturesBundle extends Bundle
{
public function build(ContainerBuilder $container): void
@@ -16,4 +18,9 @@ class DoctrineFixturesBundle extends Bundle
$container->addCompilerPass(new FixturesCompilerPass());
$container->addCompilerPass(new PurgerFactoryCompilerPass());
}
public function getPath(): string
{
return dirname(__DIR__);
}
}

View File

@@ -11,9 +11,8 @@ use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\Loader;
use LogicException;
use ReflectionClass;
use RuntimeException;
use function array_key_exists;
use function array_keys;
use function array_values;
use function get_class;
use function sprintf;
@@ -100,19 +99,22 @@ final class SymfonyFixturesLoader extends Loader
return $fixtures;
}
$filteredFixtures = [];
foreach ($fixtures as $fixture) {
foreach ($groups as $group) {
$fixtureClass = $fixture::class;
if (isset($this->groupsFixtureMapping[$group][$fixtureClass])) {
$filteredFixtures[$fixtureClass] = $fixture;
continue 2;
}
$requiredFixtures = [];
foreach ($groups as $group) {
if (! isset($this->groupsFixtureMapping[$group])) {
continue;
}
$requiredFixtures += $this->collectDependencies(...array_keys($this->groupsFixtureMapping[$group]));
}
foreach ($filteredFixtures as $fixture) {
$this->validateDependencies($filteredFixtures, $fixture);
$filteredFixtures = [];
foreach ($fixtures as $order => $fixture) {
$fixtureClass = $fixture::class;
if (isset($requiredFixtures[$fixtureClass])) {
$filteredFixtures[$order] = $fixture;
continue;
}
}
return array_values($filteredFixtures);
@@ -131,22 +133,25 @@ final class SymfonyFixturesLoader extends Loader
}
/**
* @param string[] $fixtures An array of fixtures with class names as keys
* Collect any dependent fixtures from the given classes.
*
* @throws RuntimeException
* @psalm-return array<string,true>
*/
private function validateDependencies(array $fixtures, FixtureInterface $fixture): void
private function collectDependencies(string ...$fixtureClass): array
{
if (! $fixture instanceof DependentFixtureInterface) {
return;
}
$dependencies = [];
$dependenciesClasses = $fixture->getDependencies();
foreach ($fixtureClass as $class) {
$dependencies[$class] = true;
$fixture = $this->getFixture($class);
foreach ($dependenciesClasses as $class) {
if (! array_key_exists($class, $fixtures)) {
throw new RuntimeException(sprintf('Fixture "%s" was declared as a dependency for fixture "%s", but it was not included in any of the loaded fixture groups.', $class, $fixture::class));
if (! $fixture instanceof DependentFixtureInterface) {
continue;
}
$dependencies += $this->collectDependencies(...$fixture->getDependencies());
}
return $dependencies;
}
}

View File

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures;
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Bundle\FixturesBundle\ORMFixtureInterface;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
class WithDeepDependenciesFixtures implements ORMFixtureInterface, DependentFixtureInterface, FixtureGroupInterface
{
public function load(ObjectManager $manager): void
{
// ...
}
/**
* {@inheritDoc}
*/
public function getDependencies(): array
{
return [WithDependenciesFixtures::class, DependentOnRequiredConstructorArgsFixtures::class];
}
/**
* {@inheritDoc}
*/
public static function getGroups(): array
{
return ['groupWithDeepDependencies'];
}
}

View File

@@ -29,6 +29,6 @@ class WithDependenciesFixtures implements ORMFixtureInterface, DependentFixtureI
*/
public static function getGroups(): array
{
return ['missingDependencyGroup', 'fulfilledDependencyGroup'];
return ['groupWithDependencies', 'fulfilledDependencyGroup'];
}
}

View File

@@ -11,6 +11,8 @@ use Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader;
use Doctrine\Bundle\FixturesBundle\Purger\PurgerFactory;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\DependentOnRequiredConstructorArgsFixtures;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\RequiredConstructorArgsFixtures;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDeepDependenciesFixtures;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\Common\EventManager;
@@ -19,7 +21,6 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use LogicException;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -171,18 +172,26 @@ class IntegrationTest extends TestCase
$this->assertCount(0, $loader->getFixtures(['group3']));
}
public function testLoadFixturesViaGroupWithMissingDependency(): void
public function testLoadFixturesViaGroupWithDependenciesNotInGroup(): void
{
$kernel = new IntegrationTestKernel('dev', true);
$kernel->addServices(static function (ContainerBuilder $c): void {
// has a "staging" group via the getGroups() method
$c->autowire(OtherFixtures::class)
->addTag(FixturesCompilerPass::FIXTURE_TAG);
// no getGroups() method
$c->autowire(WithDependenciesFixtures::class)
->addTag(FixturesCompilerPass::FIXTURE_TAG);
$c->autowire(WithDeepDependenciesFixtures::class)
->addTag(FixturesCompilerPass::FIXTURE_TAG);
$c->autowire(RequiredConstructorArgsFixtures::class)
->setArgument('$fooRequiredArg', 'test')
->addTag(FixturesCompilerPass::FIXTURE_TAG);
$c->autowire(DependentOnRequiredConstructorArgsFixtures::class)
->addTag(FixturesCompilerPass::FIXTURE_TAG);
$c->setAlias('test.doctrine.fixtures.loader', new Alias('doctrine.fixtures.loader', true));
});
$kernel->boot();
@@ -191,10 +200,8 @@ class IntegrationTest extends TestCase
$loader = $container->get('test.doctrine.fixtures.loader');
$this->assertInstanceOf(SymfonyFixturesLoader::class, $loader);
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Fixture "Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures" was declared as a dependency for fixture "Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures", but it was not included in any of the loaded fixture groups.');
$loader->getFixtures(['missingDependencyGroup']);
self::assertCount(2, $loader->getFixtures(['groupWithDependencies']));
self::assertCount(5, $loader->getFixtures(['groupWithDeepDependencies']));
}
public function testLoadFixturesViaGroupWithFulfilledDependency(): void