Skip to content

Commit

Permalink
[8.x] Added class and method to create cross joined sequences for fac…
Browse files Browse the repository at this point in the history
…tories (#40542)

* Added class to create matrix sequences for factories

* Fix for php7.3 support

* Rename MatrixSequence to CrossJoinSequence. Add crossJoinSequence method to Factory.

* Fix import order lint failure.
  • Loading branch information
thomasowow authored Jan 27, 2022
1 parent ffba472 commit 22e32b9
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Eloquent/Factories/CrossJoinSequence.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Illuminate\Database\Eloquent\Factories;

use Illuminate\Support\Arr;

class CrossJoinSequence extends Sequence
{
/**
* Create a new cross join sequence instance.
*
* @param array $sequences
* @return void
*/
public function __construct(...$sequences)
{
$crossJoined = array_map(
function ($a) {
return array_merge(...$a);
},
Arr::crossJoin(...$sequences),
);

parent::__construct(...$crossJoined);
}
}
11 changes: 11 additions & 0 deletions src/Illuminate/Database/Eloquent/Factories/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,17 @@ public function sequence(...$sequence)
return $this->state(new Sequence(...$sequence));
}

/**
* Add a new cross joined sequenced state transformation to the model definition.
*
* @param array $sequence
* @return static
*/
public function crossJoinSequence(...$sequence)
{
return $this->state(new CrossJoinSequence(...$sequence));
}

/**
* Define a child relationship for the model.
*
Expand Down
40 changes: 40 additions & 0 deletions tests/Database/DatabaseEloquentFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\CrossJoinSequence;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Factories\Sequence;
Expand Down Expand Up @@ -413,6 +414,45 @@ public function test_sequences()
$this->assertSame('index: 1', $users[1]->name);
}

public function test_cross_join_sequences()
{
$assert = function ($users) {
$assertions = [
['first_name' => 'Thomas', 'last_name' => 'Anderson'],
['first_name' => 'Thomas', 'last_name' => 'Smith'],
['first_name' => 'Agent', 'last_name' => 'Anderson'],
['first_name' => 'Agent', 'last_name' => 'Smith'],
];

foreach ($assertions as $key => $assertion) {
$this->assertSame(
$assertion,
$users[$key]->only('first_name', 'last_name'),
);
}
};

$usersByClass = FactoryTestUserFactory::times(4)
->state(
new CrossJoinSequence(
[['first_name' => 'Thomas'], ['first_name' => 'Agent']],
[['last_name' => 'Anderson'], ['last_name' => 'Smith']],
),
)
->make();

$assert($usersByClass);

$usersByMethod = FactoryTestUserFactory::times(4)
->crossJoinSequence(
[['first_name' => 'Thomas'], ['first_name' => 'Agent']],
[['last_name' => 'Anderson'], ['last_name' => 'Smith']],
)
->make();

$assert($usersByMethod);
}

public function test_resolve_nested_model_factories()
{
Factory::useNamespace('Factories\\');
Expand Down

0 comments on commit 22e32b9

Please sign in to comment.