Passed
Pull Request — master (#188)
by Kevin
02:42
created

RepositoryProxyTest   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 296
Duplicated Lines 0 %

Importance

Changes 8
Bugs 0 Features 5
Metric Value
wmc 22
eloc 106
c 8
b 0
f 5
dl 0
loc 296
rs 10

20 Methods

Rating   Name   Duplication   Size   Complexity  
A assertions() 0 13 1
A first_and_last_return_null_if_empty() 0 6 1
A the_number_of_persisted_objects_must_be_at_least_the_random_range_max() 0 8 1
A assertions_legacy() 0 20 1
A can_use_get_count() 0 7 1
A repository_proxy_is_countable_and_iterable() 0 8 1
A the_number_of_persisted_objects_must_be_at_least_the_random_set_number() 0 8 1
A first_and_last_return_the_correct_object() 0 11 1
A random_range_min_cannot_be_less_than_zero() 0 6 1
A doctrine_proxies_are_converted_to_foundry_proxies() 0 16 1
A random_set_number_must_be_positive() 0 6 1
A can_find_random_object() 0 11 2
A find_can_be_passed_proxy_or_object_or_array() 0 8 1
A can_find_random_range_of_objects() 0 17 2
A proxy_wrapping_orm_entity_manager_can_order_by_in_find_one_by() 0 7 1
A random_set_max_cannot_be_less_than_min() 0 6 1
A can_find_random_set_of_objects() 0 8 1
A functions_calls_are_passed_to_underlying_repository() 0 3 1
A can_fetch_objects() 0 15 1
A at_least_one_object_must_exist_to_get_random_object() 0 6 1
1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use Doctrine\Common\Proxy\Proxy as DoctrineProxy;
6
use Doctrine\ORM\Event\OnFlushEventArgs;
7
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
8
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
9
use Zenstruck\Foundry\Proxy;
10
use Zenstruck\Foundry\Test\Factories;
11
use Zenstruck\Foundry\Test\ResetDatabase;
12
use Zenstruck\Foundry\Tests\Fixtures\Entity\Category;
13
use Zenstruck\Foundry\Tests\Fixtures\Entity\Post;
14
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
15
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
16
use function Zenstruck\Foundry\repository;
17
18
/**
19
 * @author Kevin Bond <[email protected]>
20
 */
21
final class RepositoryProxyTest extends KernelTestCase
22
{
23
    use ExpectDeprecationTrait, Factories, ResetDatabase;
24
25
    /**
26
     * @test
27
     */
28
    public function functions_calls_are_passed_to_underlying_repository(): void
29
    {
30
        $this->assertSame('from custom method', repository(Post::class)->customMethod());
0 ignored issues
show
Bug introduced by
The method customMethod() does not exist on Zenstruck\Foundry\RepositoryProxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

30
        $this->assertSame('from custom method', repository(Post::class)->/** @scrutinizer ignore-call */ customMethod());
Loading history...
31
    }
32
33
    /**
34
     * @test
35
     */
36
    public function assertions(): void
37
    {
38
        $repository = repository(Category::class);
39
40
        $repository->assert()->empty();
41
42
        CategoryFactory::createMany(2);
43
44
        $repository->assert()->count(2);
45
        $repository->assert()->countGreaterThan(1);
46
        $repository->assert()->countGreaterThanOrEqual(2);
47
        $repository->assert()->countLessThan(3);
48
        $repository->assert()->countLessThanOrEqual(2);
49
    }
50
51
    /**
52
     * @test
53
     * @group legacy
54
     */
55
    public function assertions_legacy(): void
56
    {
57
        $repository = repository(Category::class);
58
59
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertEmpty() is deprecated, use RepositoryProxy::assert()->empty().');
60
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCount() is deprecated, use RepositoryProxy::assert()->count().');
61
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThan() is deprecated, use RepositoryProxy::assert()->countGreaterThan().');
62
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThanOrEqual() is deprecated, use RepositoryProxy::assert()->countGreaterThanOrEqual().');
63
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThan() is deprecated, use RepositoryProxy::assert()->countLessThan().');
64
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThanOrEqual() is deprecated, use RepositoryProxy::assert()->countLessThanOrEqual().');
65
66
        $repository->assertEmpty();
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\RepositoryProxy::assertEmpty() has been deprecated: use RepositoryProxy::assert()->empty() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

66
        /** @scrutinizer ignore-deprecated */ $repository->assertEmpty();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
67
68
        CategoryFactory::createMany(2);
69
70
        $repository->assertCount(2);
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\RepositoryProxy::assertCount() has been deprecated: use RepositoryProxy::assert()->count() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

70
        /** @scrutinizer ignore-deprecated */ $repository->assertCount(2);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
71
        $repository->assertCountGreaterThan(1);
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\Reposi...ssertCountGreaterThan() has been deprecated: use RepositoryProxy::assert()->countGreaterThan() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

71
        /** @scrutinizer ignore-deprecated */ $repository->assertCountGreaterThan(1);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
72
        $repository->assertCountGreaterThanOrEqual(2);
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\Reposi...untGreaterThanOrEqual() has been deprecated: use RepositoryProxy::assert()->countGreaterThanOrEqual() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

72
        /** @scrutinizer ignore-deprecated */ $repository->assertCountGreaterThanOrEqual(2);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
73
        $repository->assertCountLessThan(3);
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\Reposi...::assertCountLessThan() has been deprecated: use RepositoryProxy::assert()->countLessThan() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

73
        /** @scrutinizer ignore-deprecated */ $repository->assertCountLessThan(3);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
74
        $repository->assertCountLessThanOrEqual(2);
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\Reposi...tCountLessThanOrEqual() has been deprecated: use RepositoryProxy::assert()->countLessThanOrEqual() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

74
        /** @scrutinizer ignore-deprecated */ $repository->assertCountLessThanOrEqual(2);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
75
    }
76
77
    /**
78
     * @test
79
     */
80
    public function can_fetch_objects(): void
81
    {
82
        $repository = repository(Category::class);
83
84
        CategoryFactory::createMany(2);
85
86
        $objects = $repository->findAll();
87
88
        $this->assertCount(2, $objects);
89
        $this->assertInstanceOf(Proxy::class, $objects[0]);
90
91
        $objects = $repository->findBy([]);
92
93
        $this->assertCount(2, $objects);
94
        $this->assertInstanceOf(Proxy::class, $objects[0]);
95
    }
96
97
    /**
98
     * @test
99
     */
100
    public function find_can_be_passed_proxy_or_object_or_array(): void
101
    {
102
        $repository = repository(Category::class);
103
        $proxy = CategoryFactory::createOne(['name' => 'foo']);
104
105
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy));
106
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy->object()));
107
        $this->assertInstanceOf(Proxy::class, $repository->find(['name' => 'foo']));
108
    }
109
110
    /**
111
     * @test
112
     */
113
    public function can_find_random_object(): void
114
    {
115
        CategoryFactory::createMany(5);
116
117
        $ids = [];
118
119
        while (5 !== \count(\array_unique($ids))) {
120
            $ids[] = repository(Category::class)->random()->getId();
0 ignored issues
show
Bug introduced by
The method getId() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
            $ids[] = repository(Category::class)->random()->/** @scrutinizer ignore-call */ getId();
Loading history...
121
        }
122
123
        $this->assertCount(5, \array_unique($ids));
124
    }
125
126
    /**
127
     * @test
128
     */
129
    public function at_least_one_object_must_exist_to_get_random_object(): void
130
    {
131
        $this->expectException(\RuntimeException::class);
132
        $this->expectExceptionMessage(\sprintf('At least 1 "%s" object(s) must have been persisted (0 persisted).', Category::class));
133
134
        repository(Category::class)->random();
135
    }
136
137
    /**
138
     * @test
139
     */
140
    public function can_find_random_set_of_objects(): void
141
    {
142
        CategoryFactory::createMany(5);
143
144
        $objects = repository(Category::class)->randomSet(3);
145
146
        $this->assertCount(3, $objects);
147
        $this->assertCount(3, \array_unique(\array_map(static function($category) { return $category->getId(); }, $objects)));
148
    }
149
150
    /**
151
     * @test
152
     */
153
    public function random_set_number_must_be_positive(): void
154
    {
155
        $this->expectException(\InvalidArgumentException::class);
156
        $this->expectExceptionMessage('$number must be positive (-1 given).');
157
158
        repository(Category::class)->randomSet(-1);
159
    }
160
161
    /**
162
     * @test
163
     */
164
    public function the_number_of_persisted_objects_must_be_at_least_the_random_set_number(): void
165
    {
166
        CategoryFactory::createOne();
167
168
        $this->expectException(\RuntimeException::class);
169
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
170
171
        repository(Category::class)->randomSet(2);
172
    }
173
174
    /**
175
     * @test
176
     */
177
    public function can_find_random_range_of_objects(): void
178
    {
179
        CategoryFactory::createMany(5);
180
181
        $counts = [];
182
183
        while (4 !== \count(\array_unique($counts))) {
184
            $counts[] = \count(repository(Category::class)->randomRange(0, 3));
185
        }
186
187
        $this->assertCount(4, \array_unique($counts));
188
        $this->assertContains(0, $counts);
189
        $this->assertContains(1, $counts);
190
        $this->assertContains(2, $counts);
191
        $this->assertContains(3, $counts);
192
        $this->assertNotContains(4, $counts);
193
        $this->assertNotContains(5, $counts);
194
    }
195
196
    /**
197
     * @test
198
     */
199
    public function the_number_of_persisted_objects_must_be_at_least_the_random_range_max(): void
200
    {
201
        CategoryFactory::createOne();
202
203
        $this->expectException(\RuntimeException::class);
204
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
205
206
        repository(Category::class)->randomRange(0, 2);
207
    }
208
209
    /**
210
     * @test
211
     */
212
    public function random_range_min_cannot_be_less_than_zero(): void
213
    {
214
        $this->expectException(\InvalidArgumentException::class);
215
        $this->expectExceptionMessage('$min must be positive (-1 given).');
216
217
        repository(Category::class)->randomRange(-1, 3);
218
    }
219
220
    /**
221
     * @test
222
     */
223
    public function random_set_max_cannot_be_less_than_min(): void
224
    {
225
        $this->expectException(\InvalidArgumentException::class);
226
        $this->expectExceptionMessage('$max (3) cannot be less than $min (5).');
227
228
        repository(Category::class)->randomRange(5, 3);
229
    }
230
231
    /**
232
     * @see https://github.com/zenstruck/foundry/issues/42
233
     *
234
     * @test
235
     */
236
    public function doctrine_proxies_are_converted_to_foundry_proxies(): void
237
    {
238
        PostFactory::createOne(['category' => CategoryFactory::new()]);
239
240
        // clear the em so nothing is tracked
241
        static::$kernel->getContainer()->get('doctrine')->getManager()->clear();
242
243
        // load a random Post which causes the em to track a "doctrine proxy" for category
244
        PostFactory::random();
245
246
        // load a random Category which should be a "doctrine proxy"
247
        $category = CategoryFactory::random()->object();
248
249
        // ensure the category is a "doctrine proxy" and a Category
250
        $this->assertInstanceOf(DoctrineProxy::class, $category);
251
        $this->assertInstanceOf(Category::class, $category);
252
    }
253
254
    /**
255
     * @test
256
     */
257
    public function proxy_wrapping_orm_entity_manager_can_order_by_in_find_one_by(): void
258
    {
259
        $categoryA = CategoryFactory::createOne();
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryA is dead and can be removed.
Loading history...
260
        $categoryB = CategoryFactory::createOne();
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryB is dead and can be removed.
Loading history...
261
        $categoryC = CategoryFactory::createOne();
262
263
        $this->assertSame($categoryC->getId(), CategoryFactory::repository()->findOneBy([], ['id' => 'DESC'])->getId());
264
    }
265
266
    /**
267
     * @test
268
     */
269
    public function first_and_last_return_the_correct_object(): void
270
    {
271
        $categoryA = CategoryFactory::createOne(['name' => '3']);
272
        $categoryB = CategoryFactory::createOne(['name' => '2']);
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryB is dead and can be removed.
Loading history...
273
        $categoryC = CategoryFactory::createOne(['name' => '1']);
274
        $repository = CategoryFactory::repository();
275
276
        $this->assertSame($categoryA->getId(), $repository->first()->getId());
277
        $this->assertSame($categoryC->getId(), $repository->first('name')->getId());
278
        $this->assertSame($categoryC->getId(), $repository->last()->getId());
279
        $this->assertSame($categoryA->getId(), $repository->last('name')->getId());
280
    }
281
282
    /**
283
     * @test
284
     */
285
    public function first_and_last_return_null_if_empty(): void
286
    {
287
        $this->assertNull(CategoryFactory::repository()->first());
288
        $this->assertNull(CategoryFactory::repository()->first('name'));
289
        $this->assertNull(CategoryFactory::repository()->last());
290
        $this->assertNull(CategoryFactory::repository()->last('name'));
291
    }
292
293
    /**
294
     * @test
295
     */
296
    public function repository_proxy_is_countable_and_iterable(): void
297
    {
298
        CategoryFactory::createMany(4);
299
300
        $repository = CategoryFactory::repository();
301
302
        $this->assertCount(4, $repository);
303
        $this->assertCount(4, \iterator_to_array($repository));
304
    }
305
306
    /**
307
     * @test
308
     * @group legacy
309
     */
310
    public function can_use_get_count(): void
311
    {
312
        CategoryFactory::createMany(4);
313
314
        $this->expectDeprecation('Since zenstruck\foundry 1.5.0: Using RepositoryProxy::getCount() is deprecated, use RepositoryProxy::count() (it is now Countable).');
315
316
        $this->assertSame(4, CategoryFactory::repository()->getCount());
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\RepositoryProxy::getCount() has been deprecated: use RepositoryProxy::count() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

316
        $this->assertSame(4, /** @scrutinizer ignore-deprecated */ CategoryFactory::repository()->getCount());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
317
    }
318
}
319