Issues (131)

tests/Functional/RepositoryProxyTest.php (9 issues)

1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use PHPUnit\Framework\AssertionFailedError;
0 ignored issues
show
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...
6
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
7
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
8
use Zenstruck\Assert;
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 function Zenstruck\Foundry\repository;
14
15
/**
16
 * @author Kevin Bond <[email protected]>
17
 */
18
abstract class RepositoryProxyTest extends KernelTestCase
19
{
20
    use ExpectDeprecationTrait, Factories, ResetDatabase;
21
22
    /**
23
     * @test
24
     */
25
    public function assertions(): void
26
    {
27
        $repository = repository($this->categoryClass());
28
29
        $repository->assert()->empty();
30
31
        $this->categoryFactoryClass()::createMany(2);
32
33
        $repository->assert()->count(2);
34
        $repository->assert()->countGreaterThan(1);
35
        $repository->assert()->countGreaterThanOrEqual(2);
36
        $repository->assert()->countLessThan(3);
37
        $repository->assert()->countLessThanOrEqual(2);
38
        $repository->assert()->exists([]);
39
        $repository->assert()->notExists(['name' => 'invalid']);
40
41
        Assert::that(function() use ($repository) { $repository->assert()->empty(); })
42
            ->throws(AssertionFailedError::class, \sprintf('Expected %s repository to be empty but it has 2 items.', $this->categoryClass()))
43
        ;
44
        Assert::that(function() use ($repository) { $repository->assert()->count(1); })
45
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be 1.', $this->categoryClass()))
46
        ;
47
        Assert::that(function() use ($repository) { $repository->assert()->countGreaterThan(2); })
48
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be greater than 2.', $this->categoryClass()))
49
        ;
50
        Assert::that(function() use ($repository) { $repository->assert()->countGreaterThanOrEqual(3); })
51
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be greater than or equal to 3.', $this->categoryClass()))
52
        ;
53
        Assert::that(function() use ($repository) { $repository->assert()->countLessThan(2); })
54
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be less than 2.', $this->categoryClass()))
55
        ;
56
        Assert::that(function() use ($repository) { $repository->assert()->countLessThanOrEqual(1); })
57
            ->throws(AssertionFailedError::class, \sprintf('Expected count of %s repository (2) to be less than or equal to 1.', $this->categoryClass()))
58
        ;
59
        Assert::that(function() use ($repository) { $repository->assert()->exists(['name' => 'invalid-name']); })
60
            ->throws(AssertionFailedError::class, \sprintf('Expected %s to exist but it does not.', $this->categoryClass()))
61
        ;
62
        Assert::that(function() use ($repository) { $repository->assert()->notExists([]); })
63
            ->throws(AssertionFailedError::class, \sprintf('Expected %s to not exist but it does.', $this->categoryClass()))
64
        ;
65
    }
66
67
    /**
68
     * @test
69
     * @group legacy
70
     */
71
    public function assertions_legacy(): void
72
    {
73
        $repository = repository($this->categoryClass());
74
75
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertEmpty() is deprecated, use RepositoryProxy::assert()->empty().');
76
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCount() is deprecated, use RepositoryProxy::assert()->count().');
77
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThan() is deprecated, use RepositoryProxy::assert()->countGreaterThan().');
78
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThanOrEqual() is deprecated, use RepositoryProxy::assert()->countGreaterThanOrEqual().');
79
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThan() is deprecated, use RepositoryProxy::assert()->countLessThan().');
80
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThanOrEqual() is deprecated, use RepositoryProxy::assert()->countLessThanOrEqual().');
81
82
        $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

82
        /** @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...
83
84
        $this->categoryFactoryClass()::createMany(2);
85
86
        $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

86
        /** @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...
87
        $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

87
        /** @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...
88
        $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

88
        /** @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...
89
        $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

89
        /** @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...
90
        $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

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

139
            $ids[] = repository($this->categoryClass())->random()->/** @scrutinizer ignore-call */ getId();
Loading history...
140
        }
141
142
        $this->assertCount(5, \array_unique($ids));
143
    }
144
145
    /**
146
     * @test
147
     */
148
    public function at_least_one_object_must_exist_to_get_random_object(): void
149
    {
150
        $this->expectException(\RuntimeException::class);
151
        $this->expectExceptionMessage(\sprintf('At least 1 "%s" object(s) must have been persisted (0 persisted).', $this->categoryClass()));
152
153
        repository($this->categoryClass())->random();
154
    }
155
156
    /**
157
     * @test
158
     */
159
    public function can_find_random_set_of_objects(): void
160
    {
161
        $this->categoryFactoryClass()::createMany(5);
162
163
        $objects = repository($this->categoryClass())->randomSet(3);
164
165
        $this->assertCount(3, $objects);
166
        $this->assertCount(
167
            3,
168
            \array_unique(
169
                \array_map(
170
                    static function($category) {
171
                        return $category->getId();
172
                    },
173
                    $objects
174
                )
175
            )
176
        );
177
    }
178
179
    /**
180
     * @test
181
     */
182
    public function random_set_number_must_be_positive(): void
183
    {
184
        $this->expectException(\InvalidArgumentException::class);
185
        $this->expectExceptionMessage('$number must be positive (-1 given).');
186
187
        repository($this->categoryClass())->randomSet(-1);
188
    }
189
190
    /**
191
     * @test
192
     */
193
    public function the_number_of_persisted_objects_must_be_at_least_the_random_set_number(): void
194
    {
195
        $this->categoryFactoryClass()::createOne();
196
197
        $this->expectException(\RuntimeException::class);
198
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', $this->categoryClass()));
199
200
        repository($this->categoryClass())->randomSet(2);
201
    }
202
203
    /**
204
     * @test
205
     */
206
    public function can_find_random_range_of_objects(): void
207
    {
208
        $this->categoryFactoryClass()::createMany(5);
209
210
        $counts = [];
211
212
        while (4 !== \count(\array_unique($counts))) {
213
            $counts[] = \count(repository($this->categoryClass())->randomRange(0, 3));
214
        }
215
216
        $this->assertCount(4, \array_unique($counts));
217
        $this->assertContains(0, $counts);
218
        $this->assertContains(1, $counts);
219
        $this->assertContains(2, $counts);
220
        $this->assertContains(3, $counts);
221
        $this->assertNotContains(4, $counts);
222
        $this->assertNotContains(5, $counts);
223
    }
224
225
    /**
226
     * @test
227
     */
228
    public function the_number_of_persisted_objects_must_be_at_least_the_random_range_max(): void
229
    {
230
        $this->categoryFactoryClass()::createOne();
231
232
        $this->expectException(\RuntimeException::class);
233
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', $this->categoryClass()));
234
235
        repository($this->categoryClass())->randomRange(0, 2);
236
    }
237
238
    /**
239
     * @test
240
     */
241
    public function random_range_min_cannot_be_less_than_zero(): void
242
    {
243
        $this->expectException(\InvalidArgumentException::class);
244
        $this->expectExceptionMessage('$min must be positive (-1 given).');
245
246
        repository($this->categoryClass())->randomRange(-1, 3);
247
    }
248
249
    /**
250
     * @test
251
     */
252
    public function random_set_max_cannot_be_less_than_min(): void
253
    {
254
        $this->expectException(\InvalidArgumentException::class);
255
        $this->expectExceptionMessage('$max (3) cannot be less than $min (5).');
256
257
        repository($this->categoryClass())->randomRange(5, 3);
258
    }
259
260
    /**
261
     * @test
262
     */
263
    public function first_and_last_return_the_correct_object(): void
264
    {
265
        $categoryFactoryClass = $this->categoryFactoryClass();
266
267
        $categoryA = $categoryFactoryClass::createOne(['name' => '3']);
268
        $categoryB = $categoryFactoryClass::createOne(['name' => '2']);
0 ignored issues
show
The assignment to $categoryB is dead and can be removed.
Loading history...
269
        $categoryC = $categoryFactoryClass::createOne(['name' => '1']);
270
        $repository = $categoryFactoryClass::repository();
271
272
        $this->assertSame($categoryA->getId(), $repository->first()->getId());
273
        $this->assertSame($categoryC->getId(), $repository->first('name')->getId());
274
        $this->assertSame($categoryC->getId(), $repository->last()->getId());
275
        $this->assertSame($categoryA->getId(), $repository->last('name')->getId());
276
    }
277
278
    /**
279
     * @test
280
     */
281
    public function first_and_last_return_null_if_empty(): void
282
    {
283
        $categoryFactoryClass = $this->categoryFactoryClass();
284
285
        $this->assertNull($categoryFactoryClass::repository()->first());
286
        $this->assertNull($categoryFactoryClass::repository()->first('name'));
287
        $this->assertNull($categoryFactoryClass::repository()->last());
288
        $this->assertNull($categoryFactoryClass::repository()->last('name'));
289
    }
290
291
    /**
292
     * @test
293
     */
294
    public function repository_proxy_is_countable_and_iterable(): void
295
    {
296
        $categoryFactoryClass = $this->categoryFactoryClass();
297
298
        $categoryFactoryClass::createMany(4);
299
300
        $repository = $categoryFactoryClass::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
        $categoryFactoryClass = $this->categoryFactoryClass();
313
314
        $categoryFactoryClass::createMany(4);
315
316
        $this->expectDeprecation('Since zenstruck\foundry 1.5.0: Using RepositoryProxy::getCount() is deprecated, use RepositoryProxy::count() (it is now Countable).');
317
318
        $this->assertSame(4, $categoryFactoryClass::repository()->getCount());
319
    }
320
321
    abstract protected function categoryClass(): string;
322
323
    abstract protected function categoryFactoryClass(): string;
324
}
325