Skip to content

Commit 25bcdcb

Browse files
committed
chore: Add support for callable and mixed types
1 parent 2bd198f commit 25bcdcb

File tree

7 files changed

+137
-2
lines changed

7 files changed

+137
-2
lines changed

src/Validators/TypeHintValidator.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ class TypeHintValidator implements PropertyValidator
3535
'object' => 'object',
3636
'enum' => 'enum',
3737
'null' => 'null',
38-
DateTime::class => DateTime::class,
39-
DateTimeInterface::class => DateTime::class,
38+
'mixed' => 'mixed',
4039
'interface' => 'interface',
40+
'callable' => 'callable',
4141
'default' => 'default',
42+
DateTime::class => DateTime::class,
43+
DateTimeInterface::class => DateTime::class,
4244
];
4345

4446
public function __construct(array $typeHintRules = [], array $typeAliases = [])
@@ -138,6 +140,8 @@ private function getDefaultRules(): array
138140
'object' => new TypeValidators\RawObject,
139141
'enum' => new TypeValidators\RawEnum,
140142
'null' => new TypeValidators\RawNull,
143+
'mixed' => new TypeValidators\RawMixed,
144+
'callable' => new TypeValidators\RawCallable,
141145
DateTime::class => new TypeValidators\DateTime,
142146
'interface' => new TypeValidators\StrictType,
143147
ArrayObject::class => new TypeValidators\ArrayObject,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/**
4+
* Holds logic to check if a given value is a valid callable
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Attributes\Validation\Validators\Types;
10+
11+
use Attributes\Validation\Context;
12+
use Attributes\Validation\Property;
13+
use Respect\Validation\Exceptions\ValidationException as RespectValidationException;
14+
use Respect\Validation\Validator as v;
15+
16+
final class RawCallable implements BaseType
17+
{
18+
/**
19+
* Validates that a given property value is valid integer
20+
*
21+
* @param Property $property - Property to be validated
22+
* @param Context $context - Validation context
23+
*
24+
* @throws RespectValidationException - If not valid
25+
*/
26+
public function validate(Property $property, Context $context): void
27+
{
28+
$value = $property->getValue();
29+
v::callableType()->assert($value);
30+
$property->setValue($value);
31+
}
32+
}

src/Validators/Types/RawMixed.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/**
4+
* Holds logic to check if a given value is a mixed value
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Attributes\Validation\Validators\Types;
10+
11+
use Attributes\Validation\Context;
12+
use Attributes\Validation\Property;
13+
14+
final class RawMixed implements BaseType
15+
{
16+
/**
17+
* Validates that a given property value is valid mixed value
18+
*
19+
* @param Property $property - Property to be validated
20+
* @param Context $context - Validation context
21+
*/
22+
public function validate(Property $property, Context $context): void
23+
{
24+
// This is empty on purpose
25+
}
26+
}

tests/Datasets/ValidBasic.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,21 @@
106106
Models\RawIntEnum::GUEST,
107107
Models\RawIntEnum::ADMIN,
108108
]);
109+
110+
dataset('mixed', [
111+
'value',
112+
10,
113+
5.5,
114+
Models\RawIntEnum::GUEST,
115+
fn () => true,
116+
null,
117+
[[1, 2, 3]],
118+
(object) [[1, 2, 3]],
119+
true,
120+
false,
121+
new DateTime,
122+
new class
123+
{
124+
public string $name;
125+
},
126+
]);

tests/Integration/BasicTypesTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,3 +667,24 @@
667667
->throws(ValidationException::class, 'Invalid data')
668668
->with([true, false])
669669
->group('validator', 'basic', 'enum', 'int enum');
670+
671+
// Mixed validation
672+
673+
test('Mixed type', function ($value) {
674+
$validator = new Validator;
675+
$model = $validator->validate(['value' => $value], new Models\RawMixed);
676+
expect($model)
677+
->toBeInstanceOf(Models\RawMixed::class)
678+
->toHaveProperty('value', $value);
679+
})
680+
->with('mixed')
681+
->group('validator', 'basic', 'mixed');
682+
683+
test('Using default value - mixed', function () {
684+
$validator = new Validator;
685+
$model = $validator->validate([], new Models\DefaultMixed);
686+
expect($model)
687+
->toBeInstanceOf(Models\DefaultMixed::class)
688+
->toHaveProperty('value', 'default');
689+
})
690+
->group('validator', 'basic', 'mixed');

tests/Integration/ValidateCallableTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Attributes\Validation\Exceptions\ValidationException;
1717
use Attributes\Validation\Tests\Models as Models;
1818
use Attributes\Validation\Validator;
19+
use DateTime;
1920

2021
// Alias and alias generator
2122

@@ -176,3 +177,23 @@
176177
})
177178
->with([true, false])
178179
->group('validator', 'validate-callable', 'numbered-arguments');
180+
181+
// Callable
182+
183+
test('Callable - validate callable', function (bool $isStrict, mixed $callable) {
184+
$validator = new Validator(strict: $isStrict);
185+
$rawData = ['value' => $callable];
186+
$call = function (callable $value) {
187+
return 'success';
188+
};
189+
$args = $validator->validateCallable($rawData, $call);
190+
expect($args)
191+
->toBeArray()
192+
->toHaveCount(1)
193+
->toBe([
194+
'value' => $callable,
195+
]);
196+
})
197+
->with([true, false])
198+
->with(['trim', [[new DateTime, 'format']], fn () => true])
199+
->group('validator', 'validate-callable', 'callable');

tests/Models/Basic/Mixed.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Attributes\Validation\Tests\Models\Basic;
4+
5+
class RawMixed
6+
{
7+
public mixed $value;
8+
}
9+
10+
class DefaultMixed
11+
{
12+
public mixed $value = 'default';
13+
}

0 commit comments

Comments
 (0)