data-transfer-object/tests/Casters/CasterTest.php
2026-02-18 20:29:13 -03:00

71 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests;
use Illuminate\Validation\ValidationException;
use Tests\Casters\SimpleValue;
use Tests\Casters\SimpleValueCaster;
use Tests\Casters\WithGlobalCaster;
use Tests\Casters\WithSpecificCaster;
use Tests\Casters\WithoutCaster;
describe('caster priority', function () {
beforeEach(function () {
config(['dto.cast' => []]);
});
it('uses CastWith attribute over global config caster', function () {
$globalCaster = function (mixed $value): SimpleValue {
return new SimpleValue($value['value'] * 3);
};
config(['dto.cast.' . SimpleValue::class => $globalCaster]);
$object = WithSpecificCaster::fromArray([
'value' => ['value' => 5],
]);
expect($object->value->value)->toBe(10); // 5 * 2
});
it('falls back to global config caster when no CastWith attribute', function () {
$globalCaster = function (mixed $value): SimpleValue {
return new SimpleValue($value['value'] * 3);
};
config(['dto.cast.' . SimpleValue::class => $globalCaster]);
$object = WithGlobalCaster::fromArray([
'value' => ['value' => 5],
]);
expect($object->value->value)->toBe(15); // 5 * 3
});
it('falls back to default construction when no caster exists', function () {
$object = WithoutCaster::fromArray([
'value' => ['value' => 5],
]);
expect($object)->toBeInstanceOf(WithoutCaster::class);
});
});
describe('caster with rules', function () {
beforeEach(function () {
config(['dto.cast' => []]);
});
it('validates input using caster rules before casting', function () {
expect(fn() => WithSpecificCaster::fromArray([
'value' => [],
]))->toThrow(ValidationException::class);
});
it('accepts valid input and casts correctly', function () {
$object = WithSpecificCaster::fromArray([
'value' => ['value' => 10],
]);
expect($object->value->value)->toBe(20); // 10 * 2
});
});