From 0917a0daa1142a87989371f745779bdfb09e31a9 Mon Sep 17 00:00:00 2001 From: Thomas van der Veen Date: Fri, 21 Jan 2022 14:40:52 +0100 Subject: [PATCH 1/4] Added class to create matrix sequences for factories --- .../Eloquent/Factories/MatrixSequence.php | 24 +++++++++++++++++ .../Database/DatabaseEloquentFactoryTest.php | 27 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php diff --git a/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php b/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php new file mode 100644 index 000000000000..2ce00f7ed32d --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php @@ -0,0 +1,24 @@ + array_merge(...$a), + Arr::crossJoin(...$sequences), + ); + + parent::__construct(...$matrix); + } +} diff --git a/tests/Database/DatabaseEloquentFactoryTest.php b/tests/Database/DatabaseEloquentFactoryTest.php index f30276d06ffd..37dd21efe169 100644 --- a/tests/Database/DatabaseEloquentFactoryTest.php +++ b/tests/Database/DatabaseEloquentFactoryTest.php @@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Factories\MatrixSequence; use Illuminate\Database\Eloquent\Factories\Sequence; use Illuminate\Database\Eloquent\Model as Eloquent; use Mockery; @@ -413,6 +414,32 @@ public function test_sequences() $this->assertSame('index: 1', $users[1]->name); } + public function test_matrix_sequence() + { + $users = FactoryTestUserFactory::times(4) + ->state( + new MatrixSequence( + [['first_name' => 'Thomas'], ['first_name' => 'Agent']], + [['last_name' => 'Anderson'], ['last_name' => 'Smith']], + ), + ) + ->make(); + + $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'), + ); + } + } + public function test_resolve_nested_model_factories() { Factory::useNamespace('Factories\\'); From cfbebc6c141f6e3e5602cd0879e8fc01776ce38b Mon Sep 17 00:00:00 2001 From: Thomas van der Veen Date: Fri, 21 Jan 2022 15:06:46 +0100 Subject: [PATCH 2/4] Fix for php7.3 support --- src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php b/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php index 2ce00f7ed32d..04f95b67becc 100644 --- a/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php +++ b/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php @@ -15,7 +15,9 @@ class MatrixSequence extends Sequence public function __construct(...$sequences) { $matrix = array_map( - fn ($a) => array_merge(...$a), + function ($a) { + return array_merge(...$a); + }, Arr::crossJoin(...$sequences), ); From bdf7ec9f098e7f8c131effd0815c302b33a80e5a Mon Sep 17 00:00:00 2001 From: Thomas van der Veen Date: Thu, 27 Jan 2022 18:34:30 +0100 Subject: [PATCH 3/4] Rename MatrixSequence to CrossJoinSequence. Add crossJoinSequence method to Factory. --- ...trixSequence.php => CrossJoinSequence.php} | 8 ++-- .../Database/Eloquent/Factories/Factory.php | 11 +++++ .../Database/DatabaseEloquentFactoryTest.php | 45 ++++++++++++------- 3 files changed, 44 insertions(+), 20 deletions(-) rename src/Illuminate/Database/Eloquent/Factories/{MatrixSequence.php => CrossJoinSequence.php} (68%) diff --git a/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php b/src/Illuminate/Database/Eloquent/Factories/CrossJoinSequence.php similarity index 68% rename from src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php rename to src/Illuminate/Database/Eloquent/Factories/CrossJoinSequence.php index 04f95b67becc..b0efbd0c805b 100644 --- a/src/Illuminate/Database/Eloquent/Factories/MatrixSequence.php +++ b/src/Illuminate/Database/Eloquent/Factories/CrossJoinSequence.php @@ -4,23 +4,23 @@ use Illuminate\Support\Arr; -class MatrixSequence extends Sequence +class CrossJoinSequence extends Sequence { /** - * Create a new matrix sequence instance. + * Create a new cross join sequence instance. * * @param array $sequences * @return void */ public function __construct(...$sequences) { - $matrix = array_map( + $crossJoined = array_map( function ($a) { return array_merge(...$a); }, Arr::crossJoin(...$sequences), ); - parent::__construct(...$matrix); + parent::__construct(...$crossJoined); } } diff --git a/src/Illuminate/Database/Eloquent/Factories/Factory.php b/src/Illuminate/Database/Eloquent/Factories/Factory.php index 9bdce1c74563..0735b8c0270b 100644 --- a/src/Illuminate/Database/Eloquent/Factories/Factory.php +++ b/src/Illuminate/Database/Eloquent/Factories/Factory.php @@ -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. * diff --git a/tests/Database/DatabaseEloquentFactoryTest.php b/tests/Database/DatabaseEloquentFactoryTest.php index 37dd21efe169..7b962cbe41a7 100644 --- a/tests/Database/DatabaseEloquentFactoryTest.php +++ b/tests/Database/DatabaseEloquentFactoryTest.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Factories\MatrixSequence; +use Illuminate\Database\Eloquent\Factories\CrossJoinSequence; use Illuminate\Database\Eloquent\Factories\Sequence; use Illuminate\Database\Eloquent\Model as Eloquent; use Mockery; @@ -414,30 +414,43 @@ public function test_sequences() $this->assertSame('index: 1', $users[1]->name); } - public function test_matrix_sequence() + public function test_cross_join_sequences() { - $users = FactoryTestUserFactory::times(4) + $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 MatrixSequence( + new CrossJoinSequence( [['first_name' => 'Thomas'], ['first_name' => 'Agent']], [['last_name' => 'Anderson'], ['last_name' => 'Smith']], ), ) ->make(); - $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'], - ]; + $assert($usersByClass); - foreach ($assertions as $key => $assertion) { - $this->assertSame( - $assertion, - $users[$key]->only('first_name', 'last_name'), - ); - } + $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() From 90ed154c32a43f8114100c27d103917e2e6153d9 Mon Sep 17 00:00:00 2001 From: Thomas van der Veen Date: Thu, 27 Jan 2022 18:39:02 +0100 Subject: [PATCH 4/4] Fix import order lint failure. --- tests/Database/DatabaseEloquentFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Database/DatabaseEloquentFactoryTest.php b/tests/Database/DatabaseEloquentFactoryTest.php index 7b962cbe41a7..3b7e28217b49 100644 --- a/tests/Database/DatabaseEloquentFactoryTest.php +++ b/tests/Database/DatabaseEloquentFactoryTest.php @@ -7,9 +7,9 @@ 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\CrossJoinSequence; use Illuminate\Database\Eloquent\Factories\Sequence; use Illuminate\Database\Eloquent\Model as Eloquent; use Mockery;