use Data namespace
This commit is contained in:
parent
71d49def6b
commit
a5b80681c9
21 changed files with 283 additions and 68 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "icefox/dto",
|
"name": "icefox/dto",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
"version": "0.0.1",
|
||||||
"require": {
|
"require": {
|
||||||
"laravel/framework": "^11.0",
|
"laravel/framework": "^11.0",
|
||||||
"psr/log": "^3.0",
|
"psr/log": "^3.0",
|
||||||
|
|
@ -18,15 +19,12 @@
|
||||||
"license": "GPL-2.0-only",
|
"license": "GPL-2.0-only",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Icefox\\DTO\\": "src/"
|
"Icefox\\Data\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Tests\\": "tests/",
|
"Tests\\": "tests/"
|
||||||
"Workbench\\App\\": "workbench/app/",
|
|
||||||
"Workbench\\Database\\Factories\\": "workbench/database/factories/",
|
|
||||||
"Workbench\\Database\\Seeders\\": "workbench/database/seeders/"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Attributes;
|
namespace Icefox\Data\Attributes;
|
||||||
|
|
||||||
use Attribute;
|
use Attribute;
|
||||||
|
|
||||||
#[Attribute(Attribute::TARGET_PARAMETER)]
|
#[Attribute(Attribute::TARGET_PARAMETER)]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Attributes;
|
namespace Icefox\Data\Attributes;
|
||||||
|
|
||||||
use Attribute;
|
use Attribute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Attributes;
|
namespace Icefox\Data\Attributes;
|
||||||
|
|
||||||
use Attribute;
|
use Attribute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Attributes;
|
namespace Icefox\Data\Attributes;
|
||||||
|
|
||||||
use Attribute;
|
use Attribute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Attributes;
|
namespace Icefox\Data\Attributes;
|
||||||
|
|
||||||
use Attribute;
|
use Attribute;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Icefox\DTO;
|
namespace Icefox\Data;
|
||||||
|
|
||||||
use Icefox\DTO\Factories\RuleFactory;
|
use Icefox\Data\Factories\RuleFactory;
|
||||||
use phpDocumentor\Reflection\PseudoTypes\Generic;
|
use phpDocumentor\Reflection\PseudoTypes\Generic;
|
||||||
|
|
||||||
class CustomHandlers
|
class CustomHandlers
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO;
|
namespace Icefox\Data;
|
||||||
|
|
||||||
use Icefox\DTO\Factories\DataObjectFactory;
|
use Icefox\Data\Factories\DataObjectFactory;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
trait DataObject
|
trait DataObject
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Icefox\DTO\Factories;
|
namespace Icefox\Data\Factories;
|
||||||
|
|
||||||
use Icefox\DTO\Attributes\FromInput;
|
use Icefox\Data\Attributes\FromInput;
|
||||||
use Icefox\DTO\Attributes\FromRouteParameter;
|
use Icefox\Data\Attributes\FromRouteParameter;
|
||||||
use Icefox\DTO\Factories\RuleFactory;
|
use Icefox\Data\Factories\RuleFactory;
|
||||||
use Icefox\DTO\Factories\ValueFactory;
|
use Icefox\Data\Factories\ValueFactory;
|
||||||
use Icefox\DTO\ReflectionHelper;
|
use Icefox\Data\ReflectionHelper;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Route;
|
use Illuminate\Routing\Route;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
@ -15,7 +15,6 @@ use Illuminate\Validation\ValidationException;
|
||||||
use Illuminate\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use ReflectionNamedType;
|
use ReflectionNamedType;
|
||||||
use phpDocumentor\Reflection\Types\AbstractList;
|
|
||||||
|
|
||||||
class DataObjectFactory
|
class DataObjectFactory
|
||||||
{
|
{
|
||||||
|
|
@ -37,7 +36,13 @@ class DataObjectFactory
|
||||||
public static function fromArray(string $class, array $rawInput, array $routeParameters): ?object
|
public static function fromArray(string $class, array $rawInput, array $routeParameters): ?object
|
||||||
{
|
{
|
||||||
$logger = Log::channel('dto');
|
$logger = Log::channel('dto');
|
||||||
$input = self::mapInput($class, $rawInput, $routeParameters, $logger);
|
|
||||||
|
$defaults = method_exists($class, 'defaults')
|
||||||
|
? App::call("$class::defaults")
|
||||||
|
: [];
|
||||||
|
|
||||||
|
$mergedInput = array_replace_recursive($defaults, $rawInput);
|
||||||
|
$input = self::mapInput($class, $mergedInput, $routeParameters, $logger);
|
||||||
|
|
||||||
$rules = (new RuleFactory($logger))->make($class);
|
$rules = (new RuleFactory($logger))->make($class);
|
||||||
|
|
||||||
|
|
@ -104,6 +109,7 @@ class DataObjectFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($valueType = ReflectionHelper::getListParameterValueType($parameter->tag)) {
|
if ($valueType = ReflectionHelper::getListParameterValueType($parameter->tag)) {
|
||||||
|
if (class_exists($valueType)) {
|
||||||
$input[$parameterName] = $isListType
|
$input[$parameterName] = $isListType
|
||||||
? array_map(
|
? array_map(
|
||||||
fn($element) => self::mapInput($valueType, $element, $routeParameters, $logger),
|
fn($element) => self::mapInput($valueType, $element, $routeParameters, $logger),
|
||||||
|
|
@ -112,6 +118,11 @@ class DataObjectFactory
|
||||||
: self::mapInput($valueType, $rawInput[$parameterName], $routeParameters, $logger);
|
: self::mapInput($valueType, $rawInput[$parameterName], $routeParameters, $logger);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (array_key_exists($parameterName, $rawInput)) {
|
||||||
|
$input[$parameterName] = $rawInput[$parameterName];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($reflectionType instanceof ReflectionNamedType) {
|
if ($reflectionType instanceof ReflectionNamedType) {
|
||||||
if ($reflectionType->isBuiltin()) {
|
if ($reflectionType->isBuiltin()) {
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Factories;
|
namespace Icefox\Data\Factories;
|
||||||
|
|
||||||
use Icefox\DTO\Attributes\Flat;
|
use Icefox\Data\Attributes\Flat;
|
||||||
use Icefox\DTO\Attributes\Overwrite;
|
use Icefox\Data\Attributes\Overwrite;
|
||||||
use Icefox\DTO\ParameterMeta;
|
use Icefox\Data\ParameterMeta;
|
||||||
use Icefox\DTO\ReflectionHelper;
|
use Icefox\Data\ReflectionHelper;
|
||||||
use Icefox\DTO\Factories\RuleFactory;
|
use Icefox\Data\Factories\RuleFactory;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Icefox\DTO\Factories;
|
namespace Icefox\Data\Factories;
|
||||||
|
|
||||||
use Icefox\DTO\Attributes\CastWith;
|
use Icefox\Data\Attributes\CastWith;
|
||||||
use Icefox\DTO\Attributes\Flat;
|
use Icefox\Data\Attributes\Flat;
|
||||||
use Icefox\DTO\ReflectionHelper;
|
use Icefox\Data\ReflectionHelper;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use ReflectionNamedType;
|
use ReflectionNamedType;
|
||||||
use phpDocumentor\Reflection\PseudoTypes\Generic;
|
use phpDocumentor\Reflection\PseudoTypes\Generic;
|
||||||
|
|
|
||||||
5
src/IData.php
Normal file
5
src/IData.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icefox\Data;
|
||||||
|
|
||||||
|
interface IData {}
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Icefox\DTO;
|
|
||||||
|
|
||||||
interface IDataObject {}
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Icefox\DTO;
|
namespace Icefox\Data;
|
||||||
|
|
||||||
use ReflectionParameter;
|
use ReflectionParameter;
|
||||||
use phpDocumentor\Reflection\DocBlock\Tags\Param;
|
use phpDocumentor\Reflection\DocBlock\Tags\Param;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,26 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Icefox\DTO\Providers;
|
namespace Icefox\Data\Providers;
|
||||||
|
|
||||||
use Icefox\DTO\Factories\DataObjectFactory;
|
use Icefox\Data\Factories\DataObjectFactory;
|
||||||
use Icefox\DTO\IDataObject;
|
use Icefox\Data\IData;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class DataObjectServiceProvider extends ServiceProvider
|
class DataObjectServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '../../workbench/config/dto.php' => config_path('dto.php'),
|
||||||
|
]);
|
||||||
|
|
||||||
$this->app->beforeResolving(function ($abstract, $parameters, $app) {
|
$this->app->beforeResolving(function ($abstract, $parameters, $app) {
|
||||||
if ($app->has($abstract)) {
|
if ($app->has($abstract)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_subclass_of($abstract, IDataObject::class)) {
|
if (is_subclass_of($abstract, IData::class)) {
|
||||||
$app->bind($abstract, fn($container) => DataObjectFactory::fromRequest($abstract, $container['request']));
|
$app->bind($abstract, fn($container) => DataObjectFactory::fromRequest($abstract, $container['request']));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Icefox\DTO;
|
namespace Icefox\Data;
|
||||||
|
|
||||||
use ReflectionNamedType;
|
use ReflectionNamedType;
|
||||||
use ReflectionParameter;
|
use ReflectionParameter;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
namespace Tests\DataObject;
|
namespace Tests\DataObject;
|
||||||
|
|
||||||
use Icefox\DTO\Attributes\FromInput;
|
use Icefox\Data\Attributes\FromInput;
|
||||||
use Icefox\DTO\Attributes\FromRouteParameter;
|
use Icefox\Data\Attributes\FromRouteParameter;
|
||||||
use Icefox\DTO\Factories\DataObjectFactory;
|
use Icefox\Data\Factories\DataObjectFactory;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
|
|
||||||
|
|
@ -193,3 +193,208 @@ test('route parameter with nested object', function () {
|
||||||
expect($result['userId'])->toBe(123)
|
expect($result['userId'])->toBe(123)
|
||||||
->and($result['address']['street'])->toBe('Main St');
|
->and($result['address']['street'])->toBe('Main St');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
readonly class SimpleWithDefaults
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public int $age,
|
||||||
|
public string $city = 'Unknown',
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,mixed>
|
||||||
|
*/
|
||||||
|
public static function defaults(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'city' => 'New York',
|
||||||
|
'age' => 25,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('defaults with fromArray - basic usage', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
SimpleWithDefaults::class,
|
||||||
|
['name' => 'John'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->name)->toBe('John')
|
||||||
|
->and($object->age)->toBe(25)
|
||||||
|
->and($object->city)->toBe('New York');
|
||||||
|
});
|
||||||
|
|
||||||
|
readonly class NestedWithDefaults
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $title,
|
||||||
|
public SimpleWithDefaults $user,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,array<string,mixed>>
|
||||||
|
*/
|
||||||
|
public static function defaults(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'user' => [
|
||||||
|
'name' => 'Default User',
|
||||||
|
'age' => 30,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('defaults with nested objects', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
NestedWithDefaults::class,
|
||||||
|
['title' => 'Admin Dashboard'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->title)->toBe('Admin Dashboard')
|
||||||
|
->and($object->user->name)->toBe('Default User')
|
||||||
|
->and($object->user->age)->toBe(30)
|
||||||
|
->and($object->user->city)->toBe('Unknown');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('defaults merged with input - input overrides defaults', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
SimpleWithDefaults::class,
|
||||||
|
['name' => 'Alice', 'age' => 40, 'city' => 'Los Angeles'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->name)->toBe('Alice')
|
||||||
|
->and($object->age)->toBe(40)
|
||||||
|
->and($object->city)->toBe('Los Angeles');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('defaults with simple nested structures', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
NestedWithDefaults::class,
|
||||||
|
['title' => 'Simple Project'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->title)->toBe('Simple Project')
|
||||||
|
->and($object->user->name)->toBe('Default User')
|
||||||
|
->and($object->user->age)->toBe(30);
|
||||||
|
});
|
||||||
|
|
||||||
|
readonly class ArrayWithDefaults
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string,mixed> $settings
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public string $projectName,
|
||||||
|
public array $settings,
|
||||||
|
) {}
|
||||||
|
/**
|
||||||
|
* @return array<string,array<string,mixed>>
|
||||||
|
*/
|
||||||
|
public static function defaults(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'settings' => [
|
||||||
|
'theme' => 'dark',
|
||||||
|
'notifications' => true,
|
||||||
|
'language' => 'en',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('defaults with array structures', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
ArrayWithDefaults::class,
|
||||||
|
['projectName' => 'New Project'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->projectName)->toBe('New Project')
|
||||||
|
->and($object->settings)->toBe([
|
||||||
|
'theme' => 'dark',
|
||||||
|
'notifications' => true,
|
||||||
|
'language' => 'en',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('defaults partially overridden by input', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
ArrayWithDefaults::class,
|
||||||
|
[
|
||||||
|
'projectName' => 'Custom Project',
|
||||||
|
'settings' => [
|
||||||
|
'theme' => 'light',
|
||||||
|
'language' => 'fr',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->projectName)->toBe('Custom Project')
|
||||||
|
->and($object->settings)->toBe([
|
||||||
|
'theme' => 'light',
|
||||||
|
'notifications' => true, // From defaults
|
||||||
|
'language' => 'fr',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
readonly class WithInputMappingAndDefaults
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
#[FromInput('full_name')]
|
||||||
|
public string $name,
|
||||||
|
#[FromInput('user_age')]
|
||||||
|
public int $age,
|
||||||
|
public string $role = 'user',
|
||||||
|
) {}
|
||||||
|
/**
|
||||||
|
* @return array<string,mixed>
|
||||||
|
*/
|
||||||
|
public static function defaults(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'Default Name',
|
||||||
|
'role' => 'admin',
|
||||||
|
'age' => 18,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('defaults work with FromInput attribute mapping', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
WithInputMappingAndDefaults::class,
|
||||||
|
['full_name' => 'John Doe'],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->name)->toBe('John Doe') // From input mapping
|
||||||
|
->and($object->age)->toBe(18) // From defaults
|
||||||
|
->and($object->role)->toBe('admin'); // From defaults
|
||||||
|
});
|
||||||
|
|
||||||
|
test('array_merge_recursive behavior with nested arrays', function () {
|
||||||
|
$object = DataObjectFactory::fromArray(
|
||||||
|
ArrayWithDefaults::class,
|
||||||
|
[
|
||||||
|
'projectName' => 'Test Project',
|
||||||
|
'settings' => [
|
||||||
|
'new_setting' => 'custom_value',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect($object->settings)->toBe([
|
||||||
|
'theme' => 'dark', // From defaults
|
||||||
|
'notifications' => true, // From defaults
|
||||||
|
'language' => 'en', // From defaults
|
||||||
|
'new_setting' => 'custom_value', // From input
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
namespace Tests\Http;
|
namespace Tests\Http;
|
||||||
|
|
||||||
use Icefox\DTO\IDataObject;
|
use Icefox\Data\IData;
|
||||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Facades\Validator as ValidatorFacade;
|
use Illuminate\Support\Facades\Validator as ValidatorFacade;
|
||||||
use Illuminate\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
|
|
||||||
readonly class Basic implements IDataObject
|
readonly class Basic implements IData
|
||||||
{
|
{
|
||||||
public string $reply;
|
public string $reply;
|
||||||
public function __construct(string $message)
|
public function __construct(string $message)
|
||||||
|
|
@ -35,7 +35,7 @@ test('fails on validation error', function () {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
readonly class WithCustomValidator implements IDataObject
|
readonly class WithCustomValidator implements IData
|
||||||
{
|
{
|
||||||
public string $reply;
|
public string $reply;
|
||||||
public function __construct(string $message)
|
public function __construct(string $message)
|
||||||
|
|
@ -66,7 +66,7 @@ test('replies with custom validator', function () {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
readonly class WithCustomFailure implements IDataObject
|
readonly class WithCustomFailure implements IData
|
||||||
{
|
{
|
||||||
public function __construct(public bool $flag) {}
|
public function __construct(public bool $flag) {}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ test('uses custom response', function () {
|
||||||
->assertJson(['result' => 'invalid, but that is ok']);
|
->assertJson(['result' => 'invalid, but that is ok']);
|
||||||
});
|
});
|
||||||
|
|
||||||
readonly class WithDefaultObjectOnFailure implements IDataObject
|
readonly class WithDefaultObjectOnFailure implements IData
|
||||||
{
|
{
|
||||||
public function __construct(public bool $flag) {}
|
public function __construct(public bool $flag) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Tests\Rules;
|
namespace Tests\Rules;
|
||||||
|
|
||||||
use Icefox\DTO\Attributes\Flat;
|
use Icefox\Data\Attributes\Flat;
|
||||||
use Icefox\DTO\Attributes\Overwrite;
|
use Icefox\Data\Attributes\Overwrite;
|
||||||
use Icefox\DTO\Factories\RuleFactory;
|
use Icefox\Data\Factories\RuleFactory;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
readonly class BasicPrimitives
|
readonly class BasicPrimitives
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ declare(strict_types=1);
|
||||||
namespace Tests\Values;
|
namespace Tests\Values;
|
||||||
|
|
||||||
use Carbon\CarbonPeriod;
|
use Carbon\CarbonPeriod;
|
||||||
use Icefox\DTO\Attributes\CastWith;
|
use Icefox\Data\Attributes\CastWith;
|
||||||
use Icefox\DTO\Factories\ValueFactory;
|
use Icefox\Data\Factories\ValueFactory;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Icefox\DTO\CustomHandlers;
|
use Icefox\Data\CustomHandlers;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Psr\Log\LogLevel;
|
use Psr\Log\LogLevel;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'rules' => [
|
'rules' => [
|
||||||
Collection::class => CustomHandlers::CollectionRules(...),
|
Collection::class => CustomHandlers::class . "::CollectionRules",
|
||||||
],
|
],
|
||||||
'logging' => [
|
'logging' => [
|
||||||
'channel' => 'dto',
|
'channel' => 'dto',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue