Passed
Pull Request — master (#59)
by Kevin
17:18
created

ModelFactoryTest::can_find_or_create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

155
        $this->assertCount(3, $post->/** @scrutinizer ignore-call */ getTags());
Loading history...
156
        TagFactory::repository()->assertCount(5); // 3 created by this test and 2 in global state
157
        PostFactory::repository()->assertCount(1);
158
    }
159
160
    /**
161
     * @test
162
     */
163
    public function inverse_many_to_many_with_nested_collection_relationship(): void
164
    {
165
        $tag = TagFactory::new()->create([
166
            'posts' => PostFactory::new()->many(3),
167
        ]);
168
169
        $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

169
        $this->assertCount(3, $tag->/** @scrutinizer ignore-call */ getPosts());
Loading history...
170
        TagFactory::repository()->assertCount(3); // 1 created by this test and 2 in global state
171
        PostFactory::repository()->assertCount(3);
172
    }
173
174
    /**
175
     * @test
176
     */
177
    public function create_multiple_many_to_many_with_nested_collection_relationship(): void
178
    {
179
        $posts = PostFactory::new()->createMany(2, [
180
            'tags' => TagFactory::new()->many(3),
181
        ]);
182
183
        $this->assertCount(3, $posts[0]->getTags());
184
        $this->assertCount(3, $posts[1]->getTags());
185
        TagFactory::repository()->assertCount(8); // 6 created by this test and 2 in global state
186
        PostFactory::repository()->assertCount(2);
187
    }
188
189
    /**
190
     * @test
191
     */
192
    public function unpersisted_one_to_many_with_nested_collection_relationship(): void
193
    {
194
        $post = PostFactory::new()->withoutPersisting()->create([
195
            'comments' => CommentFactory::new()->many(4),
196
        ]);
197
198
        $this->assertCount(4, $post->getComments());
199
        UserFactory::repository()->assertEmpty();
200
        CommentFactory::repository()->assertEmpty();
201
        PostFactory::repository()->assertEmpty();
202
    }
203
204
    /**
205
     * @test
206
     */
207
    public function unpersisted_many_to_many_with_nested_collection_relationship(): void
208
    {
209
        $post = PostFactory::new()->withoutPersisting()->create([
210
            'tags' => TagFactory::new()->many(3),
211
        ]);
212
213
        $this->assertCount(3, $post->getTags());
214
        TagFactory::repository()->assertCount(2); // 2 created in global state
215
        PostFactory::repository()->assertEmpty();
216
    }
217
218
    /**
219
     * @test
220
     * @dataProvider dataProvider
221
     */
222
    public function can_use_model_factories_in_a_data_provider(PostFactory $factory, bool $published): void
223
    {
224
        $post = $factory->create();
225
226
        $post->assertPersisted();
227
        $this->assertSame($published, $post->isPublished());
228
    }
229
230
    public static function dataProvider(): array
231
    {
232
        return [
233
            [PostFactory::new(), false],
234
            [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

234
            [PostFactory::new()->/** @scrutinizer ignore-call */ published(), true],
Loading history...
235
        ];
236
    }
237
}
238