Skip to content

Commit acc5537

Browse files
committed
Update user test state casting
1 parent 58bec96 commit acc5537

File tree

8 files changed

+182
-51
lines changed

8 files changed

+182
-51
lines changed

tests/Casts/StateCaster.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Kodeine\Metable\Tests\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
7+
class StateCaster implements CastsAttributes
8+
{
9+
private string $baseStateClass;
10+
11+
public function __construct(string $baseStateClass)
12+
{
13+
$this->baseStateClass = $baseStateClass;
14+
}
15+
16+
public function get($model, $key, $value, $attributes) {
17+
if ( is_null( $value ) ) return null;
18+
19+
if (! is_subclass_of($value, $this->baseStateClass)) {
20+
return null;
21+
}
22+
23+
$stateClassName = $value::config()['default'];
24+
25+
$state = new $stateClassName($model);
26+
27+
return $state;
28+
}
29+
30+
public function set($model, $key, $value, $attributes) {
31+
if ( is_null( $value ) ) return null;
32+
33+
if (! is_subclass_of($value, $this->baseStateClass)) {
34+
throw new \Exception('Invalid state class.');
35+
}
36+
37+
$value = new $value($model);
38+
39+
if ($value instanceof $this->baseStateClass) {
40+
$value->setField($key);
41+
}
42+
43+
return $value->getMorphClass();
44+
}
45+
}

tests/Casts/UserCastedObject.php

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,43 @@
33
namespace Kodeine\Metable\Tests\Casts;
44

55
use Illuminate\Contracts\Database\Eloquent\Castable;
6-
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
76

8-
class UserCastedObject implements Castable, CastsAttributes
7+
abstract class UserCastedObject implements Castable
98
{
10-
public $description;
11-
12-
public function get($model, $key, $value, $attributes) {
13-
if ( is_null( $value ) ) return null;
14-
return json_decode( $value, true );
9+
public function __construct($model) {
10+
$this->model = $model;
11+
$this->stateConfig = static::config();
1512
}
16-
17-
public function set($model, $key, $value, $attributes) {
18-
return [$key => json_encode( $value )];
13+
14+
public static function config()
15+
{
16+
return [
17+
'default' => null,
18+
];
1919
}
2020

2121
public static function castUsing(array $arguments) {
22-
return new self();
22+
return new StateCaster(static::class);
23+
}
24+
25+
public function setField(string $field): self
26+
{
27+
$this->field = $field;
28+
29+
return $this;
30+
}
31+
32+
public static function getMorphClass(): string
33+
{
34+
return static::$name ?? static::class;
35+
}
36+
37+
public function make(string $name, $model)
38+
{
39+
if (is_null($name)) {
40+
return null;
41+
}
42+
43+
return new $name($model);
2344
}
2445
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Kodeine\Metable\Tests\Casts\UserState;
4+
5+
class DefaultState extends State
6+
{
7+
public string $description;
8+
9+
public function __construct() {
10+
$this->description = $this->description();
11+
}
12+
13+
public function description(): string {
14+
return 'This is a default description.';
15+
}
16+
}

tests/Casts/UserState/State.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Kodeine\Metable\Tests\Casts\UserState;
4+
5+
use Kodeine\Metable\Tests\Casts\UserCastedObject;
6+
7+
abstract class State extends UserCastedObject
8+
{
9+
abstract public function description(): string;
10+
11+
public static function config()
12+
{
13+
return [
14+
'default' => DefaultState::class,
15+
];
16+
}
17+
}

tests/MetableTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Kodeine\Metable\Tests\Models\UserTest;
1111
use Illuminate\Database\Capsule\Manager as Capsule;
1212
use Illuminate\Database\Eloquent\ModelNotFoundException;
13+
use Kodeine\Metable\Tests\Casts\UserState\DefaultState;
1314

1415
class MetableTest extends TestCase
1516
{
@@ -49,6 +50,16 @@ public static function setUpBeforeClass(): void {
4950
} );
5051
}
5152

53+
public function testCast() {
54+
$user = new UserTest;
55+
56+
$this->assertNull( $user->state, 'Casted object should be null by default' );
57+
58+
$user->state = DefaultState::class;
59+
60+
$this->assertTrue( $user->state instanceof DefaultState, 'Casted object should be instanceof DefaultState' );
61+
}
62+
5263
public function testFluentMeta() {
5364
$user = new UserTest;
5465

tests/Models/UserTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
use Illuminate\Events\Dispatcher;
77
use Illuminate\Database\Eloquent\Model;
88
use Illuminate\Database\Eloquent\Relations\HasOne;
9-
use Kodeine\Metable\Tests\Casts\UserCastedObject;
10-
use Kodeine\Metable\Tests\Traits\HasUserCasts;
9+
use Kodeine\Metable\Tests\Casts\UserState\State;
10+
use Kodeine\Metable\Tests\Traits\HasUserStates;
1111

1212
class UserTest extends Model
1313
{
1414
use Metable;
15-
use HasUserCasts;
15+
use HasUserStates;
1616

1717
public $defaultMetaValues = [
1818
'default_meta_key' => 'default_meta_value',
@@ -21,9 +21,9 @@ class UserTest extends Model
2121
public $hideMeta = false;
2222

2323
public $disableFluentMeta = false;
24-
24+
2525
protected $casts = [
26-
'state' => UserCastedObject::class,
26+
'state' => State::class,
2727
];
2828

2929
public function getNullCastAttribute() {

tests/Traits/HasUserCasts.php

Lines changed: 0 additions & 35 deletions
This file was deleted.

tests/Traits/HasUserStates.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Kodeine\Metable\Tests\Traits;
4+
5+
use Kodeine\Metable\Tests\Casts\UserState\State;
6+
7+
trait HasUserStates
8+
{
9+
public $casted = [
10+
'state' => State::class,
11+
];
12+
13+
public static function bootHasUserCasts()
14+
{
15+
self::creating( function ( $model ) {
16+
$model->setDefaultCastedProperties();
17+
} );
18+
}
19+
20+
public function initializeHasUserCasts()
21+
{
22+
$this->setDefaultCastedProperties();
23+
}
24+
25+
private function getStateConfigs()
26+
{
27+
$casts = $this->getCasts();
28+
29+
$states = [];
30+
31+
foreach ($casts as $prop => $state) {
32+
if (! is_subclass_of($state, UserCastedObject::class)) {
33+
continue;
34+
}
35+
36+
$states[$prop] = $state::config();
37+
}
38+
39+
return $states;
40+
}
41+
42+
private function setDefaultCastedProperties()
43+
{
44+
foreach ( $this->getStateConfigs() as $prop => $config ) {
45+
if ($this->{$prop} === null) {
46+
continue;
47+
}
48+
49+
if ( ! isset( $config['default'] ) ) {
50+
continue;
51+
}
52+
53+
$this->{$prop} = $config['default'];
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)