-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update: resource supports formatting
- Loading branch information
Showing
5 changed files
with
226 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sourcetoad\EnhancedResources\Exceptions; | ||
|
||
use Exception; | ||
|
||
class NoDefinedFormatsException extends Exception | ||
{ | ||
protected const MESSAGE_FORMAT = '\'%s\' has no defined formats.'; | ||
|
||
public function __construct(object $object) | ||
{ | ||
$message = vsprintf(static::MESSAGE_FORMAT, [ | ||
$object::class, | ||
]); | ||
|
||
parent::__construct($message); | ||
} | ||
} |
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,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sourcetoad\EnhancedResources\Exceptions; | ||
|
||
use Exception; | ||
|
||
class NoFormatSelectedException extends Exception | ||
{ | ||
protected const MESSAGE_FORMAT = '\'%s\' does not have a default format, and no format was specified.'; | ||
|
||
public function __construct(object $object) | ||
{ | ||
$message = vsprintf(static::MESSAGE_FORMAT, [ | ||
$object::class, | ||
]); | ||
|
||
parent::__construct($message); | ||
} | ||
} |
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,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sourcetoad\EnhancedResources; | ||
|
||
use Illuminate\Http\Resources\Json\JsonResource; | ||
use Sourcetoad\EnhancedResources\Exceptions\NoDefinedFormatsException; | ||
use Sourcetoad\EnhancedResources\Exceptions\NoFormatSelectedException; | ||
use Sourcetoad\EnhancedResources\Formatting\FormatManager; | ||
|
||
abstract class Resource extends JsonResource | ||
{ | ||
protected FormatManager $formatManager; | ||
|
||
public function __construct($resource) | ||
{ | ||
parent::__construct($resource); | ||
|
||
$this->formatManager = new FormatManager($this); | ||
|
||
if ($this->formatManager->formats()->isEmpty()) { | ||
throw new NoDefinedFormatsException($this); | ||
} | ||
} | ||
|
||
public function format(string $name): static | ||
{ | ||
$this->formatManager->select($name); | ||
|
||
return $this; | ||
} | ||
|
||
public function toArray($request) | ||
{ | ||
$currentFormat = $this->formatManager->current() ?? throw new NoFormatSelectedException($this); | ||
|
||
return $currentFormat->invoke($this, $request); | ||
} | ||
} |
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,139 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sourcetoad\EnhancedResources\Tests\Unit; | ||
|
||
use Sourcetoad\EnhancedResources\Exceptions\NoDefinedFormatsException; | ||
use Sourcetoad\EnhancedResources\Exceptions\NoFormatSelectedException; | ||
use Sourcetoad\EnhancedResources\Formatting\Attributes\Format; | ||
use Sourcetoad\EnhancedResources\Formatting\Attributes\IsDefault; | ||
use Sourcetoad\EnhancedResources\Resource; | ||
use Sourcetoad\EnhancedResources\Tests\TestCase; | ||
|
||
class ResourceTest extends TestCase | ||
{ | ||
/** @dataProvider formatProvider */ | ||
public function test_resource_is_formatted_correctly(Resource $resource, array $expectedData): void | ||
{ | ||
# Act | ||
$actualData = $resource->toArray(request()); | ||
|
||
# Assert | ||
$this->assertSame($expectedData, $actualData); | ||
} | ||
|
||
public function test_exception_is_thrown_if_no_formats_are_defined(): void | ||
{ | ||
# Expect | ||
$this->expectException(NoDefinedFormatsException::class); | ||
|
||
# Act | ||
new class(null) extends Resource {}; | ||
} | ||
|
||
public function test_exception_is_thrown_if_no_format_is_selected(): void | ||
{ | ||
# Expect | ||
$this->expectException(NoFormatSelectedException::class); | ||
|
||
# Act | ||
(new class(null) extends Resource { | ||
#[Format] | ||
public function bar() {} | ||
|
||
#[Format] | ||
public function foo() {} | ||
})->toArray(request()); | ||
} | ||
|
||
# region Data Providers | ||
|
||
public function formatProvider(): array | ||
{ | ||
return [ | ||
'implicit default is used' => [ | ||
'resource' => (new class(null) extends Resource { | ||
#[Format] | ||
public function foo(): array | ||
{ | ||
return [ | ||
'first_name' => 'John', | ||
'id' => 1, | ||
'last_name' => 'Doe', | ||
]; | ||
} | ||
}), | ||
'expectedData' => [ | ||
'first_name' => 'John', | ||
'id' => 1, | ||
'last_name' => 'Doe', | ||
], | ||
], | ||
'explicit default is used' => [ | ||
'resource' => (new class(null) extends Resource { | ||
#[Format] | ||
public function bar(): array | ||
{ | ||
return [ | ||
'first_name' => 'John', | ||
'id' => 1, | ||
'last_name' => 'Doe', | ||
]; | ||
} | ||
|
||
#[IsDefault, Format] | ||
public function foo(): array | ||
{ | ||
return [ | ||
'id' => 1, | ||
'name' => [ | ||
'first' => 'John', | ||
'last' => 'Doe', | ||
], | ||
]; | ||
} | ||
}), | ||
'expectedData' => [ | ||
'id' => 1, | ||
'name' => [ | ||
'first' => 'John', | ||
'last' => 'Doe', | ||
], | ||
], | ||
], | ||
'explicitly selected format is used' => [ | ||
'resource' => (new class(null) extends Resource { | ||
#[Format] | ||
public function bar(): array | ||
{ | ||
return [ | ||
'first_name' => 'John', | ||
'id' => 1, | ||
'last_name' => 'Doe', | ||
]; | ||
} | ||
|
||
#[IsDefault, Format] | ||
public function foo(): array | ||
{ | ||
return [ | ||
'id' => 1, | ||
'name' => [ | ||
'first' => 'John', | ||
'last' => 'Doe', | ||
], | ||
]; | ||
} | ||
})->format('bar'), | ||
'expectedData' => [ | ||
'first_name' => 'John', | ||
'id' => 1, | ||
'last_name' => 'Doe', | ||
], | ||
], | ||
]; | ||
} | ||
|
||
# endregion | ||
} |