Skip to content

Commit

Permalink
Merge pull request #4 from zero-to-prod/feat/state-dot-syntax
Browse files Browse the repository at this point in the history
feat/state-dot-syntax
  • Loading branch information
zero-to-prod authored Oct 24, 2024
2 parents 980d361 + 0b8f97c commit 5cf65d0
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 6 deletions.
File renamed without changes.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -39,13 +39,16 @@ 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
{
use \Zerotoprod\DataModelFactory\DataModel;

public $first_name;
public $last_name;
public $address;

public static function factory(array $states = []): UserFactory
{
Expand All @@ -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]);
Expand Down
22 changes: 21 additions & 1 deletion src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -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
Expand Down
28 changes: 28 additions & 0 deletions tests/Unit/Method/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
4 changes: 4 additions & 0 deletions tests/Unit/Method/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
18 changes: 17 additions & 1 deletion tests/Unit/Method/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down

0 comments on commit 5cf65d0

Please sign in to comment.