165 lines
4 KiB
PHP
165 lines
4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests;
|
|
|
|
use Icefox\DTO\Attributes\Flat;
|
|
use Icefox\DTO\RuleFactory;
|
|
use Icefox\DTO\ValueFactory;
|
|
use Illuminate\Support\Collection;
|
|
|
|
readonly class BasicPrimitives
|
|
{
|
|
public function __construct(
|
|
public string $text,
|
|
public int $number,
|
|
public bool $flag,
|
|
public ?array $items,
|
|
public float $floating = 0.0,
|
|
) {}
|
|
}
|
|
|
|
test('required rules', function () {
|
|
$object = ValueFactory::make(BasicPrimitives::class, [
|
|
'text' => 'abc',
|
|
'number' => 42,
|
|
'flag' => false,
|
|
'items' => ['a', 2, true],
|
|
'floating' => 4.2,
|
|
]);
|
|
expect($object->text)->toBe('abc');
|
|
expect($object->number)->toBe(42);
|
|
expect($object->flag)->toBe(false);
|
|
expect($object->items)->toBe(['a', 2, true]);
|
|
expect($object->floating)->toEqualWithDelta(4.2, 0.000001);
|
|
});
|
|
|
|
readonly class AnnotatedArray
|
|
{
|
|
/**
|
|
* @param array<int,float> $items
|
|
*/
|
|
public function __construct(public array $items) {}
|
|
}
|
|
test('annotated array', function () {
|
|
expect(RuleFactory::instance()->make(AnnotatedArray::class))->toBe([
|
|
'items' => ['required', 'array'],
|
|
'items.*' => ['required', 'numeric'],
|
|
]);
|
|
});
|
|
|
|
readonly class AnnotatedArrayNullableValue
|
|
{
|
|
/**
|
|
* @param array<?float> $items
|
|
*/
|
|
public function __construct(public array $items) {}
|
|
}
|
|
test('annotated array with nullable items', function () {
|
|
expect(RuleFactory::instance()->make(AnnotatedArrayNullableValue::class))->toBe([
|
|
'items' => ['required', 'array'],
|
|
'items.*' => ['nullable', 'numeric'],
|
|
]);
|
|
});
|
|
|
|
readonly class PlainLeaf
|
|
{
|
|
public function __construct(public string $name) {}
|
|
}
|
|
readonly class PlainRoot
|
|
{
|
|
public function __construct(public int $value, public PlainLeaf $leaf) {}
|
|
}
|
|
|
|
test('plain nesting', function () {
|
|
expect(RuleFactory::instance()->make(PlainRoot::class))->toBe([
|
|
'value' => ['required', 'numeric'],
|
|
'leaf' => ['required'],
|
|
'leaf.name' => ['required'],
|
|
]);
|
|
});
|
|
|
|
|
|
readonly class AnnotatedArrayItem
|
|
{
|
|
public function __construct(public int $value) {}
|
|
}
|
|
|
|
readonly class AnnotatedArrayObject
|
|
{
|
|
/**
|
|
* @param ?array<AnnotatedArrayItem> $items
|
|
*/
|
|
public function __construct(public ?array $items) {}
|
|
}
|
|
|
|
test('annotated array with object', function () {
|
|
expect(RuleFactory::instance()->make(AnnotatedArrayObject::class))->toBe([
|
|
'items' => ['nullable', 'array'],
|
|
'items.*' => ['required'],
|
|
'items.*.value' => ['required', 'numeric'],
|
|
]);
|
|
});
|
|
|
|
readonly class FlattenedLeaf
|
|
{
|
|
public function __construct(public ?bool $flag) {}
|
|
}
|
|
|
|
readonly class NotFlattenedLeaf
|
|
{
|
|
public function __construct(public string $description) {}
|
|
}
|
|
|
|
readonly class FlattenedNode
|
|
{
|
|
public function __construct(
|
|
public string $id,
|
|
public NotFlattenedLeaf $leaf,
|
|
#[Flat]
|
|
public FlattenedLeaf $squish,
|
|
public int $level = 1,
|
|
) {}
|
|
}
|
|
|
|
readonly class FlattenedRoot
|
|
{
|
|
public function __construct(
|
|
public int $value,
|
|
#[Flat]
|
|
public FlattenedNode $node,
|
|
) {}
|
|
}
|
|
|
|
test('flattened basic', function () {
|
|
expect(RuleFactory::instance()->make(FlattenedRoot::class))->toBe([
|
|
'value' => ['required', 'numeric'],
|
|
'id' => ['required' ],
|
|
'leaf' => ['required'],
|
|
'leaf.description' => ['required'],
|
|
'flag' => ['nullable', 'boolean'],
|
|
'level' => ['sometimes', 'numeric'],
|
|
]);
|
|
});
|
|
|
|
readonly class AnnotatedCollectionItem
|
|
{
|
|
public function __construct(public int $value) {}
|
|
}
|
|
|
|
readonly class AnnotatedCollection
|
|
{
|
|
/**
|
|
* @param Collection<AnnotatedCollectionItem> $group
|
|
*/
|
|
public function __construct(public Collection $group) {}
|
|
}
|
|
|
|
test('annotated collection', function () {
|
|
expect(RuleFactory::instance()->make(AnnotatedCollection::class))->toBe([
|
|
'group' => ['required', 'array'],
|
|
'group.*' => ['required'],
|
|
'group.*.value' => ['required', 'numeric'],
|
|
]);
|
|
});
|