Skip to content

Commit bf5ba58

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

File tree

2 files changed

+179
-0
lines changed

2 files changed

+179
-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(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: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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 testGetFixturesTreeByClassname() : void
53+
{
54+
$fixtures = new OtherFixtures();
55+
$this->loader->addFixture($fixtures);
56+
57+
$tree = $this->loader->getFixturesDependencyTree([OtherFixtures::class]);
58+
59+
static::assertCount(1, $tree);
60+
static::assertContains($fixtures, $tree);
61+
}
62+
63+
public function testResolveDependentFixtures() : void
64+
{
65+
$otherFixtures = new OtherFixtures();
66+
$this->loader->addFixture($otherFixtures);
67+
68+
$withDependenciesFixtures = new WithDependenciesFixtures();
69+
$this->loader->addFixture($withDependenciesFixtures);
70+
71+
$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);
72+
73+
static::assertCount(2, $tree);
74+
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
75+
}
76+
77+
public function testOmitFixturesOutsideTree() : void
78+
{
79+
$otherFixtures = new OtherFixtures();
80+
$this->loader->addFixture($otherFixtures);
81+
82+
$withDependenciesFixtures = new WithDependenciesFixtures();
83+
$this->loader->addFixture($withDependenciesFixtures);
84+
85+
$omittedFixtures = $this->createFixture([]);
86+
$this->loader->addFixture($omittedFixtures);
87+
88+
$tree = $this->loader->getFixturesDependencyTree([$withDependenciesFixtures]);
89+
90+
static::assertCount(2, $tree);
91+
static::assertSame([$otherFixtures, $withDependenciesFixtures], $tree);
92+
}
93+
94+
public function testResolveRecursively() : void
95+
{
96+
$otherFixtures = new OtherFixtures();
97+
$this->loader->addFixture($otherFixtures);
98+
99+
$withDependenciesFixtures = new WithDependenciesFixtures();
100+
$this->loader->addFixture($withDependenciesFixtures);
101+
102+
$treeTopFixtures = $this->createFixture([WithDependenciesFixtures::class]);
103+
$this->loader->addFixture($treeTopFixtures);
104+
105+
$tree = $this->loader->getFixturesDependencyTree([$treeTopFixtures]);
106+
107+
static::assertCount(3, $tree);
108+
static::assertSame([$otherFixtures, $withDependenciesFixtures, $treeTopFixtures], $tree);
109+
}
110+
111+
private function createFixture(array $dependencies) : FixtureInterface
112+
{
113+
return new class ($dependencies) implements FixtureInterface, DependentFixtureInterface {
114+
/** @var string[] */
115+
private $dependencies;
116+
117+
public function __construct(array $dependencies)
118+
{
119+
$this->dependencies = $dependencies;
120+
}
121+
122+
public function load(ObjectManager $manager) : void
123+
{
124+
}
125+
126+
public function getDependencies() : array
127+
{
128+
return $this->dependencies;
129+
}
130+
};
131+
}
132+
}

0 commit comments

Comments
 (0)