Skip to content

Commit

Permalink
Enable loader to retrieve subtree of fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
Toni Uebernickel committed Apr 17, 2020
1 parent 886cf2e commit bf5ba58
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 0 deletions.
47 changes: 47 additions & 0 deletions Loader/SymfonyFixturesLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
use RuntimeException;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use function array_key_exists;
use function array_map;
use function array_merge;
use function array_reduce;
use function array_values;
use function get_class;
use function sprintf;
Expand Down Expand Up @@ -116,6 +119,50 @@ public function getFixtures(array $groups = []) : array
return array_values($filteredFixtures);
}

/**
* @param (FixtureInterface|string)[] $fixtures
*/
public function getFixturesDependencyTree(array $fixtures) : array
{
$fixtures = array_map(function ($fixture) {
if ($fixture instanceof FixtureInterface) {
return $fixture;
}

return $this->createFixture($fixture);
}, $fixtures);

$tree = $this->resolveFixturesDependencyTree($fixtures);

return array_values($tree);
}

/**
* @param FixtureInterface[] $fixtures
*/
private function resolveFixturesDependencyTree(array $fixtures) : array
{
return array_reduce($fixtures, function (array $tree, FixtureInterface $fixture) {
$class = get_class($fixture);
if (isset($tree[$class])) {
return $tree;
}

$tree[$class] = $fixture;
if (! $fixture instanceof DependentFixtureInterface) {
return $tree;
}

$dependencies = array_map(function (string $dependency) {
return $this->createFixture($dependency);
}, $fixture->getDependencies());

$subTree = $this->getFixturesDependencyTree($dependencies);

return array_merge($subTree, $tree);
}, []);
}

/**
* Generates an array of the groups and their fixtures
*
Expand Down
132 changes: 132 additions & 0 deletions Tests/Loader/ResolveFixturesSubtreeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\FixturesBundle\Tests\Loader;

use Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures;
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Persistence\ObjectManager;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Container;
use function class_alias;
use function interface_exists;

/**
* @covers \Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader::getFixturesDependencyTree
* @covers \Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader::resolveFixturesDependencyTree
*/
class ResolveFixturesSubtreeTest extends TestCase
{
/** @var SymfonyFixturesLoader */
private $loader;

public static function setUpBeforeClass() : void
{
if (interface_exists(ObjectManager::class)) {
return;
}

class_alias('Doctrine\Common\Persistence\ObjectManager', 'Doctrine\Persistence\ObjectManager', false);
}

protected function setUp() : void
{
$this->loader = new SymfonyFixturesLoader(new Container());
}

public function testGetBasicFixturesTree() : void
{
$fixtures = new OtherFixtures();
$this->loader->addFixture($fixtures);

$tree = $this->loader->getFixturesDependencyTree([$fixtures]);

static::assertCount(1, $tree);
static::assertContains($fixtures, $tree);
}

public function testGetFixturesTreeByClassname() : void
{
$fixtures = new OtherFixtures();
$this->loader->addFixture($fixtures);

$tree = $this->loader->getFixturesDependencyTree([OtherFixtures::class]);

static::assertCount(1, $tree);
static::assertContains($fixtures, $tree);
}

public function testResolveDependentFixtures() : void
{
$otherFixtures = new OtherFixtures();
$this->loader->addFixture($otherFixtures);

$withDependenciesFixtures = new WithDependenciesFixtures();
$this->loader->addFixture($withDependenciesFixtures);

$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);

static::assertCount(2, $tree);
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
}

public function testOmitFixturesOutsideTree() : void
{
$otherFixtures = new OtherFixtures();
$this->loader->addFixture($otherFixtures);

$withDependenciesFixtures = new WithDependenciesFixtures();
$this->loader->addFixture($withDependenciesFixtures);

$omittedFixtures = $this->createFixture([]);
$this->loader->addFixture($omittedFixtures);

$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);

static::assertCount(2, $tree);
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
}

public function testResolveRecursively() : void
{
$otherFixtures = new OtherFixtures();
$this->loader->addFixture($otherFixtures);

$withDependenciesFixtures = new WithDependenciesFixtures();
$this->loader->addFixture($withDependenciesFixtures);

$treeTopFixtures = $this->createFixture([WithDependenciesFixtures::class]);
$this->loader->addFixture($treeTopFixtures);

$tree = $this->loader->getFixturesDependencyTree([$treeTopFixtures]);

static::assertCount(3, $tree);
static::assertSame([$otherFixtures, $withDependenciesFixtures, $treeTopFixtures], $tree);
}

private function createFixture(array $dependencies) : FixtureInterface
{
return new class ($dependencies) implements FixtureInterface, DependentFixtureInterface {
/** @var string[] */
private $dependencies;

public function __construct(array $dependencies)
{
$this->dependencies = $dependencies;
}

public function load(ObjectManager $manager) : void
{
}

public function getDependencies() : array
{
return $this->dependencies;
}
};
}
}

0 comments on commit bf5ba58

Please sign in to comment.