* SPDX-FileContributor: Henrique Moody */ declare(strict_types=1); test('Default', catchAll( fn() => v::shortCircuit(v::alwaysValid(), v::trueVal())->assert(false), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('`false` must evaluate to `true`') ->and($fullMessage)->toBe('- `false` must evaluate to `true`') ->and($messages)->toBe(['trueVal' => '`false` must evaluate to `true`']), )); test('With recursive', catchAll( fn() => v::shortCircuit(v::each(v::intType()))->assert([1, 2, '3', 4]), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('`.2` must be an integer') ->and($fullMessage)->toBe('- `.2` must be an integer') ->and($messages)->toBe([2 => '`.2` must be an integer']), )); test('Inverted', catchAll( fn() => v::not(v::shortCircuit(v::alwaysValid(), v::trueVal()))->assert(true), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('`true` must not evaluate to `true`') ->and($fullMessage)->toBe('- `true` must not evaluate to `true`') ->and($messages)->toBe(['notTrueVal' => '`true` must not evaluate to `true`']), )); test('Default with inverted failing rule', catchAll( fn() => v::shortCircuit(v::alwaysValid(), v::not(v::trueVal()))->assert(true), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('`true` must not evaluate to `true`') ->and($fullMessage)->toBe('- `true` must not evaluate to `true`') ->and($messages)->toBe(['notTrueVal' => '`true` must not evaluate to `true`']), )); test('With wrapped name, default', catchAll( fn() => v::named('Wrapper', v::shortCircuit(v::alwaysValid(), v::named('Wrapped', v::trueVal())))->assert(false), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Wrapped must evaluate to `true`') ->and($fullMessage)->toBe('- Wrapped must evaluate to `true`') ->and($messages)->toBe(['trueVal' => 'Wrapped must evaluate to `true`']), )); test('With wrapper name, default', catchAll( fn() => v::named('Wrapper', v::shortCircuit(v::alwaysValid(), v::trueVal()))->assert(false), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Wrapper must evaluate to `true`') ->and($fullMessage)->toBe('- Wrapper must evaluate to `true`') ->and($messages)->toBe(['trueVal' => 'Wrapper must evaluate to `true`']), )); test('With the name set in the wrapped rule of an inverted failing rule', catchAll( fn() => v::named('Wrapper', v::shortCircuit(v::alwaysValid(), v::named('Not', v::not(v::named('Wrapped', v::trueVal())))))->assert(true), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Wrapped must not evaluate to `true`') ->and($fullMessage)->toBe('- Wrapped must not evaluate to `true`') ->and($messages)->toBe(['notTrueVal' => 'Wrapped must not evaluate to `true`']), )); test('With the name set in an inverted failing rule', catchAll( fn() => v::named('Wrapper', v::shortCircuit(v::alwaysValid(), v::named('Not', v::not(v::trueVal()))))->assert(true), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Not must not evaluate to `true`') ->and($fullMessage)->toBe('- Not must not evaluate to `true`') ->and($messages)->toBe(['notTrueVal' => 'Not must not evaluate to `true`']), )); test('With the name set in the "shortCircuit" that has an inverted failing rule', catchAll( fn() => v::named('Wrapper', v::shortCircuit(v::alwaysValid(), v::not(v::trueVal())))->assert(true), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Wrapper must not evaluate to `true`') ->and($fullMessage)->toBe('- Wrapper must not evaluate to `true`') ->and($messages)->toBe(['notTrueVal' => 'Wrapper must not evaluate to `true`']), )); test('With template', catchAll( fn() => v::templated('ShortCircuit cool cats cunningly continuous cookies', v::shortCircuit(v::alwaysValid(), v::trueVal())) ->assert(false), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('ShortCircuit cool cats cunningly continuous cookies') ->and($fullMessage)->toBe('- ShortCircuit cool cats cunningly continuous cookies') ->and($messages)->toBe(['trueVal' => 'ShortCircuit cool cats cunningly continuous cookies']), )); test('With multiple templates', catchAll( fn() => v::shortCircuit(v::alwaysValid(), v::trueVal()) ->assert(false, ['trueVal' => 'Clever clowns craft shortCircuit clever clocks']), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('Clever clowns craft shortCircuit clever clocks') ->and($fullMessage)->toBe('- Clever clowns craft shortCircuit clever clocks') ->and($messages)->toBe(['trueVal' => 'Clever clowns craft shortCircuit clever clocks']), )); test('Real example', catchAll( fn() => v::shortCircuit( v::key('countyCode', v::countryCode()), v::factory( fn($input) => v::key('subdivisionCode', v::subdivisionCode($input['countyCode'])), ), )->assert(['countyCode' => 'BR', 'subdivisionCode' => 'CA']), fn(string $message, string $fullMessage, array $messages) => expect() ->and($message)->toBe('`.subdivisionCode` must be a subdivision code of Brazil') ->and($fullMessage)->toBe('- `.subdivisionCode` must be a subdivision code of Brazil') ->and($messages)->toBe(['subdivisionCode' => '`.subdivisionCode` must be a subdivision code of Brazil']), ));