* SPDX-License-Identifier: MIT */ declare(strict_types=1); test('one rule / one failed', expectAll( fn() => v::keySet(v::key('foo', v::intType()))->assert(['foo' => 'string']), 'foo must be an integer', '- foo must be an integer', ['foo' => 'foo must be an integer'] )); test('one rule / one missing key', expectAll( fn() => v::keySet(v::keyExists('foo'))->assert([]), 'foo must be present', '- foo must be present', ['foo' => 'foo must be present'] )); test('one rule / one extra key', expectAll( fn() => v::keySet(v::keyExists('foo'))->assert(['foo' => 42, 'bar' => 'string']), 'bar must not be present', '- bar must not be present', ['bar' => 'bar must not be present'] )); test('one rule / one extra key / one missing key', expectAll( fn() => v::keySet(v::keyExists('foo'))->assert(['bar' => true]), 'foo must be present', <<<'FULL_MESSAGE' - `["bar": true]` contains both missing and extra keys - foo must be present - bar must not be present FULL_MESSAGE, [ '__root__' => '`["bar": true]` contains both missing and extra keys', 'foo' => 'foo must be present', 'bar' => 'bar must not be present', ] )); test('one rule / two extra keys', expectAll( fn() => v::keySet(v::keyExists('foo'))->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), 'bar must not be present', <<<'FULL_MESSAGE' - `["foo": 42, "bar": "string", "baz": true]` contains extra keys - bar must not be present - baz must not be present FULL_MESSAGE, [ '__root__' => '`["foo": 42, "bar": "string", "baz": true]` contains extra keys', 'bar' => 'bar must not be present', 'baz' => 'baz must not be present', ] )); test('one rule / more than ten extra keys', expectAll( fn() => v::keySet(v::keyExists('foo')) ->assert([ 'foo' => 42, 'bar' => 'string', 'baz' => true, 'qux' => false, 'quux' => 42, 'corge' => 'string', 'grault' => true, 'garply' => false, 'waldo' => 42, 'fred' => 'string', 'plugh' => true, 'xyzzy' => false, 'thud' => 42, ]), 'bar must not be present', <<<'FULL_MESSAGE' - `["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys - bar must not be present - baz must not be present - qux must not be present - quux must not be present - corge must not be present - grault must not be present - garply must not be present - waldo must not be present - fred must not be present - plugh must not be present FULL_MESSAGE, [ '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys', 'bar' => 'bar must not be present', 'baz' => 'baz must not be present', 'qux' => 'qux must not be present', 'quux' => 'quux must not be present', 'corge' => 'corge must not be present', 'grault' => 'grault must not be present', 'garply' => 'garply must not be present', 'waldo' => 'waldo must not be present', 'fred' => 'fred must not be present', 'plugh' => 'plugh must not be present', ] )); test('multiple rules / one failed', expectAll( fn() => v::keySet(v::keyExists('foo'), v::keyExists('bar'))->assert(['foo' => 42]), 'bar must be present', '- bar must be present', ['bar' => 'bar must be present'] )); test('multiple rules / all failed', expectAll( fn() => v::keySet(v::keyExists('foo'), v::keyExists('bar'))->assert([]), 'foo must be present', <<<'FULL_MESSAGE' - `[]` contains missing keys - foo must be present - bar must be present FULL_MESSAGE, [ '__root__' => '`[]` contains missing keys', 'foo' => 'foo must be present', 'bar' => 'bar must be present', ] )); test('multiple rules / one extra key', expectAll( fn() => v::keySet( v::keyExists('foo'), v::keyExists('bar') )->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), 'baz must not be present', '- baz must not be present', ['baz' => 'baz must not be present'] )); test('multiple rules / one extra key / one missing', expectAll( fn() => v::keySet( v::keyExists('foo'), v::keyExists('bar') )->assert(['bar' => 'string', 'baz' => true]), 'foo must be present', <<<'FULL_MESSAGE' - `["bar": "string", "baz": true]` contains both missing and extra keys - foo must be present - baz must not be present FULL_MESSAGE, [ '__root__' => '`["bar": "string", "baz": true]` contains both missing and extra keys', 'foo' => 'foo must be present', 'baz' => 'baz must not be present', ] )); test('multiple rules / two extra keys', expectAll( fn() => v::keySet( v::keyExists('foo'), v::keyExists('bar'), v::keyOptional('qux', v::intType()) )->assert(['foo' => 42, 'bar' => 'string', 'baz' => true, 'qux' => false]), 'qux must be an integer', <<<'FULL_MESSAGE' - `["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys - qux must be an integer - baz must not be present FULL_MESSAGE, [ '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys', 'qux' => 'qux must be an integer', 'baz' => 'baz must not be present', ] )); test('multiple rules / all failed validation', expectAll( fn() => v::keySet( v::key('foo', v::intType()), v::key('bar', v::intType()), v::key('baz', v::intType()) ) ->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), 'bar must be an integer', <<<'FULL_MESSAGE' - `["foo": 42, "bar": "string", "baz": true]` validation failed - bar must be an integer - baz must be an integer FULL_MESSAGE, [ '__root__' => '`["foo": 42, "bar": "string", "baz": true]` validation failed', 'bar' => 'bar must be an integer', 'baz' => 'baz must be an integer', ] )); test('multiple rules / single missing key / single failed validation', expectAll( fn() => v::keySet( v::create() ->key('foo', v::intType()) ->key('bar', v::intType()) ->key('baz', v::intType()) ) ->assert(['foo' => 42, 'bar' => 'string']), 'bar must be an integer', <<<'FULL_MESSAGE' - `["foo": 42, "bar": "string"]` contains missing keys - bar must be an integer - baz must be present FULL_MESSAGE, [ '__root__' => '`["foo": 42, "bar": "string"]` contains missing keys', 'bar' => 'bar must be an integer', 'baz' => 'baz must be present', ] ));