diff --git a/src/Validators/TypeHintValidator.php b/src/Validators/TypeHintValidator.php index 4849f2d..a566846 100644 --- a/src/Validators/TypeHintValidator.php +++ b/src/Validators/TypeHintValidator.php @@ -35,10 +35,12 @@ class TypeHintValidator implements PropertyValidator 'object' => 'object', 'enum' => 'enum', 'null' => 'null', - DateTime::class => DateTime::class, - DateTimeInterface::class => DateTime::class, + 'mixed' => 'mixed', 'interface' => 'interface', + 'callable' => 'callable', 'default' => 'default', + DateTime::class => DateTime::class, + DateTimeInterface::class => DateTime::class, ]; public function __construct(array $typeHintRules = [], array $typeAliases = []) @@ -138,6 +140,8 @@ private function getDefaultRules(): array 'object' => new TypeValidators\RawObject, 'enum' => new TypeValidators\RawEnum, 'null' => new TypeValidators\RawNull, + 'mixed' => new TypeValidators\RawMixed, + 'callable' => new TypeValidators\RawCallable, DateTime::class => new TypeValidators\DateTime, 'interface' => new TypeValidators\StrictType, ArrayObject::class => new TypeValidators\ArrayObject, diff --git a/src/Validators/Types/RawCallable.php b/src/Validators/Types/RawCallable.php new file mode 100644 index 0000000..47fc426 --- /dev/null +++ b/src/Validators/Types/RawCallable.php @@ -0,0 +1,32 @@ +getValue(); + v::callableType()->assert($value); + $property->setValue($value); + } +} diff --git a/src/Validators/Types/RawMixed.php b/src/Validators/Types/RawMixed.php new file mode 100644 index 0000000..a98d692 --- /dev/null +++ b/src/Validators/Types/RawMixed.php @@ -0,0 +1,26 @@ + true, + null, + [[1, 2, 3]], + (object) [[1, 2, 3]], + true, + false, + new DateTime, + new class + { + public string $name; + }, +]); diff --git a/tests/Integration/BasicTypesTest.php b/tests/Integration/BasicTypesTest.php index d6cae3b..d30c462 100644 --- a/tests/Integration/BasicTypesTest.php +++ b/tests/Integration/BasicTypesTest.php @@ -667,3 +667,24 @@ ->throws(ValidationException::class, 'Invalid data') ->with([true, false]) ->group('validator', 'basic', 'enum', 'int enum'); + +// Mixed validation + +test('Mixed type', function ($value) { + $validator = new Validator; + $model = $validator->validate(['value' => $value], new Models\RawMixed); + expect($model) + ->toBeInstanceOf(Models\RawMixed::class) + ->toHaveProperty('value', $value); +}) + ->with('mixed') + ->group('validator', 'basic', 'mixed'); + +test('Using default value - mixed', function () { + $validator = new Validator; + $model = $validator->validate([], new Models\DefaultMixed); + expect($model) + ->toBeInstanceOf(Models\DefaultMixed::class) + ->toHaveProperty('value', 'default'); +}) + ->group('validator', 'basic', 'mixed'); diff --git a/tests/Integration/ValidateCallableTest.php b/tests/Integration/ValidateCallableTest.php index 5bcd16b..07fa776 100644 --- a/tests/Integration/ValidateCallableTest.php +++ b/tests/Integration/ValidateCallableTest.php @@ -16,6 +16,7 @@ use Attributes\Validation\Exceptions\ValidationException; use Attributes\Validation\Tests\Models as Models; use Attributes\Validation\Validator; +use DateTime; // Alias and alias generator @@ -176,3 +177,23 @@ }) ->with([true, false]) ->group('validator', 'validate-callable', 'numbered-arguments'); + +// Callable + +test('Callable - validate callable', function (bool $isStrict, mixed $callable) { + $validator = new Validator(strict: $isStrict); + $rawData = ['value' => $callable]; + $call = function (callable $value) { + return 'success'; + }; + $args = $validator->validateCallable($rawData, $call); + expect($args) + ->toBeArray() + ->toHaveCount(1) + ->toBe([ + 'value' => $callable, + ]); +}) + ->with([true, false]) + ->with(['trim', [[new DateTime, 'format']], fn () => true]) + ->group('validator', 'validate-callable', 'callable'); diff --git a/tests/Models/Basic/Mixed.php b/tests/Models/Basic/Mixed.php new file mode 100644 index 0000000..7ea4b95 --- /dev/null +++ b/tests/Models/Basic/Mixed.php @@ -0,0 +1,13 @@ +