Passed
Pull Request — master (#59)
by Kevin
35:33 queued 15:34
created

can_find_random_range_of_objects()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 17
rs 9.9
1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
6
use Zenstruck\Foundry\Test\Factories;
7
use Zenstruck\Foundry\Test\ResetDatabase;
8
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
9
use Zenstruck\Foundry\Tests\Fixtures\Factories\CommentFactory;
10
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
11
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithInvalidInitialize;
12
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithNullInitialize;
13
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithValidInitialize;
14
use Zenstruck\Foundry\Tests\Fixtures\Factories\TagFactory;
15
use Zenstruck\Foundry\Tests\Fixtures\Factories\UserFactory;
16
17
/**
18
 * @author Kevin Bond <[email protected]>
19
 */
20
final class ModelFactoryTest extends KernelTestCase
21
{
22
    use ResetDatabase, Factories;
23
24
    /**
25
     * @test
26
     */
27
    public function can_find_or_create(): void
28
    {
29
        CategoryFactory::repository()->assertCount(0);
30
        CategoryFactory::findOrCreate(['name' => 'php']);
31
        CategoryFactory::repository()->assertCount(1);
32
        CategoryFactory::findOrCreate(['name' => 'php']);
33
        CategoryFactory::repository()->assertCount(1);
34
    }
35
36
    /**
37
     * @test
38
     */
39
    public function can_override_initialize(): void
40
    {
41
        $this->assertFalse(PostFactory::new()->create()->isPublished());
0 ignored issues
show
Bug introduced by
The method isPublished() 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

41
        $this->assertFalse(PostFactory::new()->create()->/** @scrutinizer ignore-call */ isPublished());
Loading history...
42
        $this->assertTrue(PostFactoryWithValidInitialize::new()->create()->isPublished());
43
    }
44
45
    /**
46
     * @test
47
     */
48
    public function initialize_must_return_an_instance_of_the_current_factory(): void
49
    {
50
        $this->expectException(\TypeError::class);
51
        $this->expectExceptionMessage(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', PostFactoryWithInvalidInitialize::class));
52
53
        PostFactoryWithInvalidInitialize::new();
54
    }
55
56
    /**
57
     * @test
58
     */
59
    public function initialize_must_return_a_value(): void
60
    {
61
        $this->expectException(\TypeError::class);
62
        $this->expectExceptionMessage(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', PostFactoryWithNullInitialize::class));
63
64
        PostFactoryWithNullInitialize::new();
65
    }
66
67
    /**
68
     * @test
69
     */
70
    public function can_find_random_object(): void
71
    {
72
        CategoryFactory::new()->createMany(5);
73
74
        $ids = [];
75
76
        while (5 !== \count(\array_unique($ids))) {
77
            $ids[] = CategoryFactory::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

77
            $ids[] = CategoryFactory::random()->/** @scrutinizer ignore-call */ getId();
Loading history...
78
        }
79
80
        $this->assertCount(5, \array_unique($ids));
81
    }
82
83
    /**
84
     * @test
85
     */
86
    public function can_find_random_set_of_objects(): void
87
    {
88
        CategoryFactory::new()->createMany(5);
89
90
        $objects = CategoryFactory::randomSet(3);
91
92
        $this->assertCount(3, $objects);
93
        $this->assertCount(3, \array_unique(\array_map(static function($category) { return $category->getId(); }, $objects)));
94
    }
95
96
    /**
97
     * @test
98
     */
99
    public function can_find_random_range_of_objects(): void
100
    {
101
        CategoryFactory::new()->createMany(5);
102
103
        $counts = [];
104
105
        while (4 !== \count(\array_unique($counts))) {
106
            $counts[] = \count(CategoryFactory::randomRange(0, 3));
107
        }
108
109
        $this->assertCount(4, \array_unique($counts));
110
        $this->assertContains(0, $counts);
111
        $this->assertContains(1, $counts);
112
        $this->assertContains(2, $counts);
113
        $this->assertContains(3, $counts);
114
        $this->assertNotContains(4, $counts);
115
        $this->assertNotContains(5, $counts);
116
    }
117
118
    /**
119
     * @test
120
     */
121
    public function one_to_many_with_nested_collection_relationship(): void
122
    {
123
        $post = PostFactory::new()->create([
124
            'comments' => CommentFactory::new()->many(4),
125
        ]);
126
127
        $this->assertCount(4, $post->getComments());
0 ignored issues
show
Bug introduced by
The method getComments() 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

127
        $this->assertCount(4, $post->/** @scrutinizer ignore-call */ getComments());
Loading history...
128
        UserFactory::repository()->assertCount(4);
129
        CommentFactory::repository()->assertCount(4);
130
        PostFactory::repository()->assertCount(1);
131
    }
132
133
    /**
134
     * @test
135
     */
136
    public function create_multiple_one_to_many_with_nested_collection_relationship(): void
137
    {
138
        $user = UserFactory::new()->create();
139
        $posts = PostFactory::new()->createMany(2, [
140
            'comments' => CommentFactory::new(['user' => $user])->many(4),
141
        ]);
142
143
        $this->assertCount(4, $posts[0]->getComments());
144
        $this->assertCount(4, $posts[1]->getComments());
145
        UserFactory::repository()->assertCount(1);
146
        CommentFactory::repository()->assertCount(8);
147
        PostFactory::repository()->assertCount(2);
148
    }
149
150
    /**
151
     * @test
152
     */
153
    public function many_to_many_with_nested_collection_relationship(): void
154
    {
155
        $post = PostFactory::new()->create([
156
            'tags' => TagFactory::new()->many(3),
157
        ]);
158
159
        $this->assertCount(3, $post->getTags());
0 ignored issues
show
Bug introduced by
The method getTags() 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

159
        $this->assertCount(3, $post->/** @scrutinizer ignore-call */ getTags());
Loading history...
160
        TagFactory::repository()->assertCount(5); // 3 created by this test and 2 in global state
161
        PostFactory::repository()->assertCount(1);
162
    }
163
164
    /**
165
     * @test
166
     */
167
    public function inverse_many_to_many_with_nested_collection_relationship(): void
168
    {
169
        $tag = TagFactory::new()->create([
170
            'posts' => PostFactory::new()->many(3),
171
        ]);
172
173
        $this->assertCount(3, $tag->getPosts());
0 ignored issues
show
Bug introduced by
The method getPosts() 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

173
        $this->assertCount(3, $tag->/** @scrutinizer ignore-call */ getPosts());
Loading history...
174
        TagFactory::repository()->assertCount(3); // 1 created by this test and 2 in global state
175
        PostFactory::repository()->assertCount(3);
176
    }
177
178
    /**
179
     * @test
180
     */
181
    public function create_multiple_many_to_many_with_nested_collection_relationship(): void
182
    {
183
        $posts = PostFactory::new()->createMany(2, [
184
            'tags' => TagFactory::new()->many(3),
185
        ]);
186
187
        $this->assertCount(3, $posts[0]->getTags());
188
        $this->assertCount(3, $posts[1]->getTags());
189
        TagFactory::repository()->assertCount(8); // 6 created by this test and 2 in global state
190
        PostFactory::repository()->assertCount(2);
191
    }
192
193
    /**
194
     * @test
195
     */
196
    public function unpersisted_one_to_many_with_nested_collection_relationship(): void
197
    {
198
        $post = PostFactory::new()->withoutPersisting()->create([
199
            'comments' => CommentFactory::new()->many(4),
200
        ]);
201
202
        $this->assertCount(4, $post->getComments());
203
        UserFactory::repository()->assertEmpty();
204
        CommentFactory::repository()->assertEmpty();
205
        PostFactory::repository()->assertEmpty();
206
    }
207
208
    /**
209
     * @test
210
     */
211
    public function unpersisted_many_to_many_with_nested_collection_relationship(): void
212
    {
213
        $post = PostFactory::new()->withoutPersisting()->create([
214
            'tags' => TagFactory::new()->many(3),
215
        ]);
216
217
        $this->assertCount(3, $post->getTags());
218
        TagFactory::repository()->assertCount(2); // 2 created in global state
219
        PostFactory::repository()->assertEmpty();
220
    }
221
222
    /**
223
     * @test
224
     * @dataProvider dataProvider
225
     */
226
    public function can_use_model_factories_in_a_data_provider(PostFactory $factory, bool $published): void
227
    {
228
        $post = $factory->create();
229
230
        $post->assertPersisted();
231
        $this->assertSame($published, $post->isPublished());
232
    }
233
234
    public static function dataProvider(): array
235
    {
236
        return [
237
            [PostFactory::new(), false],
238
            [PostFactory::new()->published(), true],
0 ignored issues
show
Bug introduced by
The method published() does not exist on Zenstruck\Foundry\ModelFactory. It seems like you code against a sub-type of Zenstruck\Foundry\ModelFactory such as Zenstruck\Foundry\Tests\...s\Factories\PostFactory. ( Ignorable by Annotation )

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

238
            [PostFactory::new()->/** @scrutinizer ignore-call */ published(), true],
Loading history...
239
        ];
240
    }
241
}
242