-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[7.x] Add
Orchestra\Testbench\Support\FluentDecorator
(#280)
* [7.x] Add `Orchestra\Testbench\Support\FluentDecorator` Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> * wip Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com> --------- Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
- Loading branch information
Showing
3 changed files
with
256 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
<?php | ||
|
||
namespace Orchestra\Testbench\Support; | ||
|
||
use ArrayAccess; | ||
use Illuminate\Contracts\Support\Arrayable; | ||
use Illuminate\Contracts\Support\Jsonable; | ||
use Illuminate\Support\Fluent; | ||
use Illuminate\Support\Traits\ForwardsCalls; | ||
use JsonSerializable; | ||
|
||
/** | ||
* @template TKey of array-key | ||
* @template TValue | ||
* | ||
* @implements \Illuminate\Contracts\Support\Arrayable<TKey, TValue> | ||
* @implements \ArrayAccess<TKey, TValue> | ||
*/ | ||
abstract class FluentDecorator implements Arrayable, ArrayAccess, Jsonable, JsonSerializable | ||
{ | ||
use ForwardsCalls; | ||
|
||
/** | ||
* The Fluent instance. | ||
* | ||
* @var \Illuminate\Support\Fluent<TKey, TValue> | ||
*/ | ||
protected Fluent $fluent; | ||
|
||
/** | ||
* Create a new fluent instance. | ||
* | ||
* @param iterable<TKey, TValue> $attributes | ||
*/ | ||
public function __construct($attributes = []) | ||
{ | ||
$this->fluent = new Fluent($attributes); | ||
} | ||
|
||
/** | ||
* Convert the fluent instance to an array. | ||
* | ||
* @return array<TKey, TValue> | ||
*/ | ||
public function toArray() | ||
{ | ||
return $this->fluent->getAttributes(); | ||
} | ||
|
||
/** | ||
* Convert the object into something JSON serializable. | ||
* | ||
* @return array<TKey, TValue> | ||
*/ | ||
public function jsonSerialize(): array | ||
{ | ||
return $this->toArray(); | ||
} | ||
|
||
/** | ||
* Convert the fluent instance to JSON. | ||
* | ||
* @param int $options | ||
* @return string | ||
*/ | ||
public function toJson($options = 0) | ||
{ | ||
return (string) json_encode($this->jsonSerialize(), $options); | ||
} | ||
|
||
/** | ||
* Determine if the given offset exists. | ||
* | ||
* @param TKey $offset | ||
*/ | ||
public function offsetExists($offset): bool | ||
{ | ||
return $this->fluent->offsetExists($offset); | ||
} | ||
|
||
/** | ||
* Get the value for a given offset. | ||
* | ||
* @param TKey $offset | ||
* @return TValue|null | ||
*/ | ||
public function offsetGet($offset): mixed | ||
{ | ||
return $this->fluent->offsetGet($offset); | ||
} | ||
|
||
/** | ||
* Set the value at the given offset. | ||
* | ||
* @param TKey $offset | ||
* @param TValue $value | ||
*/ | ||
public function offsetSet($offset, $value): void | ||
{ | ||
$this->fluent->offsetSet($offset, $value); | ||
} | ||
|
||
/** | ||
* Unset the value at the given offset. | ||
* | ||
* @param TKey $offset | ||
*/ | ||
public function offsetUnset($offset): void | ||
{ | ||
$this->fluent->offsetUnset($offset); | ||
} | ||
|
||
/** | ||
* Handle dynamic calls to the fluent instance to set attributes. | ||
* | ||
* @param TKey $method | ||
* @param array{0: ?TValue} $parameters | ||
* @return $this | ||
*/ | ||
public function __call($method, $parameters) | ||
{ | ||
return $this->forwardDecoratedCallTo($this->fluent, $method, $parameters); | ||
} | ||
|
||
/** | ||
* Dynamically retrieve the value of an attribute. | ||
* | ||
* @param TKey $key | ||
* @return TValue|null | ||
*/ | ||
public function __get($key) | ||
{ | ||
return $this->fluent->get($key); | ||
} | ||
|
||
/** | ||
* Dynamically set the value of an attribute. | ||
* | ||
* @param TKey $key | ||
* @param TValue $value | ||
* @return void | ||
*/ | ||
public function __set($key, $value) | ||
{ | ||
$this->fluent->offsetSet($key, $value); | ||
} | ||
|
||
/** | ||
* Dynamically check if an attribute is set. | ||
* | ||
* @param TKey $key | ||
* @return bool | ||
*/ | ||
public function __isset($key) | ||
{ | ||
return $this->fluent->offsetExists($key); | ||
} | ||
|
||
/** | ||
* Dynamically unset an attribute. | ||
* | ||
* @param TKey $key | ||
* @return void | ||
*/ | ||
public function __unset($key) | ||
{ | ||
$this->fluent->offsetUnset($key); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace Orchestra\Testbench\Tests\Support; | ||
|
||
use Illuminate\Foundation\Application; | ||
use Orchestra\Testbench\Support\FluentDecorator; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class FluentDecoratorTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_can_be_utilise_fluent_features() | ||
{ | ||
$fluent = new class($attributes = ['testbench' => true, 'class' => __CLASS__]) extends FluentDecorator | ||
{ | ||
// ... | ||
}; | ||
|
||
$this->assertTrue(isset($fluent['testbench'])); | ||
$this->assertTrue(isset($fluent['class'])); | ||
$this->assertFalse(isset($fluent['workbench'])); | ||
|
||
$this->assertTrue($fluent['testbench']); | ||
$this->assertNull($fluent['workbench']); | ||
|
||
$this->assertSame($attributes, $fluent->getAttributes()); | ||
$this->assertSame($attributes, $fluent->toArray()); | ||
$this->assertSame(json_encode($attributes), $fluent->toJson()); | ||
$this->assertSame($attributes, $fluent->jsonSerialize()); | ||
|
||
$this->assertFalse(isset($fluent['laravel'])); | ||
$this->assertNull($fluent['laravel']); | ||
|
||
$this->assertInstanceOf(FluentDecorator::class, $fluent->laravel(Application::VERSION)); | ||
|
||
$this->assertTrue(isset($fluent['laravel'])); | ||
$this->assertSame(Application::VERSION, $fluent['laravel']); | ||
|
||
unset($fluent['class']); | ||
|
||
$this->assertFalse(isset($fluent['class'])); | ||
$this->assertFalse(isset($fluent->class)); | ||
$this->assertNull($fluent['class']); | ||
$this->assertNull($fluent->class); | ||
|
||
$this->assertFalse(isset($fluent->file)); | ||
|
||
$fluent->file = __FILE__; | ||
|
||
$this->assertTrue(isset($fluent->file)); | ||
|
||
unset($fluent->file); | ||
|
||
$this->assertFalse(isset($fluent->file)); | ||
} | ||
} |