Files
tez-utils-validate/tests/EachTest.php
T

97 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Tez\Utils\Tests\Validate;
use PHPUnit\Framework\TestCase;
use Tez\Utils\Validate\Each;
use Tez\Utils\Validate\Guard;
final class EachTest extends TestCase
{
public function testPassesWhenAllItemsAreValid(): void
{
$this->expectNotToPerformAssertions();
Each::validate([1, 2, 3], function (mixed $item): void {
Guard::isTrue(is_int($item) && $item > 0, \InvalidArgumentException::class);
});
}
public function testThrowsOnFirstInvalidItem(): void
{
$this->expectException(\DomainException::class);
$this->expectExceptionMessageMatches('/items\[1\]/');
$orders = [
['amount' => 50],
['amount' => -10],
['amount' => 200],
];
Each::validate($orders, function (mixed $order): void {
/** @var array{amount: int} $order */
if ($order['amount'] <= 0) {
throw new \DomainException('Amount must be positive.');
}
});
}
public function testIndexIsIncludedInMessage(): void
{
try {
Each::validate(['ok', 'ok', 'fail'], function (mixed $item): void {
if ($item === 'fail') {
throw new \RuntimeException('bad value');
}
});
self::fail('Expected exception not thrown.');
} catch (\RuntimeException $e) {
self::assertStringContainsString('items[2]', $e->getMessage());
self::assertStringContainsString('bad value', $e->getMessage());
}
}
public function testCustomPathIsUsed(): void
{
try {
Each::validate(['a', 'b'], fn() => throw new \RuntimeException('err'), path: 'lines');
self::fail('Expected exception not thrown.');
} catch (\RuntimeException $e) {
self::assertStringContainsString('lines[', $e->getMessage());
}
}
public function testEmptyArrayPasses(): void
{
$this->expectNotToPerformAssertions();
Each::validate([], fn() => throw new \RuntimeException('should not be called'));
}
public function testOriginalExceptionIsAvailableAsPrevious(): void
{
$original = new \DomainException('original message');
try {
Each::validate(['x'], function () use ($original): void {
throw $original;
});
} catch (\DomainException $e) {
self::assertSame($original, $e->getPrevious());
}
}
public function testRuleReceivesIndexAsSecondArgument(): void
{
$received = [];
Each::validate(['a', 'b', 'c'], function (mixed $item, int|string $index) use (&$received): void {
$received[] = $index;
});
self::assertSame([0, 1, 2], $received);
}
}