Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add enum support #13

Merged
merged 1 commit into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions src/AttributeEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Kleemans\Tests\Fake\OrderStatus;

trait AttributeEvents
{
Expand All @@ -28,35 +29,31 @@ private function fireAttributeEvents(): void
{
foreach ($this->getAttributeEvents() as $change => $event) {
[$attribute, $expected] = explode(':', $change);

$value = $this->getAttribute($attribute);

// Accessor
if ($this->hasAccessor($attribute)) {
if (!$this->isDirtyAccessor($attribute)) {
if (! $this->isDirtyAccessor($attribute)) {
continue; // Not changed
}
}

// JSON attribute
} // JSON attribute
elseif (Str::contains($attribute, '->')) {
[$attribute, $path] = explode('->', $attribute, 2);
$path = str_replace('->', '.', $path);

if (!$this->isDirtyNested($attribute, $path)) {
if (! $this->isDirtyNested($attribute, $path)) {
continue; // Not changed
}

$value = Arr::get($this->getAttribute($attribute), $path);
}

// Regular attribute
elseif (!$this->isDirty($attribute)) {
} // Regular attribute
elseif (! $this->isDirty($attribute)) {
continue; // Not changed
}

if (
$expected === '*'
|| $value instanceof \UnitEnum && ($value->name === $expected)
|| $expected === 'true' && $value === true
|| $expected === 'false' && $value === false
|| is_numeric($expected) && Str::contains($expected, '.') && $value === (float) $expected // float
Expand All @@ -73,7 +70,7 @@ private function syncOriginalAccessors(): void
foreach ($this->getAttributeEvents() as $change => $event) {
[$attribute] = explode(':', $change);

if (!$this->hasAccessor($attribute)) {
if (! $this->hasAccessor($attribute)) {
continue; // Attribute does not have accessor
}

Expand All @@ -88,7 +85,7 @@ private function syncOriginalAccessors(): void

public function isDirtyAccessor(string $attribute): bool
{
if (!isset($this->originalAccessors[$attribute])) {
if (! isset($this->originalAccessors[$attribute])) {
return false; // Attribute does not have a original value saved
}

Expand Down Expand Up @@ -116,7 +113,7 @@ public function isDirtyNested(string $attribute, string $path): bool
private function getAttributeEvents(): iterable
{
foreach ($this->dispatchesEvents as $change => $event) {
if (!Str::contains($change, ':')) {
if (! Str::contains($change, ':')) {
continue; // Not an attribute event
}

Expand Down
15 changes: 15 additions & 0 deletions tests/AttributeEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Testing\Fakes\EventFake;
use Kleemans\Tests\Fake\OrderStatus;
use PHPUnit\Framework\TestCase;

class AttributeEventsTest extends TestCase
Expand All @@ -18,6 +19,7 @@ class AttributeEventsTest extends TestCase
Fake\Events\OrderDeleted::class,
Fake\Events\OrderNoteUpdated::class,
Fake\Events\OrderShipped::class,
Fake\Events\EnumOrderShipped::class,
Fake\Events\OrderCanceled::class,
Fake\Events\OrderReturned::class,
Fake\Events\OrderMadeFree::class,
Expand Down Expand Up @@ -391,6 +393,19 @@ public function it_works_with_nested_json_fields()
$this->dispatcher->assertDispatched(Fake\Events\InvoiceDownloaded::class);
}

/** @test */
public function it_works_with_enumerated_casts()
{
$order = new Fake\EnumOrder();
$order->status = OrderStatus::PROCESSING;
$order->save();

$order->status = OrderStatus::SHIPPED;
$order->save();

$this->dispatcher->assertDispatched(Fake\Events\EnumOrderShipped::class);
}

// Setup methods

private function initEventDispatcher()
Expand Down
37 changes: 37 additions & 0 deletions tests/Fake/EnumOrder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Kleemans\Tests\Fake;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Kleemans\AttributeEvents;

class EnumOrder extends Model
{
use AttributeEvents;

protected $table = 'orders';

protected $attributes = [
'status' => OrderStatus::PROCESSING,
'shipping_address' => '',
'billing_address' => '',
'note' => '',
'total' => 0.00,
'paid_amount' => 0.00,
'discount_percentage' => 0,
'tax_free' => false,
'payment_gateway' => 'credit_card',
'meta' => '{}',
];

protected $guarded = [];

protected $casts = [
'status' => OrderStatus::class,
];

protected $dispatchesEvents = [
'status:SHIPPED' => Events\EnumOrderShipped::class,
];
}
13 changes: 13 additions & 0 deletions tests/Fake/Events/EnumOrderShipped.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Kleemans\Tests\Fake\Events;

use Kleemans\Tests\Fake\EnumOrder;
use Kleemans\Tests\Fake\Order;

class EnumOrderShipped
{
public function __construct(EnumOrder $order)
{
}
}
10 changes: 10 additions & 0 deletions tests/Fake/OrderStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Kleemans\Tests\Fake;

enum OrderStatus: int
{
case PROCESSING = 1;
case SHIPPED = 2;
case CANCELLED = 3;
}