Skip to content

Commit

Permalink
add model factory after callbacks with states
Browse files Browse the repository at this point in the history
  • Loading branch information
Carl Olsen committed Mar 19, 2018
1 parent 350ea24 commit bc4624c
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 14 deletions.
34 changes: 32 additions & 2 deletions src/Illuminate/Database/Eloquent/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,22 @@ public function state($class, $state, $attributes)
*/
public function afterMaking($class, $callback)
{
$this->afterMaking[$class][] = $callback;
$this->afterMaking[$class]['default'][] = $callback;

return $this;
}

/**
* Define a callback to run after making a model with given type.
*
* @param string $class
* @param string $state
* @param callable $callback
* @return $this
*/
public function afterMakingState($class, $state, callable $callback)
{
$this->afterMaking[$class][$state][] = $callback;

return $this;
}
Expand All @@ -134,7 +149,22 @@ public function afterMaking($class, $callback)
*/
public function afterCreating($class, $callback)
{
$this->afterCreating[$class][] = $callback;
$this->afterCreating[$class]['default'][] = $callback;

return $this;
}

/**
* Define a callback to run after creating a model with given type.
*
* @param string $class
* @param string $state
* @param callable $callback
* @return $this
*/
public function afterCreatingState($class, $state, callable $callback)
{
$this->afterCreating[$class][$state][] = $callback;

return $this;
}
Expand Down
61 changes: 49 additions & 12 deletions src/Illuminate/Database/Eloquent/FactoryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ protected function applyStates(array $definition, array $attributes = [])
{
foreach ($this->activeStates as $state) {
if (! isset($this->states[$this->class][$state])) {
if ($this->afterStateExists($state)) {
continue;
}
throw new InvalidArgumentException("Unable to locate [{$state}] state for [{$this->class}].");
}

Expand Down Expand Up @@ -366,13 +369,7 @@ protected function expandAttributes(array $attributes)
*/
public function callAfterMaking($models)
{
$models->each(function ($model) {
if (isset($this->afterMaking[$this->class])) {
foreach ($this->afterMaking[$this->class] as $callback) {
$callback($model, $this->faker);
}
}
});
$this->callAfter($this->afterMaking, $models);
}

/**
Expand All @@ -383,12 +380,52 @@ public function callAfterMaking($models)
*/
public function callAfterCreating($models)
{
$models->each(function ($model) {
if (isset($this->afterCreating[$this->class])) {
foreach ($this->afterCreating[$this->class] as $callback) {
$callback($model, $this->faker);
}
$this->callAfter($this->afterCreating, $models);
}

/**
* Call after callbacks for each model and state.
*
* @param array $afterCallbacks
* @param \Illuminate\Support\Collection $models
* @return void
*/
protected function callAfter(array $afterCallbacks, $models)
{
$states = array_merge([$this->name], $this->activeStates);

$models->each(function ($model) use ($states, $afterCallbacks) {
foreach ($states as $state) {
$this->callAfterCallbacks($afterCallbacks, $model, $state);
}
});
}

/**
* Call after callbacks for each model and state.
*
* @param array $afterCallbacks
* @param Model $model
* @param string $state
* @return void
*/
protected function callAfterCallbacks(array $afterCallbacks, $model, $state)
{
if (!isset($afterCallbacks[$this->class][$state])) {
return;
}

foreach ($afterCallbacks[$this->class][$state] as $callback) {
$callback($model, $this->faker);
}
}

/**
* @param string $state
* @return bool
*/
protected function afterStateExists($state)
{
return isset($this->afterMaking[$this->class][$state]) || isset($this->afterCreating[$this->class][$state]);
}
}
32 changes: 32 additions & 0 deletions tests/Integration/Database/EloquentFactoryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ protected function getEnvironmentSetUp($app)
$user->setRelation('profile', $profile);
});

$factory->afterMakingState(FactoryBuildableUser::class, 'with_callable_server', function (FactoryBuildableUser $user, Generator $faker) {
$server = factory(FactoryBuildableServer::class)
->states('callable')
->make(['user_id' => $user->id]);

$user->servers->push($server);
});

$factory->define(FactoryBuildableTeam::class, function (Generator $faker) {
return [
'name' => $faker->name,
Expand Down Expand Up @@ -81,6 +89,12 @@ protected function getEnvironmentSetUp($app)
];
});

$factory->afterCreatingState(FactoryBuildableUser::class, 'with_callable_server', function(FactoryBuildableUser $user, Generator $faker){
$server = factory(FactoryBuildableServer::class)
->states('callable')
->create(['user_id' => $user->id]);
});

$factory->state(FactoryBuildableServer::class, 'inline', ['status' => 'inline']);

$app->singleton(Factory::class, function ($app) use ($factory) {
Expand Down Expand Up @@ -234,6 +248,15 @@ public function creating_models_with_after_callback()
$this->assertTrue($team->users->contains($team->owner));
}

/** @test **/
public function creating_models_with_after_callback_states()
{
$user = factory(FactoryBuildableUser::class)->states('with_callable_server')->create();

$this->assertNotNull($user->profile);
$this->assertNotNull($user->servers->where('status', 'callable')->first());
}

/** @test */
public function making_models_with_a_custom_connection()
{
Expand All @@ -251,6 +274,15 @@ public function making_models_with_after_callback()

$this->assertNotNull($user->profile);
}

/** @test **/
public function making_models_with_after_callback_states()
{
$user = factory(FactoryBuildableUser::class)->states('with_callable_server')->make();

$this->assertNotNull($user->profile);
$this->assertNotNull($user->servers->where('status', 'callable')->first());
}
}

class FactoryBuildableUser extends Model
Expand Down

0 comments on commit bc4624c

Please sign in to comment.