Skip to content

Commit 88ee524

Browse files
author
Toni Uebernickel
committed
Enable loader to retrieve subtree of fixtures
1 parent 886cf2e commit 88ee524

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

Loader/SymfonyFixturesLoader.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
use RuntimeException;
1414
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
1515
use function array_key_exists;
16+
use function array_map;
17+
use function array_merge;
18+
use function array_reduce;
1619
use function array_values;
1720
use function get_class;
1821
use function sprintf;
@@ -116,6 +119,50 @@ public function getFixtures(array $groups = []) : array
116119
return array_values($filteredFixtures);
117120
}
118121

122+
/**
123+
* @param (FixtureInterface|string)[] $fixtures
124+
*/
125+
public function getFixturesDependencyTree(array $fixtures) : array
126+
{
127+
$fixtures = array_map(static function ($fixture) {
128+
if ($fixture instanceof FixtureInterface) {
129+
return $fixture;
130+
}
131+
132+
return $this->createFixture($fixture);
133+
}, $fixtures);
134+
135+
$tree = $this->resolveFixturesDependencyTree($fixtures);
136+
137+
return array_values($tree);
138+
}
139+
140+
/**
141+
* @param FixtureInterface[] $fixtures
142+
*/
143+
private function resolveFixturesDependencyTree(array $fixtures) : array
144+
{
145+
return array_reduce($fixtures, function (array $tree, FixtureInterface $fixture) {
146+
$class = get_class($fixture);
147+
if (isset($tree[$class])) {
148+
return $tree;
149+
}
150+
151+
$tree[$class] = $fixture;
152+
if (! $fixture instanceof DependentFixtureInterface) {
153+
return $tree;
154+
}
155+
156+
$dependencies = array_map(function (string $dependency) {
157+
return $this->createFixture($dependency);
158+
}, $fixture->getDependencies());
159+
160+
$subTree = $this->getFixturesDependencyTree($dependencies);
161+
162+
return array_merge($subTree, $tree);
163+
}, []);
164+
}
165+
119166
/**
120167
* Generates an array of the groups and their fixtures
121168
*
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\FixturesBundle\Tests\Loader;
6+
7+
use Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader;
8+
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\OtherFixtures;
9+
use Doctrine\Bundle\FixturesBundle\Tests\Fixtures\FooBundle\DataFixtures\WithDependenciesFixtures;
10+
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
11+
use Doctrine\Common\DataFixtures\FixtureInterface;
12+
use Doctrine\Persistence\ObjectManager;
13+
use PHPUnit\Framework\TestCase;
14+
use Symfony\Component\DependencyInjection\Container;
15+
use function class_alias;
16+
use function interface_exists;
17+
18+
/**
19+
* @covers \Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader::getFixturesDependencyTree
20+
* @covers \Doctrine\Bundle\FixturesBundle\Loader\SymfonyFixturesLoader::resolveFixturesDependencyTree
21+
*/
22+
class ResolveFixturesSubtreeTest extends TestCase
23+
{
24+
/** @var SymfonyFixturesLoader */
25+
private $loader;
26+
27+
public static function setUpBeforeClass() : void
28+
{
29+
if (interface_exists(ObjectManager::class)) {
30+
return;
31+
}
32+
33+
class_alias('Doctrine\Common\Persistence\ObjectManager', 'Doctrine\Persistence\ObjectManager', false);
34+
}
35+
36+
protected function setUp() : void
37+
{
38+
$this->loader = new SymfonyFixturesLoader(new Container());
39+
}
40+
41+
public function testGetBasicFixturesTree() : void
42+
{
43+
$fixtures = new OtherFixtures();
44+
$this->loader->addFixture($fixtures);
45+
46+
$tree = $this->loader->getFixturesDependencyTree([$fixtures]);
47+
48+
static::assertCount(1, $tree);
49+
static::assertContains($fixtures, $tree);
50+
}
51+
52+
public function testResolveDependentFixtures() : void
53+
{
54+
$otherFixtures = new OtherFixtures();
55+
$this->loader->addFixture($otherFixtures);
56+
57+
$withDependenciesFixtures = new WithDependenciesFixtures();
58+
$this->loader->addFixture($withDependenciesFixtures);
59+
60+
$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);
61+
62+
static::assertCount(2, $tree);
63+
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
64+
}
65+
66+
public function testOmitFixturesOutsideTree() : void
67+
{
68+
$otherFixtures = new OtherFixtures();
69+
$this->loader->addFixture($otherFixtures);
70+
71+
$withDependenciesFixtures = new WithDependenciesFixtures();
72+
$this->loader->addFixture($withDependenciesFixtures);
73+
74+
$omittedFixtures = $this->createFixture([]);
75+
$this->loader->addFixture($omittedFixtures);
76+
77+
$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);
78+
79+
static::assertCount(2, $tree);
80+
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
81+
}
82+
83+
public function testResolveRecursively() : void
84+
{
85+
$otherFixtures = new OtherFixtures();
86+
$this->loader->addFixture($otherFixtures);
87+
88+
$withDependenciesFixtures = new WithDependenciesFixtures();
89+
$this->loader->addFixture($withDependenciesFixtures);
90+
91+
$treeTopFixtures = $this->createFixture([WithDependenciesFixtures::class]);
92+
$this->loader->addFixture($treeTopFixtures);
93+
94+
$tree = $this->loader->getFixturesDependencyTree([$treeTopFixtures]);
95+
96+
static::assertCount(3, $tree);
97+
static::assertSame([$otherFixtures, $withDependenciesFixtures, $treeTopFixtures], $tree);
98+
}
99+
100+
private function createFixture(array $dependencies) : FixtureInterface
101+
{
102+
return new class ($dependencies) implements FixtureInterface, DependentFixtureInterface {
103+
/** @var string[] */
104+
private $dependencies;
105+
106+
public function __construct(array $dependencies)
107+
{
108+
$this->dependencies = $dependencies;
109+
}
110+
111+
public function load(ObjectManager $manager) : void
112+
{
113+
}
114+
115+
public function getDependencies() : array
116+
{
117+
return $this->dependencies;
118+
}
119+
};
120+
}
121+
}

0 commit comments

Comments
 (0)