Skip to content

Commit a04e351

Browse files
committed
Add Static fixtures
1 parent 4c65f98 commit a04e351

11 files changed

Lines changed: 516 additions & 8 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
/composer.lock
99
/composer.phar
1010
/phpunit.xml
11+
.phpunit.cache

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# v1.4.0
22

3+
* Add "StaticFixture" so that one could use fixtures statically outside the services context.
34
* Drop support for PHP <8.1
45
* Ensure PHP 8.5 compatibility
56
* Upgrade test suite to PHPUnit 10 and update tests to be compatible

src/ArrayFixture.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public function load(ObjectManager $manager): void
8787
$dbConfiguration->setSQLLogger(null);
8888
}
8989

90+
$this->beforeCreatingObjects();
91+
9092
$objects = $this->getObjects();
9193

9294
$this->numberOfIteratedObjects = 0;
@@ -191,6 +193,14 @@ protected function clearEntityManagerOnFlush(): bool
191193
return true;
192194
}
193195

196+
/**
197+
* Will be called just before "->getObjects()".
198+
* This allows side-actions, like fetching data from an external source, using injected services, etc.
199+
*/
200+
protected function beforeCreatingObjects(): void
201+
{
202+
}
203+
194204
/**
195205
* Creates a new instance of the class associated with the fixture.
196206
* Override this method if you have constructor arguments to manage yourself depending on input data.

src/Ref.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Orbitale\Component\ArrayFixture;
4+
5+
final class Ref
6+
{
7+
public function __construct(
8+
public string $class,
9+
public string $name,
10+
) {
11+
}
12+
}

src/StaticFixture.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Orbitale\Component\ArrayFixture;
4+
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
7+
abstract class StaticFixture extends ArrayFixture
8+
{
9+
abstract public static function getStaticData(): iterable;
10+
11+
public static function findByKeyAndValue(string $key, mixed $value): array
12+
{
13+
$data = \array_filter(
14+
static::getStaticData(),
15+
static fn (array $data) => $value instanceof Ref && $data[$key] instanceof Ref
16+
? $value->name === $data[$key]->name
17+
: $data[$key] === $value
18+
);
19+
20+
if (!\count($data)) {
21+
throw new \RuntimeException(\sprintf('No fixture object with key "%s" and value "%s" in class "%s".', $key, $value, static::class));
22+
}
23+
24+
return \array_values($data)[0];
25+
}
26+
27+
public static function filterByKeyAndValue(string $key, mixed $value): array
28+
{
29+
return \array_filter(
30+
static::getStaticData(),
31+
static fn (array $data) => $value instanceof Ref && $data[$key] instanceof Ref
32+
? $value->name === $data[$key]->name
33+
: $data[$key] === $value
34+
);
35+
}
36+
37+
public static function filterData(\Closure $callback): array
38+
{
39+
return \array_filter(static::getStaticData(), $callback);
40+
}
41+
42+
public static function getIdFromName(string $name): string
43+
{
44+
foreach (static::getStaticData() as $id => $values) {
45+
if ($values['name'] === $name) {
46+
return $id;
47+
}
48+
}
49+
50+
throw new \RuntimeException(\sprintf('No fixture object with name "%s" in class "%s".', $name, static::class));
51+
}
52+
53+
protected function getObjects(): iterable
54+
{
55+
foreach (static::getStaticData() as $id => $properties) {
56+
foreach ($properties as $property => $value) {
57+
$properties['id'] = $id;
58+
59+
if ($value instanceof \Closure) {
60+
$value = $value();
61+
}
62+
63+
if ($value instanceof Ref) {
64+
$value = $this->getReference($value->name, $value->class);
65+
} elseif (\is_array($value)) {
66+
$arrayData = $value;
67+
$hasRef = false;
68+
69+
foreach ($arrayData as $key => $arrayValue) {
70+
if ($arrayValue instanceof Ref) {
71+
$arrayData[$key] = $this->getReference($arrayValue->name, $arrayValue->class);
72+
$hasRef = true;
73+
}
74+
}
75+
76+
$value = $hasRef ? new ArrayCollection($arrayData) : $arrayData;
77+
}
78+
79+
$properties[$property] = $value;
80+
}
81+
82+
$class = $this->getEntityClass();
83+
if (\property_exists($class, 'createdAt')) {
84+
$properties['createdAt'] = new \DateTime();
85+
}
86+
if (\property_exists($class, 'updatedAt')) {
87+
$properties['updatedAt'] = new \DateTime();
88+
}
89+
90+
yield $id => $properties;
91+
}
92+
}
93+
}

tests/ArrayFixtureTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
class ArrayFixtureTest extends TestCase
3939
{
40-
public function test post title fixture(): void
40+
public function test_post_title_fixture(): void
4141
{
4242
$manager = $this->getObjectManager();
4343

@@ -53,7 +53,7 @@ public function test post title fixture(): void
5353
(new PostTitleFixtureStub())->load($manager);
5454
}
5555

56-
public function test post self reference fixture(): void
56+
public function test_post_self_reference_fixture(): void
5757
{
5858
$manager = $this->getObjectManager();
5959

@@ -88,7 +88,7 @@ public function test post self reference fixture(): void
8888
$fixture->load($manager);
8989
}
9090

91-
public function test inexistent property(): void
91+
public function test_inexistent_property(): void
9292
{
9393
$manager = $this->getObjectManager();
9494

@@ -100,7 +100,7 @@ public function test inexistent property(): void
100100
(new InexistentPropertyFixtureStub())->load($manager);
101101
}
102102

103-
public function test toString for prefix(): void
103+
public function test_toString_for_prefix(): void
104104
{
105105
$manager = $this->getObjectManager();
106106
$refsRepo = new ReferenceRepositoryStub($manager);
@@ -132,7 +132,7 @@ public function test toString for prefix(): void
132132
self::assertSame($refs['post-Default title'], $persistedStub);
133133
}
134134

135-
public function test inexistent prefix method(): void
135+
public function test_inexistent_prefix_method(): void
136136
{
137137
$manager = $this->getObjectManager();
138138

@@ -144,7 +144,7 @@ public function test inexistent prefix method(): void
144144
(new InexistentMethodPrefixFixtureStub())->load($manager);
145145
}
146146

147-
public function test custom number of flushes(): void
147+
public function test_custom_number_of_flushes(): void
148148
{
149149
$manager = $this->getObjectManager();
150150

@@ -174,7 +174,7 @@ public function test custom number of flushes(): void
174174
}
175175
}
176176

177-
public function test entities with ids(): void
177+
public function test_entities_with_ids(): void
178178
{
179179
$entityManager = $this->getEntityManager();
180180

@@ -201,7 +201,7 @@ public function test entities with ids(): void
201201
self::assertNull($persistedStubs[1]->getParent());
202202
}
203203

204-
public function test documents with ids(): void
204+
public function test_documents_with_ids(): void
205205
{
206206
$documentManager = $this->getDocumentManager();
207207

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Orbitale ArrayFixture package.
7+
*
8+
* (c) Alexandre Rock Ancelet <alex@orbitale.io>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Orbitale\Component\ArrayFixture\Fixtures;
15+
16+
use Orbitale\Component\ArrayFixture\Ref;
17+
use Orbitale\Component\ArrayFixture\StaticFixture;
18+
use Tests\Orbitale\Component\ArrayFixture\Stubs\PostStub;
19+
20+
/**
21+
* @extends StaticFixture<PostStub>
22+
*/
23+
class StaticLoadablePostFixtureStub extends StaticFixture
24+
{
25+
protected function getEntityClass(): string
26+
{
27+
return PostStub::class;
28+
}
29+
30+
public static function getStaticData(): iterable
31+
{
32+
return [
33+
'post-1' => [
34+
'title' => 'Basic title',
35+
'tags' => ['php'],
36+
],
37+
'post-2' => [
38+
'title' => fn () => 'Closure title',
39+
'parent' => new Ref(PostStub::class, 'parent-ref'),
40+
'tags' => [new Ref(PostStub::class, 'tag-ref-1'), new Ref(PostStub::class, 'tag-ref-2')],
41+
],
42+
];
43+
}
44+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Orbitale ArrayFixture package.
7+
*
8+
* (c) Alexandre Rock Ancelet <alex@orbitale.io>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Orbitale\Component\ArrayFixture\Fixtures;
15+
16+
use Orbitale\Component\ArrayFixture\Ref;
17+
use Orbitale\Component\ArrayFixture\StaticFixture;
18+
use Tests\Orbitale\Component\ArrayFixture\Stubs\PostStub;
19+
20+
/**
21+
* @extends StaticFixture<PostStub>
22+
*/
23+
class StaticPostFixtureStub extends StaticFixture
24+
{
25+
protected function getEntityClass(): string
26+
{
27+
return PostStub::class;
28+
}
29+
30+
public static function getStaticData(): iterable
31+
{
32+
return [
33+
'post-1' => [
34+
'name' => 'First post',
35+
'title' => 'First title',
36+
'parent' => null,
37+
'tags' => ['php', 'doctrine'],
38+
],
39+
'post-2' => [
40+
'name' => 'Second post',
41+
'title' => 'Second title',
42+
'parent' => new Ref(PostStub::class, 'parent-ref'),
43+
'tags' => ['symfony'],
44+
],
45+
'post-3' => [
46+
'name' => 'Third post',
47+
'title' => 'First title',
48+
'parent' => null,
49+
'tags' => [],
50+
],
51+
];
52+
}
53+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Orbitale ArrayFixture package.
7+
*
8+
* (c) Alexandre Rock Ancelet <alex@orbitale.io>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Tests\Orbitale\Component\ArrayFixture\Fixtures;
15+
16+
use Orbitale\Component\ArrayFixture\StaticFixture;
17+
use Tests\Orbitale\Component\ArrayFixture\Stubs\TimestampedPostStub;
18+
19+
/**
20+
* @extends StaticFixture<TimestampedPostStub>
21+
*/
22+
class StaticTimestampedPostFixtureStub extends StaticFixture
23+
{
24+
protected function getEntityClass(): string
25+
{
26+
return TimestampedPostStub::class;
27+
}
28+
29+
public static function getStaticData(): iterable
30+
{
31+
return [
32+
'post-1' => [
33+
'title' => 'Timestamped post',
34+
],
35+
];
36+
}
37+
}

0 commit comments

Comments
 (0)