Passed
Pull Request — master (#182)
by Kevin
02:26
created

RepositoryProxyTest   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Importance

Changes 9
Bugs 0 Features 5
Metric Value
wmc 22
eloc 118
c 9
b 0
f 5
dl 0
loc 316
rs 10

20 Methods

Rating   Name   Duplication   Size   Complexity  
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 can_use_get_count() 0 7 1
A assertions() 0 39 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 legacy_assertions() 0 13 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 PHPUnit\Framework\AssertionFailedError;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\AssertionFailedError was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
8
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
9
use Zenstruck\Assert;
10
use Zenstruck\Foundry\Proxy;
11
use Zenstruck\Foundry\Test\Factories;
12
use Zenstruck\Foundry\Test\ResetDatabase;
13
use Zenstruck\Foundry\Tests\Fixtures\Entity\Category;
14
use Zenstruck\Foundry\Tests\Fixtures\Entity\Post;
15
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
16
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
17
use function Zenstruck\Foundry\repository;
18
19
/**
20
 * @author Kevin Bond <[email protected]>
21
 */
22
final class RepositoryProxyTest extends KernelTestCase
23
{
24
    use ExpectDeprecationTrait, Factories, ResetDatabase;
25
26
    /**
27
     * @test
28
     */
29
    public function functions_calls_are_passed_to_underlying_repository(): void
30
    {
31
        $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

31
        $this->assertSame('from custom method', repository(Post::class)->/** @scrutinizer ignore-call */ customMethod());
Loading history...
32
    }
33
34
    /**
35
     * @test
36
     */
37
    public function assertions(): void
38
    {
39
        $repository = repository(Category::class);
40
41
        $repository->assert()->empty();
42
43
        CategoryFactory::createMany(2);
44
45
        $repository->assert()->count(2);
46
        $repository->assert()->countGreaterThan(1);
47
        $repository->assert()->countGreaterThanOrEqual(2);
48
        $repository->assert()->countLessThan(3);
49
        $repository->assert()->countLessThanOrEqual(2);
50
        $repository->assert()->exists([]);
51
        $repository->assert()->notExists(['name' => 'invalid']);
52
53
        Assert::that(function() use ($repository) { $repository->assert()->empty(); })
54
            ->throws(AssertionFailedError::class, \sprintf('Expected %s repository to be empty but it has 2 items.', Category::class))
55
        ;
56
        Assert::that(function() use ($repository) { $repository->assert()->count(1); })
57
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be 1.', Category::class))
58
        ;
59
        Assert::that(function() use ($repository) { $repository->assert()->countGreaterThan(2); })
60
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be greater than 2.', Category::class))
61
        ;
62
        Assert::that(function() use ($repository) { $repository->assert()->countGreaterThanOrEqual(3); })
63
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be greater than or equal to 3.', Category::class))
64
        ;
65
        Assert::that(function() use ($repository) { $repository->assert()->countLessThan(2); })
66
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be less than 2.', Category::class))
67
        ;
68
        Assert::that(function() use ($repository) { $repository->assert()->countLessThanOrEqual(1); })
69
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be less than or equal to 1.', Category::class))
70
        ;
71
        Assert::that(function() use ($repository) { $repository->assert()->exists(['name' => 'invalid-name']); })
72
            ->throws(AssertionFailedError::class, \sprintf('Expected %s to exist but it does not.', Category::class))
73
        ;
74
        Assert::that(function() use ($repository) { $repository->assert()->notExists([]); })
75
            ->throws(AssertionFailedError::class, \sprintf('Expected %s to not exist but it does.', Category::class))
76
        ;
77
    }
78
79
    /**
80
     * @test
81
     * @group legacy
82
     */
83
    public function legacy_assertions(): void
84
    {
85
        $repository = repository(Category::class);
86
87
        $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

87
        /** @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...
88
89
        CategoryFactory::createMany(2);
90
91
        $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

91
        /** @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...
92
        $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

92
        /** @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...
93
        $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

93
        /** @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...
94
        $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

94
        /** @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...
95
        $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

95
        /** @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...
96
    }
97
98
    /**
99
     * @test
100
     */
101
    public function can_fetch_objects(): void
102
    {
103
        $repository = repository(Category::class);
104
105
        CategoryFactory::createMany(2);
106
107
        $objects = $repository->findAll();
108
109
        $this->assertCount(2, $objects);
110
        $this->assertInstanceOf(Proxy::class, $objects[0]);
111
112
        $objects = $repository->findBy([]);
113
114
        $this->assertCount(2, $objects);
115
        $this->assertInstanceOf(Proxy::class, $objects[0]);
116
    }
117
118
    /**
119
     * @test
120
     */
121
    public function find_can_be_passed_proxy_or_object_or_array(): void
122
    {
123
        $repository = repository(Category::class);
124
        $proxy = CategoryFactory::createOne(['name' => 'foo']);
125
126
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy));
127
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy->object()));
128
        $this->assertInstanceOf(Proxy::class, $repository->find(['name' => 'foo']));
129
    }
130
131
    /**
132
     * @test
133
     */
134
    public function can_find_random_object(): void
135
    {
136
        CategoryFactory::createMany(5);
137
138
        $ids = [];
139
140
        while (5 !== \count(\array_unique($ids))) {
141
            $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

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

337
        $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...
338
    }
339
}
340