Skip to content

[8.x] Add Conditional trait to Eloquent Factory #39228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Illuminate/Database/Eloquent/Factories/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\ForwardsCalls;
use Illuminate\Support\Traits\Macroable;
use Throwable;

abstract class Factory
{
use ForwardsCalls, Macroable {
use Conditionable, ForwardsCalls, Macroable {
__call as macroCall;
}

Expand Down
143 changes: 80 additions & 63 deletions tests/Database/DatabaseEloquentFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ public function test_multiple_model_attributes_can_be_created()
public function test_after_creating_and_making_callbacks_are_called()
{
$user = FactoryTestUserFactory::new()
->afterMaking(function ($user) {
$_SERVER['__test.user.making'] = $user;
})
->afterCreating(function ($user) {
$_SERVER['__test.user.creating'] = $user;
})
->create();
->afterMaking(function ($user) {
$_SERVER['__test.user.making'] = $user;
})
->afterCreating(function ($user) {
$_SERVER['__test.user.creating'] = $user;
})
->create();

$this->assertSame($user, $_SERVER['__test.user.making']);
$this->assertSame($user, $_SERVER['__test.user.creating']);
Expand All @@ -206,22 +206,22 @@ public function test_after_creating_and_making_callbacks_are_called()
public function test_has_many_relationship()
{
$users = FactoryTestUserFactory::times(10)
->has(
FactoryTestPostFactory::times(3)
->state(function ($attributes, $user) {
// Test parent is passed to child state mutations...
$_SERVER['__test.post.state-user'] = $user;

return [];
})
// Test parents passed to callback...
->afterCreating(function ($post, $user) {
$_SERVER['__test.post.creating-post'] = $post;
$_SERVER['__test.post.creating-user'] = $user;
}),
'posts'
)
->create();
->has(
FactoryTestPostFactory::times(3)
->state(function ($attributes, $user) {
// Test parent is passed to child state mutations...
$_SERVER['__test.post.state-user'] = $user;

return [];
})
// Test parents passed to callback...
->afterCreating(function ($post, $user) {
$_SERVER['__test.post.creating-post'] = $post;
$_SERVER['__test.post.creating-user'] = $user;
}),
'posts'
)
->create();

$this->assertCount(10, FactoryTestUser::all());
$this->assertCount(30, FactoryTestPost::all());
Expand All @@ -237,8 +237,8 @@ public function test_has_many_relationship()
public function test_belongs_to_relationship()
{
$posts = FactoryTestPostFactory::times(3)
->for(FactoryTestUserFactory::new(['name' => 'Taylor Otwell']), 'user')
->create();
->for(FactoryTestUserFactory::new(['name' => 'Taylor Otwell']), 'user')
->create();

$this->assertCount(3, $posts->filter(function ($post) {
return $post->user->name === 'Taylor Otwell';
Expand All @@ -252,8 +252,8 @@ public function test_belongs_to_relationship_with_existing_model_instance()
{
$user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->create();
$posts = FactoryTestPostFactory::times(3)
->for($user, 'user')
->create();
->for($user, 'user')
->create();

$this->assertCount(3, $posts->filter(function ($post) use ($user) {
return $post->user->is($user);
Expand All @@ -267,8 +267,8 @@ public function test_belongs_to_relationship_with_existing_model_instance_with_r
{
$user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->create();
$posts = FactoryTestPostFactory::times(3)
->for($user)
->create();
->for($user)
->create();

$this->assertCount(3, $posts->filter(function ($post) use ($user) {
return $post->factoryTestUser->is($user);
Expand All @@ -281,8 +281,8 @@ public function test_belongs_to_relationship_with_existing_model_instance_with_r
public function test_morph_to_relationship()
{
$posts = FactoryTestCommentFactory::times(3)
->for(FactoryTestPostFactory::new(['title' => 'Test Title']), 'commentable')
->create();
->for(FactoryTestPostFactory::new(['title' => 'Test Title']), 'commentable')
->create();

$this->assertSame('Test Title', FactoryTestPost::first()->title);
$this->assertCount(3, FactoryTestPost::first()->comments);
Expand All @@ -295,8 +295,8 @@ public function test_morph_to_relationship_with_existing_model_instance()
{
$post = FactoryTestPostFactory::new(['title' => 'Test Title'])->create();
$posts = FactoryTestCommentFactory::times(3)
->for($post, 'commentable')
->create();
->for($post, 'commentable')
->create();

$this->assertSame('Test Title', FactoryTestPost::first()->title);
$this->assertCount(3, FactoryTestPost::first()->comments);
Expand All @@ -308,15 +308,15 @@ public function test_morph_to_relationship_with_existing_model_instance()
public function test_belongs_to_many_relationship()
{
$users = FactoryTestUserFactory::times(3)
->hasAttached(
FactoryTestRoleFactory::times(3)->afterCreating(function ($role, $user) {
$_SERVER['__test.role.creating-role'] = $role;
$_SERVER['__test.role.creating-user'] = $user;
}),
['admin' => 'Y'],
'roles'
)
->create();
->hasAttached(
FactoryTestRoleFactory::times(3)->afterCreating(function ($role, $user) {
$_SERVER['__test.role.creating-role'] = $role;
$_SERVER['__test.role.creating-user'] = $user;
}),
['admin' => 'Y'],
'roles'
)
->create();

$this->assertCount(9, FactoryTestRole::all());

Expand All @@ -334,13 +334,13 @@ public function test_belongs_to_many_relationship()
public function test_belongs_to_many_relationship_with_existing_model_instances()
{
$roles = FactoryTestRoleFactory::times(3)
->afterCreating(function ($role) {
$_SERVER['__test.role.creating-role'] = $role;
})
->create();
->afterCreating(function ($role) {
$_SERVER['__test.role.creating-role'] = $role;
})
->create();
FactoryTestUserFactory::times(3)
->hasAttached($roles, ['admin' => 'Y'], 'roles')
->create();
->hasAttached($roles, ['admin' => 'Y'], 'roles')
->create();

$this->assertCount(3, FactoryTestRole::all());

Expand All @@ -357,13 +357,13 @@ public function test_belongs_to_many_relationship_with_existing_model_instances(
public function test_belongs_to_many_relationship_with_existing_model_instances_with_relationship_name_implied_from_model()
{
$roles = FactoryTestRoleFactory::times(3)
->afterCreating(function ($role) {
$_SERVER['__test.role.creating-role'] = $role;
})
->create();
->afterCreating(function ($role) {
$_SERVER['__test.role.creating-role'] = $role;
})
->create();
FactoryTestUserFactory::times(3)
->hasAttached($roles, ['admin' => 'Y'])
->create();
->hasAttached($roles, ['admin' => 'Y'])
->create();

$this->assertCount(3, FactoryTestRole::all());

Expand All @@ -388,12 +388,12 @@ public function test_sequences()
$this->assertSame('Abigail Otwell', $users[1]->name);

$user = FactoryTestUserFactory::new()
->hasAttached(
FactoryTestRoleFactory::times(4),
new Sequence(['admin' => 'Y'], ['admin' => 'N']),
'roles'
)
->create();
->hasAttached(
FactoryTestRoleFactory::times(4),
new Sequence(['admin' => 'Y'], ['admin' => 'N']),
'roles'
)
->create();

$this->assertCount(4, $user->roles);

Expand Down Expand Up @@ -468,9 +468,9 @@ public function test_dynamic_has_and_for_methods()
$this->assertCount(3, $user->posts);

$post = FactoryTestPostFactory::new()
->forAuthor(['name' => 'Taylor Otwell'])
->hasComments(2)
->create();
->forAuthor(['name' => 'Taylor Otwell'])
->hasComments(2)
->create();

$this->assertInstanceOf(FactoryTestUser::class, $post->author);
$this->assertSame('Taylor Otwell', $post->author->name);
Expand All @@ -487,6 +487,23 @@ public function test_can_be_macroable()
$this->assertSame('Hello World', $factory->getFoo());
}

public function test_factory_can_conditionally_execute_code()
{
FactoryTestUserFactory::new()
->when(true, function () {
$this->assertTrue(true);
})
->when(false, function () {
$this->fail('Unreachable code that has somehow been reached.');
})
->unless(false, function () {
$this->assertTrue(true);
})
->unless(true, function () {
$this->fail('Unreachable code that has somehow been reached.');
});
}

/**
* Get a database connection instance.
*
Expand Down