From 1f6de3390cabec923ffec4241cb8458edb7fc356 Mon Sep 17 00:00:00 2001 From: david_smith Date: Thu, 24 Oct 2024 15:55:50 -0400 Subject: [PATCH 1/4] Update `README.md`. --- README.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7e05c8e..85f383a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # `Zerotoprod\DataModelFactory` [![Repo](https://img.shields.io/badge/github-gray?logo=github)](https://github.com/zero-to-prod/data-model-factory) -[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/zero-to-prod/data-model-factory/phpunit.yml?label=tests)](https://github.com/zero-to-prod/data-model-factory/actions) +[![tests](https://img.shields.io/github/actions/workflow/status/zero-to-prod/data-model-factory/test.yml?label=tests)](https://github.com/zero-to-prod/data-model-factory/actions) [![Packagist Downloads](https://img.shields.io/packagist/dt/zero-to-prod/data-model-factory?color=blue)](https://packagist.org/packages/zero-to-prod/data-model-factory/stats) +[![php](https://img.shields.io/packagist/php-v/zero-to-prod/data-model-factory.svg?color=purple)](https://packagist.org/packages/zero-to-prod/data-model-factory/stats) [![Packagist Version](https://img.shields.io/packagist/v/zero-to-prod/data-model-factory?color=f28d1a)](https://packagist.org/packages/zero-to-prod/data-model-factory) -[![GitHub repo size](https://img.shields.io/github/repo-size/zero-to-prod/data-model-factory)](https://github.com/zero-to-prod/data-model-factory) -[![License](https://img.shields.io/packagist/l/zero-to-prod/data-model-factory?color=red)](https://github.com/zero-to-prod/data-model-factory/blob/main/LICENSE.md) +[![License](https://img.shields.io/packagist/l/zero-to-prod/data-model-factory?color=pink)](https://github.com/zero-to-prod/data-model-factory/blob/main/LICENSE.md) ## Installation @@ -39,6 +39,8 @@ If you don't want to use this trait, you can [customize the class instantiation] 2. Set the `$model` property to the class you want to instantiate. 3. Implement a `definition()` method that returns an array of default values. +> NOTE: The `$this->state()` method accepts dot syntax, arrays, or a callback. + ```php class User { @@ -46,6 +48,7 @@ class User public $first_name; public $last_name; + public $address; public static function factory(array $states = []): UserFactory { @@ -63,10 +66,18 @@ class UserFactory { return [ 'first_name' => 'John', - 'last_name' => 'N/A' + 'last_name' => 'N/A', + 'address' => [ + 'street' => 'Memory Lane' + ] ]; } + public function setStreet(string $value): self + { + return $this->state('address.street', $value); + } + public function setFirstName(string $value): self { return $this->state(['first_name' => $value]); From 5f9f53c87b61b117b47735536a131b6016ebe66b Mon Sep 17 00:00:00 2001 From: david_smith Date: Thu, 24 Oct 2024 15:56:10 -0400 Subject: [PATCH 2/4] Implement dot syntax for `Factory.php`. --- src/Factory.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Factory.php b/src/Factory.php index 05a221c..e6f223b 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -148,6 +148,11 @@ public function make() * Mutate the context before instantiating the class. * * ``` + * public function setValue($value): self + * { + * return $this->state('value.nested', $value); + * } + * * public function setValue($value): self * { * return $this->state(['value' => $value]); @@ -171,8 +176,23 @@ public function make() * @see https://github.com/zero-to-prod/data-model-helper * @see https://github.com/zero-to-prod/transformable */ - private function state($state): self + private function state($state, $value = null): self { + if (is_string($state)) { + $ref = &$this->context; + + foreach (explode('.', $state) as $key) { + if (!isset($ref[$key]) || !is_array($ref[$key])) { + $ref[$key] = []; + } + $ref = &$ref[$key]; + } + + $ref = $value; + + return $this; + } + $this->context = array_merge( $this->context, is_callable($state) ? $state($this->context) : $state From a0f72da482b1fa06df04ffb43f6568ddbc698390 Mon Sep 17 00:00:00 2001 From: david_smith Date: Thu, 24 Oct 2024 15:56:19 -0400 Subject: [PATCH 3/4] Added tests. --- tests/Unit/Method/FactoryTest.php | 28 ++++++++++++++++++++++++++++ tests/Unit/Method/User.php | 4 ++++ tests/Unit/Method/UserFactory.php | 18 +++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Method/FactoryTest.php b/tests/Unit/Method/FactoryTest.php index 4f1c9c8..4b04222 100644 --- a/tests/Unit/Method/FactoryTest.php +++ b/tests/Unit/Method/FactoryTest.php @@ -20,4 +20,32 @@ public function from(): void self::assertEquals('Jim', $User->first_name); self::assertEquals('N/A', $User->last_name); } + + /** + * @test + * + * @see Factory + */ + public function nested_element(): void + { + $User = User::factory() + ->setAddress('bogus') + ->make(); + + self::assertEquals('bogus', $User->address['street']); + } + + /** + * @test + * + * @see Factory + */ + public function nested_array(): void + { + $User = User::factory() + ->setShippingAddress(['bogus' => 'Bogus']) + ->make(); + + self::assertEquals(['bogus' => 'Bogus'], $User->shipping_address); + } } \ No newline at end of file diff --git a/tests/Unit/Method/User.php b/tests/Unit/Method/User.php index 3d6e4e4..6184703 100644 --- a/tests/Unit/Method/User.php +++ b/tests/Unit/Method/User.php @@ -10,8 +10,12 @@ class User public const first_name = 'first_name'; public const last_name = 'last_name'; + public const address = 'address'; + public const shipping_address = 'shipping_address'; public $first_name; public $last_name; + public $address; + public $shipping_address; public static function factory(array $states = []): UserFactory { diff --git a/tests/Unit/Method/UserFactory.php b/tests/Unit/Method/UserFactory.php index d287b51..9703f59 100644 --- a/tests/Unit/Method/UserFactory.php +++ b/tests/Unit/Method/UserFactory.php @@ -14,10 +14,26 @@ protected function definition(): array { return [ User::first_name => 'John', - User::last_name => 'N/A' + User::last_name => 'N/A', + User::address => [ + 'street' => '123 Main St', + ], + User::shipping_address => [ + 'street' => '123 Main St', + ] ]; } + public function setAddress(string $value): self + { + return $this->state('address.street', $value); + } + + public function setShippingAddress(array $value): self + { + return $this->state('shipping_address', $value); + } + public function setFirstName(string $value): self { return $this->state([User::first_name => $value]); From 0b8f97cd5685f26b1a54311754631ec977a78064 Mon Sep 17 00:00:00 2001 From: david_smith Date: Thu, 24 Oct 2024 15:56:33 -0400 Subject: [PATCH 4/4] Renamed `test.yml`. --- .github/workflows/{phpunit.yml => test.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{phpunit.yml => test.yml} (100%) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/test.yml similarity index 100% rename from .github/workflows/phpunit.yml rename to .github/workflows/test.yml