diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc32e7a..c346c4f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed - Update test case to current (PHP) standards ([#831](https://github.com/jsonrainbow/json-schema/pull/831)) +- Upgrade test suite to use generators ([#834](https://github.com/jsonrainbow/json-schema/pull/834)) ## [6.4.2] - 2025-06-03 ### Fixed diff --git a/tests/ConstraintErrorTest.php b/tests/ConstraintErrorTest.php index 158f3074..cc599010 100644 --- a/tests/ConstraintErrorTest.php +++ b/tests/ConstraintErrorTest.php @@ -1,11 +1,6 @@ expectException('\JsonSchema\Exception\InvalidArgumentException'); + $this->expectException(\JsonSchema\Exception\InvalidArgumentException::class); $this->expectExceptionMessage('Missing error message for missingError'); $e->getMessage(); diff --git a/tests/Constraints/AdditionalPropertiesTest.php b/tests/Constraints/AdditionalPropertiesTest.php index 46b29a82..a4753cde 100644 --- a/tests/Constraints/AdditionalPropertiesTest.php +++ b/tests/Constraints/AdditionalPropertiesTest.php @@ -1,11 +1,6 @@ Validator::ERROR_DOCUMENT_VALIDATION ] ] - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":"2" @@ -62,8 +56,8 @@ public function getInvalidTests(): array }, "additionalProperties": false }' - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":2 @@ -75,8 +69,8 @@ public function getInvalidTests(): array }, "additionalProperties": {"type":"string"} }' - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":2 @@ -88,8 +82,8 @@ public function getInvalidTests(): array }, "additionalProperties": {"type":"string"} }' - ], - [ + ]; + yield [ '{ "prop1": "a", "prop2": "b" @@ -100,8 +94,8 @@ public function getInvalidTests(): array "type": "boolean" } }' - ], - [ + ]; + yield [ '{ "prop1": "a", "prop2": "b" @@ -110,14 +104,12 @@ public function getInvalidTests(): array "type": "object", "additionalProperties": false }' - ], - ]; + ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ + yield [ '{ "prop":"1", "additionalProp":"2" @@ -128,8 +120,8 @@ public function getValidTests(): array "prop":{"type":"string"} } }' - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":"2" @@ -140,8 +132,8 @@ public function getValidTests(): array "prop":{"type":"string"} } }' - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":"2" @@ -153,8 +145,8 @@ public function getValidTests(): array }, "additionalProperties": {"type":"string"} }' - ], - [ + ]; + yield [ '{ "prop":"1", "additionalProp":[] @@ -166,8 +158,8 @@ public function getValidTests(): array }, "additionalProperties": true }' - ], - [ + ]; + yield [ '{ "prop1": "a", "prop2": "b" @@ -178,8 +170,8 @@ public function getValidTests(): array "type": "string" } }' - ], - [ + ]; + yield [ '{ "prop1": "a", "prop2": "b" @@ -188,8 +180,8 @@ public function getValidTests(): array "type": "object", "additionalProperties": true }' - ], - 'additional property casted into int when actually is numeric string (#784)' => [ + ]; + yield 'additional property casted into int when actually is numeric string (#784)' => [ '{ "prop1": { "123": "a" @@ -206,7 +198,6 @@ public function getValidTests(): array } } }' - ], - ]; + ]; } } diff --git a/tests/Constraints/ArraysTest.php b/tests/Constraints/ArraysTest.php index aac3fc7f..4476c4ab 100644 --- a/tests/Constraints/ArraysTest.php +++ b/tests/Constraints/ArraysTest.php @@ -1,22 +1,17 @@ [ '{"data": ["a", "b"]}', '{ "type": "object", @@ -86,8 +81,8 @@ public function getInvalidTests(): array } } }' - ], - [ // Test array items.enum where type integer fail validation if value(s) is/are not in items.enum + ]; + yield 'Test array items.enum where type integer fail validation if value(s) is/are not in items.enum' => [ '{"data": [1, 2]}', '{ "type": "object", @@ -101,8 +96,8 @@ public function getInvalidTests(): array } } }' - ], - [ // Test array items.enum where type number fail validation if value(s) is/are not in items.enum + ]; + yield 'Test array items.enum where type number fail validation if value(s) is/are not in items.enum' => [ '{"data": [1.25, 2.25]}', '{ "type": "object", @@ -116,8 +111,8 @@ public function getInvalidTests(): array } } }' - ], - [ + ]; + yield [ '{"data": [{"not_a_string_but_object":"string_but_in_object"}]}', '{ "type": "object", @@ -129,14 +124,12 @@ public function getInvalidTests(): array } } }' - ] - ]; + ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ + yield [ '{ "array":[1,2,"a"] }', @@ -146,8 +139,8 @@ public function getValidTests(): array "array":{"type":"array"} } }' - ], - [ + ]; + yield [ '{ "array":[1,2,"a"] }', @@ -161,8 +154,8 @@ public function getValidTests(): array } } }' - ], - [ + ]; + yield [ '{"data": [1, 2, 3, 4]}', '{ "type": "object", @@ -174,8 +167,8 @@ public function getValidTests(): array } } }' - ], - [ + ]; + yield [ '{"data": [1, "foo", false]}', '{ "type": "object", @@ -186,8 +179,8 @@ public function getValidTests(): array } } }' - ], - [ + ]; + yield [ '{"data": [1, "foo", false]}', '{ "type": "object", @@ -198,8 +191,8 @@ public function getValidTests(): array } } }' - ], - [ + ]; + yield [ '{"data": [1, 2, 3, 4, 5]}', '{ "type": "object", @@ -210,8 +203,8 @@ public function getValidTests(): array } } }' - ], - [ // test more schema items than array items + ]; + yield 'test more schema items than array items' => [ '{"data": [1, 2]}', '{ "type": "object", @@ -226,8 +219,8 @@ public function getValidTests(): array } } }' - ], - [ // Test array items.enum where type string passes validation if value(s) is/are in items.enum + ]; + yield 'Test array items.enum where type string passes validation if value(s) is/are in items.enum' => [ '{"data": ["c", "c", "b"]}', '{ "type": "object", @@ -241,8 +234,8 @@ public function getValidTests(): array } } }' - ], - [ // Test array items.enum where type integer passes validation if value(s) is/are in items.enum + ]; + yield 'Test array items.enum where type integer passes validation if value(s) is/are in items.enum' => [ '{"data": [1, 1, 2]}', '{ "type": "object", @@ -256,8 +249,8 @@ public function getValidTests(): array } } }' - ], - [ // Test array items.enum where type number passes validation if value(s) is/are in items.enum + ]; + yield 'Test array items.enum where type number passes validation if value(s) is/are in items.enum' => [ '{"data": [1.25, 1.25, 2.25]}', '{ "type": "object", @@ -271,7 +264,6 @@ public function getValidTests(): array } } }' - ], ]; } } diff --git a/tests/Constraints/BaseTestCase.php b/tests/Constraints/BaseTestCase.php index 84daaf13..f65037d6 100644 --- a/tests/Constraints/BaseTestCase.php +++ b/tests/Constraints/BaseTestCase.php @@ -1,23 +1,16 @@ validateSchema) { $checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA; } @@ -94,14 +87,14 @@ public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_M if ($this->validateSchema) { $checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA; } - $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema))); + $schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema, false))); $schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json'); if (is_object($schema) && !isset($schema->{'$schema'})) { $schema->{'$schema'} = $this->schemaSpec; } $validator = new Validator(new Factory($schemaStorage, null, $checkMode)); - $checkValue = json_decode($input); + $checkValue = json_decode($input, false); $errorMask = $validator->validate($checkValue, $schema); $this->assertEquals(0, $errorMask); @@ -135,17 +128,17 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain $this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true)); } - abstract public function getValidTests(): array; + abstract public function getValidTests(): Generator; - public function getValidForAssocTests(): array + public function getValidForAssocTests(): Generator { - return $this->getValidTests(); + yield from $this->getValidTests(); } - abstract public function getInvalidTests(): array; + abstract public function getInvalidTests(): Generator; - public function getInvalidForAssocTests(): array + public function getInvalidForAssocTests(): Generator { - return $this->getInvalidTests(); + yield from $this->getInvalidTests(); } } diff --git a/tests/Constraints/BasicTypesTest.php b/tests/Constraints/BasicTypesTest.php index 01e1f7ba..497cb578 100644 --- a/tests/Constraints/BasicTypesTest.php +++ b/tests/Constraints/BasicTypesTest.php @@ -1,150 +1,143 @@ [ - '{"value":"foo"}', - '{ - "type":"object", - "properties":{ - "value":{"type":"string","const":"bar"} - }, - "additionalProperties":false - }' - ], - 'Object with inner integer value' => [ - '{"value":5}', - '{ - "type":"object", - "properties":{ - "value":{"type":"integer","const":6} - }, - "additionalProperties":false - }' - ], - 'Object with inner boolean value' => [ - '{"value":false}', - '{ - "type":"object", - "properties":{ - "value":{"type":"boolean","const":true} - }, - "additionalProperties":false - }' - ], - 'Object with inner numerical string value' => [ + yield 'Object with inner string value' => [ + '{"value":"foo"}', + '{ + "type":"object", + "properties":{ + "value":{"type":"string","const":"bar"} + }, + "additionalProperties":false + }' + ]; + yield 'Object with inner integer value' => [ + '{"value":5}', + '{ + "type":"object", + "properties":{ + "value":{"type":"integer","const":6} + }, + "additionalProperties":false + }' + ]; + yield 'Object with inner boolean value' => [ + '{"value":false}', + '{ + "type":"object", + "properties":{ + "value":{"type":"boolean","const":true} + }, + "additionalProperties":false + }' + ]; + yield 'Object with inner numerical string value' => [ '{ "value": { "foo": "12" @@ -64,54 +60,52 @@ public function getInvalidTests(): array } } }' - ] - ]; + ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - 'String value' => [ - '{"value":"bar"}', - '{ - "type":"object", - "properties":{ - "value":{"type":"string","const":"bar"} - }, - "additionalProperties":false - }' - ], - 'Boolean(false) value' => [ - '{"value":false}', - '{ - "type":"object", - "properties":{ - "value":{"type":"boolean","const":false} - }, - "additionalProperties":false - }' - ], - 'Boolean(true) value' => [ - '{"value":true}', - '{ - "type":"object", - "properties":{ - "value":{"type":"boolean","const":true} - }, - "additionalProperties":false - }' - ], - 'Integer value' => [ - '{"value":5}', - '{ - "type":"object", - "properties":{ - "value":{"type":"integer","const":5} - }, - "additionalProperties":false - }' - ], - 'Object with inner integer value' => [ + yield 'String value' => [ + '{"value":"bar"}', + '{ + "type":"object", + "properties":{ + "value":{"type":"string","const":"bar"} + }, + "additionalProperties":false + }' + ]; + yield 'Boolean(false) value' => [ + '{"value":false}', + '{ + "type":"object", + "properties":{ + "value":{"type":"boolean","const":false} + }, + "additionalProperties":false + }' + ]; + yield 'Boolean(true) value' => [ + '{"value":true}', + '{ + "type":"object", + "properties":{ + "value":{"type":"boolean","const":true} + }, + "additionalProperties":false + }' + ]; + yield 'Integer value' => [ + '{"value":5}', + '{ + "type":"object", + "properties":{ + "value":{"type":"integer","const":5} + }, + "additionalProperties":false + }' + ]; + yield 'Object with inner integer value' => [ '{ "value": { "foo": 12 @@ -128,7 +122,6 @@ public function getValidTests(): array } } }' - ] - ]; + ]; } } diff --git a/tests/Constraints/DefaultPropertiesTest.php b/tests/Constraints/DefaultPropertiesTest.php index 28498352..e43b980e 100644 --- a/tests/Constraints/DefaultPropertiesTest.php +++ b/tests/Constraints/DefaultPropertiesTest.php @@ -1,11 +1,6 @@ [ - 'data' => '12', - 'schema' => '{ - "type": "any", - "enum": [ - 12.0 - ] - }' - ], - 'Array with number values with mathematical equality are considered valid' => [ - 'input' => '[ 0.0 ]', - 'schema' => '{ - "enum": [ - [ 0 ] - ] - }', - ] + } + }' + ]; + yield 'Number values with mathematical equality are considered valid' => [ + 'data' => '12', + 'schema' => '{ + "type": "any", + "enum": [ + 12.0 + ] + }' + ]; + yield 'Array with number values with mathematical equality are considered valid' => [ + 'input' => '[ 0.0 ]', + 'schema' => '{ + "enum": [ + [ 0 ] + ] + }', ]; } } diff --git a/tests/Constraints/ExtendsTest.php b/tests/Constraints/ExtendsTest.php index 286b24b8..2fd0adc1 100644 --- a/tests/Constraints/ExtendsTest.php +++ b/tests/Constraints/ExtendsTest.php @@ -1,154 +1,147 @@ assertEmpty($validator->getErrors()); } - public function getValidFormats(): array + public function getValidFormats(): \Generator { - return [ - ['2001-01-23', 'date'], - ['2000-02-29', 'date'], - [42, 'date'], - [4.2, 'date'], - - ['12:22:01', 'time'], - ['00:00:00', 'time'], - ['23:59:59', 'time'], - [42, 'time'], - [4.2, 'time'], - - ['2000-05-01T12:12:12Z', 'date-time'], - ['2000-05-01T12:12:12+0100', 'date-time'], - ['2000-05-01T12:12:12+01:00', 'date-time'], - ['2000-05-01T12:12:12.123456Z', 'date-time'], - ['2000-05-01T12:12:12.123Z', 'date-time'], - ['2000-05-01T12:12:12.123000Z', 'date-time'], - ['2000-05-01T12:12:12.0Z', 'date-time'], - ['2000-05-01T12:12:12.000Z', 'date-time'], - ['2000-05-01T12:12:12.000000Z', 'date-time'], - [42, 'date-time'], - [4.2, 'date-time'], - - ['0', 'utc-millisec'], - - ['aqua', 'color'], - ['black', 'color'], - ['blue', 'color'], - ['fuchsia', 'color'], - ['gray', 'color'], - ['green', 'color'], - ['lime', 'color'], - ['maroon', 'color'], - ['navy', 'color'], - ['olive', 'color'], - ['orange', 'color'], - ['purple', 'color'], - ['red', 'color'], - ['silver', 'color'], - ['teal', 'color'], - ['white', 'color'], - ['yellow', 'color'], - ['#fff', 'color'], - ['#00cc00', 'color'], - [42, 'color'], - [4.2, 'color'], - - ['background: blue', 'style'], - ['color: #000;', 'style'], - - ['555 320 1212', 'phone'], - - ['http://bluebox.org', 'uri'], - ['//bluebox.org', 'uri-reference'], - ['/absolutePathReference/', 'uri-reference'], - ['./relativePathReference/', 'uri-reference'], - ['./relative:PathReference/', 'uri-reference'], - ['relativePathReference/', 'uri-reference'], - ['relative/Path:Reference/', 'uri-reference'], - [42, 'uri-reference'], - [4.2, 'uri-reference'], - - ['info@something.edu', 'email'], - [42, 'email'], - [4.2, 'email'], - - ['10.10.10.10', 'ip-address'], - ['127.0.0.1', 'ip-address'], - [42, 'ip-address'], - [4.2, 'ip-address'], - - ['127.0.0.1', 'ipv4'], - [42, 'ipv4'], - [4.2, 'ipv4'], - - ['::ff', 'ipv6'], - [42, 'ipv6'], - [4.2, 'ipv6'], - - ['www.example.com', 'host-name'], - ['3v4l.org', 'host-name'], - ['a-valid-host.com', 'host-name'], - ['localhost', 'host-name'], - [42, 'host-name'], - [4.2, 'host-name'], - - ['www.example.com', 'hostname'], - ['3v4l.org', 'hostname'], - ['a-valid-host.com', 'hostname'], - ['localhost', 'hostname'], - [42, 'hostname'], - [4.2, 'hostname'], - - ['anything', '*'], - ['unknown', '*'], - ]; + yield ['2001-01-23', 'date']; + yield ['2000-02-29', 'date']; + yield [42, 'date']; + yield [4.2, 'date']; + + yield ['12:22:01', 'time']; + yield ['00:00:00', 'time']; + yield ['23:59:59', 'time']; + yield [42, 'time']; + yield [4.2, 'time']; + + yield ['2000-05-01T12:12:12Z', 'date-time']; + yield ['2000-05-01T12:12:12+0100', 'date-time']; + yield ['2000-05-01T12:12:12+01:00', 'date-time']; + yield ['2000-05-01T12:12:12.123456Z', 'date-time']; + yield ['2000-05-01T12:12:12.123Z', 'date-time']; + yield ['2000-05-01T12:12:12.123000Z', 'date-time']; + yield ['2000-05-01T12:12:12.0Z', 'date-time']; + yield ['2000-05-01T12:12:12.000Z', 'date-time']; + yield ['2000-05-01T12:12:12.000000Z', 'date-time']; + yield [42, 'date-time']; + yield [4.2, 'date-time']; + + yield ['0', 'utc-millisec']; + + yield ['aqua', 'color']; + yield ['black', 'color']; + yield ['blue', 'color']; + yield ['fuchsia', 'color']; + yield ['gray', 'color']; + yield ['green', 'color']; + yield ['lime', 'color']; + yield ['maroon', 'color']; + yield ['navy', 'color']; + yield ['olive', 'color']; + yield ['orange', 'color']; + yield ['purple', 'color']; + yield ['red', 'color']; + yield ['silver', 'color']; + yield ['teal', 'color']; + yield ['white', 'color']; + yield ['yellow', 'color']; + yield ['#fff', 'color']; + yield ['#00cc00', 'color']; + yield [42, 'color']; + yield [4.2, 'color']; + + yield ['background: blue', 'style']; + yield ['color: #000;', 'style']; + + yield ['555 320 1212', 'phone']; + + yield ['http://bluebox.org', 'uri']; + yield ['//bluebox.org', 'uri-reference']; + yield ['/absolutePathReference/', 'uri-reference']; + yield ['./relativePathReference/', 'uri-reference']; + yield ['./relative:PathReference/', 'uri-reference']; + yield ['relativePathReference/', 'uri-reference']; + yield ['relative/Path:Reference/', 'uri-reference']; + yield [42, 'uri-reference']; + yield [4.2, 'uri-reference']; + + yield ['info@something.edu', 'email']; + yield [42, 'email']; + yield [4.2, 'email']; + + yield ['10.10.10.10', 'ip-address']; + yield ['127.0.0.1', 'ip-address']; + yield [42, 'ip-address']; + yield [4.2, 'ip-address']; + + yield ['127.0.0.1', 'ipv4']; + yield [42, 'ipv4']; + yield [4.2, 'ipv4']; + + yield ['::ff', 'ipv6']; + yield [42, 'ipv6']; + yield [4.2, 'ipv6']; + + yield ['www.example.com', 'host-name']; + yield ['3v4l.org', 'host-name']; + yield ['a-valid-host.com', 'host-name']; + yield ['localhost', 'host-name']; + yield [42, 'host-name']; + yield [4.2, 'host-name']; + + yield ['www.example.com', 'hostname']; + yield ['3v4l.org', 'hostname']; + yield ['a-valid-host.com', 'hostname']; + yield ['localhost', 'hostname']; + yield [42, 'hostname']; + yield [4.2, 'hostname']; + + yield ['anything', '*']; + yield ['unknown', '*']; } - public function getInvalidFormats(): array + public function getInvalidFormats(): \Generator { - return [ - ['January 1st, 1910', 'date'], - ['199-01-1', 'date'], - ['2012-0-11', 'date'], - ['2012-10-1', 'date'], + yield ['January 1st, 1910', 'date']; + yield ['199-01-1', 'date']; + yield ['2012-0-11', 'date']; + yield ['2012-10-1', 'date']; - ['24:01:00', 'time'], - ['00:00:60', 'time'], - ['25:00:00', 'time'], + yield ['24:01:00', 'time']; + yield ['00:00:60', 'time']; + yield ['25:00:00', 'time']; - ['invalid_value_2000-05-01T12:12:12Z', 'date-time'], - ['2000-05-01T12:12:12Z_invalid_value', 'date-time'], - ['1999-1-11T00:00:00Z', 'date-time'], - ['1999-01-11T00:00:00+100', 'date-time'], - ['1999-01-11T00:00:00+1:00', 'date-time'], - ['1999.000Z-01-11T00:00:00+1:00', 'date-time'], + yield ['invalid_value_2000-05-01T12:12:12Z', 'date-time']; + yield ['2000-05-01T12:12:12Z_invalid_value', 'date-time']; + yield ['1999-1-11T00:00:00Z', 'date-time']; + yield ['1999-01-11T00:00:00+100', 'date-time']; + yield ['1999-01-11T00:00:00+1:00', 'date-time']; + yield ['1999.000Z-01-11T00:00:00+1:00', 'date-time']; - [PHP_INT_MAX, 'utc-millisec'], + yield [PHP_INT_MAX, 'utc-millisec']; - ['grey', 'color'], - ['#HHH', 'color'], - ['#000a', 'color'], - ['#aa', 'color'], + yield ['grey', 'color']; + yield ['#HHH', 'color']; + yield ['#000a', 'color']; + yield ['#aa', 'color']; - ['background; blue', 'style'], + yield ['background; blue', 'style']; - ['1 123 4424', 'phone'], + yield ['1 123 4424', 'phone']; - ['htt:/bluebox.org', 'uri'], - ['.relative:path/reference/', 'uri'], - ['', 'uri'], - ['//bluebox.org', 'uri'], - ['/absolutePathReference/', 'uri'], - ['./relativePathReference/', 'uri'], - ['./relative:PathReference/', 'uri'], - ['relativePathReference/', 'uri'], - ['relative/Path:Reference/', 'uri'], + yield ['htt:/bluebox.org', 'uri']; + yield ['.relative:path/reference/', 'uri']; + yield ['', 'uri']; + yield ['//bluebox.org', 'uri']; + yield ['/absolutePathReference/', 'uri']; + yield ['./relativePathReference/', 'uri']; + yield ['./relative:PathReference/', 'uri']; + yield ['relativePathReference/', 'uri']; + yield ['relative/Path:Reference/', 'uri']; - ['info@somewhere', 'email'], + yield ['info@somewhere', 'email']; - ['256.2.2.2', 'ip-address'], + yield ['256.2.2.2', 'ip-address']; - [':::ff', 'ipv6'], + yield [':::ff', 'ipv6']; - ['@localhost', 'host-name'], - ['..nohost', 'host-name'], - ]; + yield ['@localhost', 'host-name']; + yield ['..nohost', 'host-name']; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - '{ "counter": "10" }', - '{ - "type": "object", - "properties": { - "counter": { - "type": "string", - "format": "regex", - "pattern": "[0-9]+" - } + yield [ + '{ "counter": "10" }', + '{ + "type": "object", + "properties": { + "counter": { + "type": "string", + "format": "regex", + "pattern": "[0-9]+" } - }'], + } + }' ]; } - public function getInvalidTests(): array + public function getInvalidTests(): \Generator { - return [ - [ - '{ "counter": "blue" }', - '{ - "type": "object", - "properties": { - "counter": { - "type": "string", - "format": "regex", - "pattern": "[0-9]+" - } + yield [ + '{ "counter": "blue" }', + '{ + "type": "object", + "properties": { + "counter": { + "type": "string", + "format": "regex", + "pattern": "[0-9]+" } - }' - ], - [ - '{ "color": "blueberry" }', - '{ - "type": "object", - "properties": { - "color": { - "type": "string", - "format": "color" - } + } + }' + ]; + yield [ + '{ "color": "blueberry" }', + '{ + "type": "object", + "properties": { + "color": { + "type": "string", + "format": "color" } - }' - ] + } + }' ]; } } diff --git a/tests/Constraints/LongArraysTest.php b/tests/Constraints/LongArraysTest.php index 8b8c88f0..d5289fed 100644 --- a/tests/Constraints/LongArraysTest.php +++ b/tests/Constraints/LongArraysTest.php @@ -1,11 +1,6 @@ p_array = array_map(function ($i) { - return rand(1, 1000) / 1000.0; + return random_int(1, 1000) / 1000.0; }, range(1, 100000)); $input = json_encode($tmp); diff --git a/tests/Constraints/MinItemsMaxItemsTest.php b/tests/Constraints/MinItemsMaxItemsTest.php index df6f0c75..c096d675 100644 --- a/tests/Constraints/MinItemsMaxItemsTest.php +++ b/tests/Constraints/MinItemsMaxItemsTest.php @@ -1,11 +1,6 @@ [ - 'input' => '{ - "value":[2] - }', - 'schema' => '{ - "type":"object", - "properties":{ - "value":{"type":"array","minItems":2,"maxItems":4} - } - }', - 'checkMode' => Constraint::CHECK_MODE_NORMAL, - [[ - 'property' => 'value', - 'pointer' => '/value', - 'message' => 'There must be a minimum of 2 items in the array, 1 found', - 'constraint' => [ - 'name' => 'minItems', - 'params' => [ - 'minItems' => 2, - 'found' => 1 - ] - ], - 'context' => 1 - ]] - ], - 'Input violating maxItems constraint' => [ - 'input' => '{ - "value":[2,2,5,8,5] - }', - 'schema' => '{ - "type":"object", - "properties":{ - "value":{"type":"array","minItems":2,"maxItems":4} - } - }', - 'checkMode' => Constraint::CHECK_MODE_NORMAL, - [[ - 'property' => 'value', - 'pointer' => '/value', - 'message' => 'There must be a maximum of 4 items in the array, 5 found', - 'constraint' => [ - 'name' => 'maxItems', - 'params' => [ - 'maxItems' => 4, - 'found' => 5 - ] - ], - 'context' => 1 - ]] - ] + yield 'Input violating minItems constraint' => [ + 'input' => '{ + "value":[2] + }', + 'schema' => '{ + "type":"object", + "properties":{ + "value":{"type":"array","minItems":2,"maxItems":4} + } + }', + 'checkMode' => Constraint::CHECK_MODE_NORMAL, + [[ + 'property' => 'value', + 'pointer' => '/value', + 'message' => 'There must be a minimum of 2 items in the array, 1 found', + 'constraint' => [ + 'name' => 'minItems', + 'params' => [ + 'minItems' => 2, + 'found' => 1 + ] + ], + 'context' => 1 + ]] + ]; + yield 'Input violating maxItems constraint' => [ + 'input' => '{ + "value":[2,2,5,8,5] + }', + 'schema' => '{ + "type":"object", + "properties":{ + "value":{"type":"array","minItems":2,"maxItems":4} + } + }', + 'checkMode' => Constraint::CHECK_MODE_NORMAL, + [[ + 'property' => 'value', + 'pointer' => '/value', + 'message' => 'There must be a maximum of 4 items in the array, 5 found', + 'constraint' => [ + 'name' => 'maxItems', + 'params' => [ + 'maxItems' => 4, + 'found' => 5 + ] + ], + 'context' => 1 + ]] ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - '{ - "value":[2,2] - }', - '{ - "type":"object", - "properties":{ - "value":{"type":"array","minItems":2,"maxItems":4} - } - }' - ], - [ - '{ - "value":[2,2,5,8] - }', - '{ - "type":"object", - "properties":{ - "value":{"type":"array","minItems":2,"maxItems":4} - } - }' - ] + yield [ + '{ + "value":[2,2] + }', + '{ + "type":"object", + "properties":{ + "value":{"type":"array","minItems":2,"maxItems":4} + } + }' + ]; + yield [ + '{ + "value":[2,2,5,8] + }', + '{ + "type":"object", + "properties":{ + "value":{"type":"array","minItems":2,"maxItems":4} + } + }' ]; } } diff --git a/tests/Constraints/MinLengthMaxLengthMultiByteTest.php b/tests/Constraints/MinLengthMaxLengthMultiByteTest.php index ab6db1a3..38b2bc5e 100644 --- a/tests/Constraints/MinLengthMaxLengthMultiByteTest.php +++ b/tests/Constraints/MinLengthMaxLengthMultiByteTest.php @@ -1,16 +1,12 @@ [ - 'input' => '{ - "value": {} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "minProperties": 0} - } - }' - ], - 'Empty object with maxProperties: 1' => [ - 'input' => '{ - "value": {} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "maxProperties": 1} - } - }' - ], - 'Empty object with minProperties: 0 and maxProperties: 1' => [ - 'input' => '{ - "value": {} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "minProperties": 0,"maxProperties": 1} - } - }' - ], - 'Object with two properties with minProperties: 1 and maxProperties: 2' => [ - 'input' => '{ - "value": {"foo": 1, "bar": 2} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "minProperties": 1,"maxProperties": 2} - } - }' - ], - 'Empty array with minProperties: 1 and maxProperties: 2' => [ - 'input' => '{ - "value": [] - }', - 'schema' => '{ - "properties": { - "value": {"minProperties": 1,"maxProperties": 2} - } - }', - 'checkMode' => Constraint::CHECK_MODE_NORMAL, - ], - 'Array with two items with maxProperties: 1' => [ - 'input' => '{ - "value": [1, 2] - }', - 'schema' => '{ - "properties": { - "value": {"maxProperties": 1} - } - }' - ], + yield 'Empty object with minProperties: 0' => [ + 'input' => '{ + "value": {} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "minProperties": 0} + } + }' + ]; + yield 'Empty object with maxProperties: 1' => [ + 'input' => '{ + "value": {} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "maxProperties": 1} + } + }' + ]; + yield 'Empty object with minProperties: 0 and maxProperties: 1' => [ + 'input' => '{ + "value": {} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "minProperties": 0,"maxProperties": 1} + } + }' + ]; + yield 'Object with two properties with minProperties: 1 and maxProperties: 2' => [ + 'input' => '{ + "value": {"foo": 1, "bar": 2} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "minProperties": 1,"maxProperties": 2} + } + }' + ]; + yield 'Empty array with minProperties: 1 and maxProperties: 2' => [ + 'input' => '{ + "value": [] + }', + 'schema' => '{ + "properties": { + "value": {"minProperties": 1,"maxProperties": 2} + } + }', + 'checkMode' => Constraint::CHECK_MODE_NORMAL, + ]; + yield 'Array with two items with maxProperties: 1' => [ + 'input' => '{ + "value": [1, 2] + }', + 'schema' => '{ + "properties": { + "value": {"maxProperties": 1} + } + }' ]; } - /** - * {@inheritdoc} - */ - public function getInvalidTests(): array + public function getInvalidTests(): \Generator { - return [ - 'Empty object with minProperties: 1' => [ - 'input' => '{ - "value": {} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "minProperties": 1} - } - }' - ], - 'Empty object with minProperties' => [ - 'input' => '{}', - 'schema' => '{ - "type": "object", - "properties": { - "propertyOne": { - "type": "string" - }, - "propertyTwo": { - "type": "string" - } - }, - "minProperties": 1 - }' - ], - 'Object with two properties with maxProperties: 1' => [ - 'input' => '{ - "value": { - "propertyOne": "valueOne", - "propertyTwo": "valueTwo" - } - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "maxProperties": 1} - } - }' - ], - 'Object with two properties with minProperties: 1 and maxProperties: 2' => [ - 'input' => '{ - "value": {"foo": 1, "bar": 2, "baz": 3} - }', - 'schema' => '{ - "type": "object", - "properties": { - "value": {"type": "object", "minProperties": 1,"maxProperties": 2} - } - }' - ], + yield 'Empty object with minProperties: 1' => [ + 'input' => '{ + "value": {} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "minProperties": 1} + } + }' + ]; + yield 'Empty object with minProperties' => [ + 'input' => '{}', + 'schema' => '{ + "type": "object", + "properties": { + "propertyOne": { + "type": "string" + }, + "propertyTwo": { + "type": "string" + } + }, + "minProperties": 1 + }' + ]; + yield 'Object with two properties with maxProperties: 1' => [ + 'input' => '{ + "value": { + "propertyOne": "valueOne", + "propertyTwo": "valueTwo" + } + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "maxProperties": 1} + } + }' + ]; + yield 'Object with two properties with minProperties: 1 and maxProperties: 2' => [ + 'input' => '{ + "value": {"foo": 1, "bar": 2, "baz": 3} + }', + 'schema' => '{ + "type": "object", + "properties": { + "value": {"type": "object", "minProperties": 1,"maxProperties": 2} + } + }' ]; } } diff --git a/tests/Constraints/MinimumMaximumTest.php b/tests/Constraints/MinimumMaximumTest.php index 6f66565b..3573ed36 100644 --- a/tests/Constraints/MinimumMaximumTest.php +++ b/tests/Constraints/MinimumMaximumTest.php @@ -1,176 +1,168 @@ [ + '{"y": "foo"}', + '{ + "type": "object", + "required": ["x"], + "properties": { + "x": { + "not": { + "type": "null" } } - }' - ] + } + }' ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - '{ - "x": [1] - }', - '{ - "properties": { - "x": { - "not": { - "type": "array", - "items": {"type": "integer"}, - "minItems": 2 - } + yield [ + '{ + "x": [1] + }', + '{ + "properties": { + "x": { + "not": { + "type": "array", + "items": {"type": "integer"}, + "minItems": 2 } } - }' - ], - [ - '{ - "x": ["foo", 2] - }', - '{ - "properties": { - "x": { - "not": { - "type": "array", - "items": {"type": "integer"}, - "minItems": 2 - } + } + }' + ]; + yield [ + '{ + "x": ["foo", 2] + }', + '{ + "properties": { + "x": { + "not": { + "type": "array", + "items": {"type": "integer"}, + "minItems": 2 } } - }' - ], - [ // check that a missing, non-required property isn't validated - '{"y": "foo"}', - '{ - "type": "object", - "properties": { - "x": { - "not": { - "type": "null" - } + } + }' + ]; + yield "check that a missing, non-required property isn't validated" => [ + '{"y": "foo"}', + '{ + "type": "object", + "properties": { + "x": { + "not": { + "type": "null" } } - }' - ] + } + }' ]; } } diff --git a/tests/Constraints/NumberAndIntegerTypesTest.php b/tests/Constraints/NumberAndIntegerTypesTest.php index 78b02110..c09abee8 100644 --- a/tests/Constraints/NumberAndIntegerTypesTest.php +++ b/tests/Constraints/NumberAndIntegerTypesTest.php @@ -1,118 +1,110 @@ 'prop2', - 'pointer' => '/prop2', - 'message' => 'Array value found, but a string is required', - 'constraint' => [ - 'name' => 'type', - 'params' => [ - 'expected' => 'a string', - 'found' => 'array' - ] - ], - 'context' => Validator::ERROR_DOCUMENT_VALIDATION + 'property' => 'prop2', + 'pointer' => '/prop2', + 'message' => 'Array value found, but a string is required', + 'constraint' => [ + 'name' => 'type', + 'params' => [ + 'expected' => 'a string', + 'found' => 'array' + ] ], - [ - 'property' => 'prop2', - 'pointer' => '/prop2', - 'message' => 'Array value found, but a number is required', - 'constraint' => [ - 'name' => 'type', - 'params' => [ - 'expected' => 'a number', - 'found' => 'array' - ] - ], - 'context' => Validator::ERROR_DOCUMENT_VALIDATION + 'context' => Validator::ERROR_DOCUMENT_VALIDATION + ], + [ + 'property' => 'prop2', + 'pointer' => '/prop2', + 'message' => 'Array value found, but a number is required', + 'constraint' => [ + 'name' => 'type', + 'params' => [ + 'expected' => 'a number', + 'found' => 'array' + ] ], - [ - 'property' => 'prop2', - 'pointer' => '/prop2', - 'message' => 'Failed to match exactly one schema', - 'constraint' => [ - 'name' => 'oneOf', - 'params' => [] - ], - 'context' => Validator::ERROR_DOCUMENT_VALIDATION + 'context' => Validator::ERROR_DOCUMENT_VALIDATION + ], + [ + 'property' => 'prop2', + 'pointer' => '/prop2', + 'message' => 'Failed to match exactly one schema', + 'constraint' => [ + 'name' => 'oneOf', + 'params' => [] ], + 'context' => Validator::ERROR_DOCUMENT_VALIDATION ], ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "oneOf": [ - { - "type": "string", - "pattern": "^[a-z]*$" - }, - { - "type": "string", - "pattern": "^[A-Z]*$" - } - ] + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "oneOf": [ + { + "type": "string", + "pattern": "^[a-z]*$" + }, + { + "type": "string", + "pattern": "^[A-Z]*$" } - } - }' - ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "anyOf": [ - { - "type": "string", - "pattern": "^[A-Z]*$" - } - ] + ] + } + } + }' + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Z]*$" } - } - }' - ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^[A-Z]*$" - } - ] + ] + } + } + }' + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^[A-Z]*$" } - } - }' - ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "pattern": "^[A-Z]*$" - } - ] + ] + } + } + }' + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "pattern": "^[A-Z]*$" } - } - }' - ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "anyOf": [ - { - "type": "string", - "pattern": "^[a-z]*$" - }, - { - "type": "string", - "pattern": "^[A-Z]*$" - } - ] + ] + } + } + }' + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "anyOf": [ + { + "type": "string", + "pattern": "^[a-z]*$" + }, + { + "type": "string", + "pattern": "^[A-Z]*$" } - } - }' - ], - [ - '{"prop1": [1,2]}', - '{ - "type": "object", - "properties": { - "prop1": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "string" - } - ] + ] + } + } + }' + ]; + yield [ + '{"prop1": [1,2]}', + '{ + "type": "object", + "properties": { + "prop1": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" } - } - }' - ] + ] + } + } + }' ]; } public function testNoPrematureAnyOfException(): void { - $schema = json_decode('{ + $schema = json_decode( + '{ "type": "object", "properties": { "propertyOne": { @@ -244,8 +235,10 @@ public function testNoPrematureAnyOfException(): void ] } } - }'); - $data = json_decode('{"propertyOne":"ABC"}'); + }', + false + ); + $data = json_decode('{"propertyOne":"ABC"}', false); $v = new Validator(); $v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS); @@ -254,7 +247,8 @@ public function testNoPrematureAnyOfException(): void public function testNoPrematureOneOfException(): void { - $schema = json_decode('{ + $schema = json_decode( + '{ "type": "object", "properties": { "propertyOne": { @@ -264,8 +258,10 @@ public function testNoPrematureOneOfException(): void ] } } - }'); - $data = json_decode('{"propertyOne":"ABC"}'); + }', + false + ); + $data = json_decode('{"propertyOne":"ABC"}', false); $v = new Validator(); $v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS); diff --git a/tests/Constraints/PatternPropertiesTest.php b/tests/Constraints/PatternPropertiesTest.php index 526777ef..ca99fc47 100644 --- a/tests/Constraints/PatternPropertiesTest.php +++ b/tests/Constraints/PatternPropertiesTest.php @@ -1,214 +1,200 @@ [ - 'foobar' => 'foo', - 'barfoo' => 'bar', - ] - ]), - json_encode([ - 'type' => 'object', - 'patternProperties' => [ - '^someobject$' => [ - 'type' => 'object', - 'additionalProperties' => false, - 'properties' => [ - 'barfoo' => [ - 'type' => 'string', - ], - ] + yield 'matches pattern but invalid schema for object' => [ + json_encode([ + 'someobject' => [ + 'foobar' => 'foo', + 'barfoo' => 'bar', + ] + ]), + json_encode([ + 'type' => 'object', + 'patternProperties' => [ + '^someobject$' => [ + 'type' => 'object', + 'additionalProperties' => false, + 'properties' => [ + 'barfoo' => [ + 'type' => 'string', + ], ] ] - ]) - ], - // Does not match pattern - [ - json_encode([ - 'regex_us' => false, - ]), - json_encode([ - 'type' => 'object', - 'patternProperties' => [ - '^[a-z]+_(jp|de)$' => [ - 'type' => ['boolean'] - ] - ], - 'additionalProperties' => false - ]) - ], - // Does not match pattern with unicode - [ - json_encode([ - '猡猡獛' => false, - ]), - json_encode([ - 'type' => 'object', - 'patternProperties' => [ - '^[\\x{0080}-\\x{006FFF}]+$' => [ - 'type' => ['boolean'] - ] - ], - 'additionalProperties' => false - ]) - ], - // An invalid regular expression pattern - [ - json_encode([ - 'regex_us' => false, - ]), - json_encode([ - 'type' => 'object', - 'patternProperties' => [ - '^[a-z+_jp|de)$' => [ - 'type' => ['boolean'] - ] - ], - 'additionalProperties' => false - ]) - ], + ] + ]) + ]; + yield 'Does not match pattern' => [ + json_encode([ + 'regex_us' => false, + ]), + json_encode([ + 'type' => 'object', + 'patternProperties' => [ + '^[a-z]+_(jp|de)$' => [ + 'type' => ['boolean'] + ] + ], + 'additionalProperties' => false + ]) + ]; + yield 'Does not match pattern with unicode' => [ + json_encode([ + '猡猡獛' => false, + ]), + json_encode([ + 'type' => 'object', + 'patternProperties' => [ + '^[\\x{0080}-\\x{006FFF}]+$' => [ + 'type' => ['boolean'] + ] + ], + 'additionalProperties' => false + ]) + ]; + yield 'An invalid regular expression pattern' => [ + json_encode([ + 'regex_us' => false, + ]), + json_encode([ + 'type' => 'object', + 'patternProperties' => [ + '^[a-z+_jp|de)$' => [ + 'type' => ['boolean'] + ] + ], + 'additionalProperties' => false + ]) ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - // validates pattern schema - json_encode([ - 'someobject' => [ - 'foobar' => 'foo', - 'barfoo' => 'bar', - ], - 'someotherobject' => [ - 'foobar' => 1234, + [ + yield 'validates pattern schema' => json_encode([ + 'someobject' => [ + 'foobar' => 'foo', + 'barfoo' => 'bar', + ], + 'someotherobject' => [ + 'foobar' => 1234, + ], + '/products' => [ + 'get' => [] + ], + '#products' => [ + 'get' => [] + ], + '+products' => [ + 'get' => [] + ], + '~products' => [ + 'get' => [] + ], + '*products' => [ + 'get' => [] + ], + '%products' => [ + 'get' => [] + ] + ]), + json_encode([ + 'type' => 'object', + 'additionalProperties' => false, + 'patternProperties' => [ + '^someobject$' => [ + 'type' => 'object', + 'properties' => [ + 'foobar' => ['type' => 'string'], + 'barfoo' => ['type' => 'string'], + ], ], - '/products' => [ - 'get' => [] + '^someotherobject$' => [ + 'type' => 'object', + 'properties' => [ + 'foobar' => ['type' => 'number'], + ], ], - '#products' => [ - 'get' => [] + '^/' => [ + 'type' => 'object', + 'properties' => [ + 'get' => ['type' => 'array'] + ] ], - '+products' => [ - 'get' => [] + '^#' => [ + 'type' => 'object', + 'properties' => [ + 'get' => ['type' => 'array'] + ] ], - '~products' => [ - 'get' => [] + '^\+' => [ + 'type' => 'object', + 'properties' => [ + 'get' => ['type' => 'array'] + ] ], - '*products' => [ - 'get' => [] + '^~' => [ + 'type' => 'object', + 'properties' => [ + 'get' => ['type' => 'array'] + ] ], - '%products' => [ - 'get' => [] - ] - ]), - json_encode([ - 'type' => 'object', - 'additionalProperties' => false, - 'patternProperties' => [ - '^someobject$' => [ - 'type' => 'object', - 'properties' => [ - 'foobar' => ['type' => 'string'], - 'barfoo' => ['type' => 'string'], - ], - ], - '^someotherobject$' => [ - 'type' => 'object', - 'properties' => [ - 'foobar' => ['type' => 'number'], - ], - ], - '^/' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] - ], - '^#' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] - ], - '^\+' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] - ], - '^~' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] - ], - '^\*' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] - ], - '^%' => [ - 'type' => 'object', - 'properties' => [ - 'get' => ['type' => 'array'] - ] + '^\*' => [ + 'type' => 'object', + 'properties' => [ + 'get' => ['type' => 'array'] ] - ] - ]) - ], - [ - json_encode([ - 'foobar' => true, - 'regex_us' => 'foo', - 'regex_de' => 1234 - ]), - json_encode([ + ], + '^%' => [ 'type' => 'object', 'properties' => [ - 'foobar' => ['type' => 'boolean'] - ], - 'patternProperties' => [ - '^[a-z]+_(us|de)$' => [ - 'type' => ['string', 'integer'] - ] - ], - 'additionalProperties' => false - ]) - ], - // Does match pattern with unicode - [ - json_encode([ - 'ðæſ' => 'unicode', - ]), - json_encode([ + 'get' => ['type' => 'array'] + ] + ] + ] + ]) + ]; + yield [ + json_encode([ + 'foobar' => true, + 'regex_us' => 'foo', + 'regex_de' => 1234 + ]), + json_encode([ 'type' => 'object', + 'properties' => [ + 'foobar' => ['type' => 'boolean'] + ], 'patternProperties' => [ - '^[\\x{0080}-\\x{10FFFF}]+$' => [ - 'type' => ['string'] + '^[a-z]+_(us|de)$' => [ + 'type' => ['string', 'integer'] ] ], 'additionalProperties' => false - ]) - ], + ]) + ]; + yield 'Does match pattern with unicode' => [ + json_encode([ + 'ðæſ' => 'unicode', + ]), + json_encode([ + 'type' => 'object', + 'patternProperties' => [ + '^[\\x{0080}-\\x{10FFFF}]+$' => [ + 'type' => ['string'] + ] + ], + 'additionalProperties' => false + ]) ]; } } diff --git a/tests/Constraints/PatternTest.php b/tests/Constraints/PatternTest.php index 8207c91b..ee44d5fb 100644 --- a/tests/Constraints/PatternTest.php +++ b/tests/Constraints/PatternTest.php @@ -1,103 +1,95 @@ [ + '{ "number": [] }', + '{ + "type":"object", + "properties":{ + "number":{"type":"string","readonly":true} + } + }' ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - '{ - "number": "1.4" - }', - '{ - "type":"object", - "properties":{ - "number":{"type":"string","readonly":true} - } - }' - ] + yield [ + '{ + "number": "1.4" + }', + '{ + "type":"object", + "properties":{ + "number":{"type":"string","readonly":true} + } + }' ]; } } diff --git a/tests/Constraints/RequireTest.php b/tests/Constraints/RequireTest.php index 34ca88ca..614f6276 100644 --- a/tests/Constraints/RequireTest.php +++ b/tests/Constraints/RequireTest.php @@ -1,52 +1,44 @@ check($document, $schema); @@ -47,11 +42,7 @@ public function testErrorPropertyIsPopulatedForRequiredIfMissingInInput(): void public function testPathErrorPropertyIsPopulatedForRequiredIfMissingInInput(): void { $validator = new UndefinedConstraint(); - $document = json_decode( - '{ - "foo": [{"baz": 1.5}] - }' - ); + $document = json_decode('{ "foo": [{"baz": 1.5}] }', false); $schema = json_decode( '{ "type": "object", @@ -69,7 +60,8 @@ public function testPathErrorPropertyIsPopulatedForRequiredIfMissingInInput(): v } }, "required": ["foo"] - }' + }', + false ); $validator->check($document, $schema); @@ -80,21 +72,17 @@ public function testPathErrorPropertyIsPopulatedForRequiredIfMissingInInput(): v public function testErrorPropertyIsPopulatedForRequiredIfEmptyValueInInput(): void { $validator = new UndefinedConstraint(); - $document = json_decode( - '{ - "bar": 42, - "foo": null - }' - ); + $document = json_decode('{ "bar": 42, "foo": null }', false); $schema = json_decode( '{ - "type": "object", - "properties": { - "foo": {"type": "number"}, - "bar": {"type": "number"} - }, - "required": ["foo"] - }' + "type": "object", + "properties": { + "foo": {"type": "number"}, + "bar": {"type": "number"} + }, + "required": ["foo"] + }', + false ); $validator->check($document, $schema); @@ -113,329 +101,325 @@ protected function assertErrorHasExpectedPropertyValue($error, $propertyValue): $this->assertEquals($propertyValue, $error[0]['property']); } - public function getInvalidTests(): array + public function getInvalidTests(): \Generator { - return [ - [ - '{}', - '{ - "type":"object", - "properties":{ - "number":{"type":"number","required":true} - } - }' - ], - [ - '{}', - '{ - "type": "object", - "properties": { - "number": {"type": "number"} - }, - "required": ["number"] - }' - ], - [ - '{ - "foo": {} - }', - '{ - "type": "object", - "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number"} - }, - "required": ["bar"] - } - } - }' - ], - [ - '{ - "bar": 1.4 - }', - '{ - "type": "object", - "properties": { - "foo": {"type": "string", "required": true}, - "bar": {"type": "number"} - }, - "required": ["bar"] - }' - ], - [ - '{}', - '{ - "required": ["foo"] - }' - ], - [ - '{ - }', - '{ - "type": "object", - "properties": { - "foo": { "required": true } + yield [ + '{}', + '{ + "type":"object", + "properties":{ + "number":{"type":"number","required":true} + } + }' + ]; + yield [ + '{}', + '{ + "type": "object", + "properties": { + "number": {"type": "number"} + }, + "required": ["number"] + }' + ]; + yield [ + '{ + "foo": {} + }', + '{ + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": {"type": "number"} + }, + "required": ["bar"] } - }' - ], - [ - '{ - "string":{} - }', - '{ - "type":"object", - "properties": { - "string":{"type":"string", "required": true} - } - }' - ], - [ - '{ - "number":{} - }', - '{ - "type":"object", - "properties": { - "number":{"type":"number", "required": true} - } - }' - ], - [ - '{ - "integer":{} - }', - '{ - "type":"object", - "properties": { - "integer":{"type":"integer", "required": true} - } - }' - ], - [ - '{ - "boolean":{} - }', - '{ - "type":"object", - "properties": { - "boolean":{"type":"boolean", "required": true} - } - }' - ], - [ - '{ - "array":{} - }', - '{ - "type":"object", - "properties": { - "array":{"type":"array", "required": true} - } - }', - Constraint::CHECK_MODE_NORMAL - ], - [ - '{ - "null":{} - }', - '{ - "type":"object", - "properties": { - "null":{"type":"null", "required": true} - } - }' - ], - [ - '{ - "foo": {"baz": 1.5} - }', - '{ + } + }' + ]; + yield [ + '{ + "bar": 1.4 + }', + '{ + "type": "object", + "properties": { + "foo": {"type": "string", "required": true}, + "bar": {"type": "number"} + }, + "required": ["bar"] + }' + ]; + yield [ + '{}', + '{ + "required": ["foo"] + }' + ]; + yield [ + '{ + }', + '{ + "type": "object", + "properties": { + "foo": { "required": true } + } + }' + ]; + yield [ + '{ + "string":{} + }', + '{ + "type":"object", + "properties": { + "string":{"type":"string", "required": true} + } + }' + ]; + yield [ + '{ + "number":{} + }', + '{ + "type":"object", + "properties": { + "number":{"type":"number", "required": true} + } + }' + ]; + yield [ + '{ + "integer":{} + }', + '{ + "type":"object", + "properties": { + "integer":{"type":"integer", "required": true} + } + }' + ]; + yield [ + '{ + "boolean":{} + }', + '{ + "type":"object", + "properties": { + "boolean":{"type":"boolean", "required": true} + } + }' + ]; + yield [ + '{ + "array":{} + }', + '{ + "type":"object", + "properties": { + "array":{"type":"array", "required": true} + } + }', + Constraint::CHECK_MODE_NORMAL + ]; + yield [ + '{ + "null":{} + }', + '{ + "type":"object", + "properties": { + "null":{"type":"null", "required": true} + } + }' + ]; + yield [ + '{ + "foo": {"baz": 1.5} + }', + '{ + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number"} - }, - "required": ["bar"] - } - } - }' - ], - [ - '{ - "foo": {"baz": 1.5} - }', - '{ + "bar": {"type": "number"} + }, + "required": ["bar"] + } + } + }' + ]; + yield [ + '{ + "foo": {"baz": 1.5} + }', + '{ + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number", "required": true} - } - } + "bar": {"type": "number", "required": true} } - }' - ], + } + } + }' ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - [ - '{ - "number": 1.4 - }', - '{ - "type":"object", - "properties":{ - "number":{"type":"number","required":true} - } - }' - ], - [ - '{}', - '{ - "type":"object", - "properties":{ - "number":{"type":"number"} - } - }' - ], - [ - '{}', - '{ - "type":"object", - "properties":{ - "number":{"type":"number","required":false} - } - }' - ], - [ - '{ - "number": 0 - }', - '{ - "type":"object", - "properties":{ - "number":{"type":"integer","required":true} - } - }' - ], - [ - '{ - "is_active": false - }', - '{ - "type":"object", - "properties":{ - "is_active":{"type":"boolean","required":true} - } - }' - ], - [ - '{ - "status": null - }', - '{ - "type":"object", - "properties":{ - "status":{"type":"null","required":true} - } - }' - ], - [ - '{ - "users": [] - }', - '{ - "type":"object", - "properties":{ - "users":{"type":"array","required":true} - } - }' - ], - [ - '{ - "foo": "foo", - "bar": 1.4 - }', - '{ - "type": "object", - "properties": { - "foo": {"type": "string", "required": true}, - "bar": {"type": "number"} - }, - "required": ["bar"] - }' - ], - [ - '{ - "foo": {"bar": 1.5} - }', - '{ - "type": "object", - "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number"} - }, - "required": ["bar"] - } - }, - "required": ["foo"] - }' - ], - [ - '{ - "foo": {} - }', - '{ - "type": "object", - "properties": { - "foo": { "required": true } + yield [ + '{ + "number": 1.4 + }', + '{ + "type":"object", + "properties":{ + "number":{"type":"number","required":true} + } + }' + ]; + yield [ + '{}', + '{ + "type":"object", + "properties":{ + "number":{"type":"number"} + } + }' + ]; + yield [ + '{}', + '{ + "type":"object", + "properties":{ + "number":{"type":"number","required":false} + } + }' + ]; + yield [ + '{ + "number": 0 + }', + '{ + "type":"object", + "properties":{ + "number":{"type":"integer","required":true} + } + }' + ]; + yield [ + '{ + "is_active": false + }', + '{ + "type":"object", + "properties":{ + "is_active":{"type":"boolean","required":true} + } + }' + ]; + yield [ + '{ + "status": null + }', + '{ + "type":"object", + "properties":{ + "status":{"type":"null","required":true} + } + }' + ]; + yield [ + '{ + "users": [] + }', + '{ + "type":"object", + "properties":{ + "users":{"type":"array","required":true} + } + }' + ]; + yield [ + '{ + "foo": "foo", + "bar": 1.4 + }', + '{ + "type": "object", + "properties": { + "foo": {"type": "string", "required": true}, + "bar": {"type": "number"} + }, + "required": ["bar"] + }' + ]; + yield [ + '{ + "foo": {"bar": 1.5} + }', + '{ + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": {"type": "number"} + }, + "required": ["bar"] } - }' - ], - [ - '{ - "boo": {"bar": 1.5} - }', - '{ + }, + "required": ["foo"] + }' + ]; + yield [ + '{ + "foo": {} + }', + '{ + "type": "object", + "properties": { + "foo": { "required": true } + } + }' + ]; + yield [ + '{ + "boo": {"bar": 1.5} + }', + '{ + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number"} - }, - "required": ["bar"] - } - } - }' - ], - [ - '{ - "boo": {"bar": 1.5} - }', - '{ + "bar": {"type": "number"} + }, + "required": ["bar"] + } + } + }' + ]; + yield [ + '{ + "boo": {"bar": 1.5} + }', + '{ + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "bar": {"type": "number", "required": true} - } - } + "bar": {"type": "number", "required": true} } - }' - ], + } + } + }' ]; } } diff --git a/tests/Constraints/SchemaValidationTest.php b/tests/Constraints/SchemaValidationTest.php index 65268f49..e7b41967 100644 --- a/tests/Constraints/SchemaValidationTest.php +++ b/tests/Constraints/SchemaValidationTest.php @@ -1,11 +1,6 @@ expectException('\JsonSchema\Exception\RuntimeException'); + $this->expectException(\JsonSchema\Exception\RuntimeException::class); $this->expectExceptionMessage('Cannot validate the schema of a non-object'); $this->testValidCases('"notAnObject"'); @@ -110,7 +105,7 @@ public function testNonObjectSchema(): void public function testInvalidSchemaException(): void { - $this->expectException('\JsonSchema\Exception\InvalidSchemaException'); + $this->expectException(\JsonSchema\Exception\InvalidSchemaException::class); $this->expectExceptionMessage('Schema did not pass validation'); $input = json_decode('{}'); diff --git a/tests/Constraints/SelfDefinedSchemaTest.php b/tests/Constraints/SelfDefinedSchemaTest.php index 4ac1b8a7..f23baa1c 100644 --- a/tests/Constraints/SelfDefinedSchemaTest.php +++ b/tests/Constraints/SelfDefinedSchemaTest.php @@ -1,80 +1,74 @@ expectException('\JsonSchema\Exception\InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $v->validate($value, $schema); } diff --git a/tests/Constraints/TupleTypingTest.php b/tests/Constraints/TupleTypingTest.php index f565ae00..3c84c3d0 100644 --- a/tests/Constraints/TupleTypingTest.php +++ b/tests/Constraints/TupleTypingTest.php @@ -1,140 +1,132 @@ - */ class TypeTest extends TestCase { /** @@ -133,7 +121,7 @@ public function testValidateTypeException(): void $data = new \stdClass(); $schema = json_decode('{"type": "notAValidTypeName"}'); - $this->expectException('JsonSchema\Exception\InvalidArgumentException'); + $this->expectException(\JsonSchema\Exception\InvalidArgumentException::class); $this->expectExceptionMessage('object is an invalid type for notAValidTypeName'); $t->check($data, $schema); diff --git a/tests/Constraints/UndefinedConstraintTest.php b/tests/Constraints/UndefinedConstraintTest.php index 7e66a60b..d6fb2f2f 100644 --- a/tests/Constraints/UndefinedConstraintTest.php +++ b/tests/Constraints/UndefinedConstraintTest.php @@ -8,162 +8,134 @@ class UndefinedConstraintTest extends BaseTestCase { - /** - * @return array{} - */ - public function getInvalidTests(): array + public function getInvalidTests(): \Generator { - return []; + yield from []; } - /** - * @return array - */ - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - 'oneOf with type coercion should not affect value passed to each sub schema (#790)' => [ - 'input' => << [ + 'input' => '{ + "id": "LOC1", + "related_locations": [ { - "id": "LOC1", - "related_locations": [ - { - "latitude": "51.047598", - "longitude": "3.729943" - } - ] + "latitude": "51.047598", + "longitude": "3.729943" } -JSON - , - 'schema' => << '{ + "title": "Location", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "related_locations": { + "oneOf": [ + { + "type": "null" }, - "related_locations": { - "oneOf": [ - { - "type": "null" - }, - { - "type": "array", - "items": { - "type": "object", - "properties": { - "latitude": { - "type": "string" - }, - "longitude": { - "type": "string" - } - } + { + "type": "array", + "items": { + "type": "object", + "properties": { + "latitude": { + "type": "string" + }, + "longitude": { + "type": "string" } } - ] + } } - } + ] } -JSON - , - 'checkMode' => Constraint::CHECK_MODE_COERCE_TYPES - ], - 'oneOf with apply defaults should not affect value passed to each sub schema (#510)' => [ - 'input' => << << Constraint::CHECK_MODE_COERCE_TYPES + ]; + yield 'oneOf with apply defaults should not affect value passed to each sub schema (#510)' => [ + 'input' => '{"foo": {"name": "bar"}}', + 'schema' => '{ + "oneOf": [ { - "oneOf": [ - { + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "name": {"enum":["baz"],"default":"baz"}, - "meta": {"enum":["baz"],"default":"baz"} - } - } + "name": {"enum":["baz"],"default":"baz"}, + "meta": {"enum":["baz"],"default":"baz"} } - }, - { + } + } + }, + { + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "name": {"enum":["bar"],"default":"bar"}, - "meta": {"enum":["bar"],"default":"bar"} - } - } + "name": {"enum":["bar"],"default":"bar"}, + "meta": {"enum":["bar"],"default":"bar"} } - }, - { + } + } + }, + { + "type": "object", + "properties": { + "foo": { "type": "object", "properties": { - "foo": { - "type": "object", - "properties": { - "name": {"enum":["zip"],"default":"zip"}, - "meta": {"enum":["zip"],"default":"zip"} - } - } + "name": {"enum":["zip"],"default":"zip"}, + "meta": {"enum":["zip"],"default":"zip"} } } - ] + } } -JSON - , - 'checkMode' => Constraint::CHECK_MODE_APPLY_DEFAULTS - ], - 'anyOf with apply defaults should not affect value passed to each sub schema (#711)' => [ - 'input' => << Constraint::CHECK_MODE_APPLY_DEFAULTS + ]; + yield 'anyOf with apply defaults should not affect value passed to each sub schema (#711)' => [ + 'input' => '{ "b": 2 }', + 'schema' => '{ + "anyOf": [ + { + "required": [ "a" ], + "pro": { + "a": { + "type": "integer" + }, + "aDefault": { + "type": "integer", + "default": 1 } -JSON - , - 'schema' => << Constraint::CHECK_MODE_APPLY_DEFAULTS - ] + ] + }', + 'checkMode' => Constraint::CHECK_MODE_APPLY_DEFAULTS ]; } } diff --git a/tests/Constraints/UnionTypesTest.php b/tests/Constraints/UnionTypesTest.php index 387848df..7dc87e71 100644 --- a/tests/Constraints/UnionTypesTest.php +++ b/tests/Constraints/UnionTypesTest.php @@ -1,53 +1,45 @@ [ - 'input' => '[1,2,2]', - 'schema' => '{ - "type":"array", - "uniqueItems": true - }' - ], - 'Non unique objects' => [ - 'input' => '[{"a":"b"},{"a":"c"},{"a":"b"}]', - 'schema' => '{ - "type":"array", - "uniqueItems": true - }' - ], - 'Non unique objects - three levels deep' => [ - 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}}]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Non unique mathematical values for the number one' => [ - 'input' => '[1.0, 1.00, 1]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Non unique arrays' => [ - 'input' => '[["foo"], ["foo"]]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Non unique mix of different types' => [ - 'input' => '[{}, [1], true, null, {}, 1]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'objects are non-unique despite key order' => [ - 'input' => '[{"a": 1, "b": 2}, {"b": 2, "a": 1}]', - 'schema' => '{"uniqueItems": true}', - ] + yield 'Non unique integers' => [ + 'input' => '[1,2,2]', + 'schema' => '{ + "type":"array", + "uniqueItems": true + }' + ]; + yield 'Non unique objects' => [ + 'input' => '[{"a":"b"},{"a":"c"},{"a":"b"}]', + 'schema' => '{ + "type":"array", + "uniqueItems": true + }' + ]; + yield 'Non unique objects - three levels deep' => [ + 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}}]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Non unique mathematical values for the number one' => [ + 'input' => '[1.0, 1.00, 1]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Non unique arrays' => [ + 'input' => '[["foo"], ["foo"]]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Non unique mix of different types' => [ + 'input' => '[{}, [1], true, null, {}, 1]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'objects are non-unique despite key order' => [ + 'input' => '[{"a": 1, "b": 2}, {"b": 2, "a": 1}]', + 'schema' => '{"uniqueItems": true}', ]; } - public function getValidTests(): array + public function getValidTests(): \Generator { - return [ - 'unique integers' => [ - 'input' => '[1,2,3]', - 'schema' => '{ - "type":"array", - "uniqueItems": true - }' - ], - 'unique objects' =>[ - 'input' => '[{"foo": 12}, {"bar": false}]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Integer one and boolean true' => [ - 'input' => '[1, true]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Integer zero and boolean false' => [ - 'input' => '[0, false]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Objects with different value three levels deep' => [ - 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}}]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Array of strings' => [ - 'input' => '[["foo"], ["bar"]]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - 'Object, Array, boolean, null and integer' => [ - 'input' => '[{}, [1], true, null, 1]', - 'schema' => '{ - "type": "array", - "uniqueItems": true - }' - ], - // below equals the invalid tests, but with uniqueItems set to false - 'Non unique integers' => [ - 'input' => '[1,2,2]', - 'schema' => '{ - "type":"array", - "uniqueItems": false - }' - ], - 'Non unique objects' => [ - 'input' => '[{"a":"b"},{"a":"c"},{"a":"b"}]', - 'schema' => '{ - "type":"array", - "uniqueItems": false - }' - ], - 'Non unique objects - three levels deep' => [ - 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}}]', - 'schema' => '{ - "type": "array", - "uniqueItems": false - }' - ], - 'Non unique mathematical values for the number one' => [ - 'input' => '[1.0, 1.00, 1]', - 'schema' => '{ - "type": "array", - "uniqueItems": false - }' - ], - 'Non unique arrays' => [ - 'input' => '[["foo"], ["foo"]]', - 'schema' => '{ - "type": "array", - "uniqueItems": false - }' - ], - 'Non unique mix of different types' => [ - 'input' => '[{}, [1], true, null, {}, 1]', - 'schema' => '{ - "type": "array", - "uniqueItems": false - }' - ] + yield 'unique integers' => [ + 'input' => '[1,2,3]', + 'schema' => '{ + "type":"array", + "uniqueItems": true + }' + ]; + yield 'unique objects' =>[ + 'input' => '[{"foo": 12}, {"bar": false}]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Integer one and boolean true' => [ + 'input' => '[1, true]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Integer zero and boolean false' => [ + 'input' => '[0, false]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Objects with different value three levels deep' => [ + 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : false}}}]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Array of strings' => [ + 'input' => '[["foo"], ["bar"]]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + yield 'Object, Array, boolean, null and integer' => [ + 'input' => '[{}, [1], true, null, 1]', + 'schema' => '{ + "type": "array", + "uniqueItems": true + }' + ]; + // below equals the invalid tests, but with uniqueItems set to false + yield 'Non unique integers' => [ + 'input' => '[1,2,2]', + 'schema' => '{ + "type":"array", + "uniqueItems": false + }' + ]; + yield 'Non unique objects' => [ + 'input' => '[{"a":"b"},{"a":"c"},{"a":"b"}]', + 'schema' => '{ + "type":"array", + "uniqueItems": false + }' + ]; + yield 'Non unique objects - three levels deep' => [ + 'input' => '[{"foo": {"bar" : {"baz" : true}}}, {"foo": {"bar" : {"baz" : true}}}]', + 'schema' => '{ + "type": "array", + "uniqueItems": false + }' + ]; + yield 'Non unique mathematical values for the number one' => [ + 'input' => '[1.0, 1.00, 1]', + 'schema' => '{ + "type": "array", + "uniqueItems": false + }' + ]; + yield 'Non unique arrays' => [ + 'input' => '[["foo"], ["foo"]]', + 'schema' => '{ + "type": "array", + "uniqueItems": false + }' + ]; + yield 'Non unique mix of different types' => [ + 'input' => '[{}, [1], true, null, {}, 1]', + 'schema' => '{ + "type": "array", + "uniqueItems": false + }' ]; } } diff --git a/tests/Constraints/ValidationExceptionTest.php b/tests/Constraints/ValidationExceptionTest.php index ac6d973d..bb0fd162 100644 --- a/tests/Constraints/ValidationExceptionTest.php +++ b/tests/Constraints/ValidationExceptionTest.php @@ -1,11 +1,6 @@ assertInstanceOf('\JsonSchema\Exception\ValidationException', $exception); + $this->assertInstanceOf(\JsonSchema\Exception\ValidationException::class, $exception); $checkValue = json_decode('{"propertyOne": "thisIsNotAnObject"}'); $schema = json_decode('{ @@ -45,7 +40,7 @@ public function testValidationException(): void $exception->getMessage() ); - $this->expectException('JsonSchema\Exception\ValidationException'); + $this->expectException(\JsonSchema\Exception\ValidationException::class); throw $exception; } } diff --git a/tests/Constraints/WrongMessagesFailingTestCaseTest.php b/tests/Constraints/WrongMessagesFailingTestCaseTest.php index e36f57ce..6ed20e56 100644 --- a/tests/Constraints/WrongMessagesFailingTestCaseTest.php +++ b/tests/Constraints/WrongMessagesFailingTestCaseTest.php @@ -1,53 +1,45 @@ setUpTests(false); + yield from $this->setUpTests(false); } - public function getValidTests(): array + public function getValidTests(): \Generator { - return $this->setUpTests(true); + yield from $this->setUpTests(true); } /** diff --git a/tests/Drafts/Draft3Test.php b/tests/Drafts/Draft3Test.php index bebc6eaf..4ed6f76c 100644 --- a/tests/Drafts/Draft3Test.php +++ b/tests/Drafts/Draft3Test.php @@ -1,11 +1,6 @@ $testcase) { + if (in_array($name, $skip, true)) { + continue; + } + yield $name => $testcase; + } } - public function getValidForAssocTests(): array + public function getValidForAssocTests(): \Generator { - $tests = parent::getValidForAssocTests(); - unset( - $tests['type.json / object type matches objects / an array is not an object'], - $tests['type.json / array type matches arrays / an object is not an array'] - ); + $skip = [ + 'type.json / object type matches objects / an array is not an object', + 'type.json / array type matches arrays / an object is not an array', + ]; - return $tests; + foreach (parent::getValidForAssocTests() as $name => $testcase) { + if (in_array($name, $skip, true)) { + continue; + } + yield $name => $testcase; + } } /** diff --git a/tests/Drafts/Draft4Test.php b/tests/Drafts/Draft4Test.php index 16c73b45..dbf1354a 100644 --- a/tests/Drafts/Draft4Test.php +++ b/tests/Drafts/Draft4Test.php @@ -1,17 +1,9 @@ $testcase) { + if (in_array($name, $skip, true)) { + continue; + } + yield $name => $testcase; + } } - public function getValidForAssocTests(): array + public function getValidForAssocTests(): \Generator { - $tests = parent::getValidForAssocTests(); - unset( - $tests['type.json / object type matches objects / an array is not an object'], - $tests['type.json / array type matches arrays / an object is not an array'] - ); + $skip = [ + 'type.json / object type matches objects / an array is not an object', + 'type.json / array type matches arrays / an object is not an array', + ]; - return $tests; + foreach (parent::getValidForAssocTests() as $name => $testcase) { + if (in_array($name, $skip, true)) { + continue; + } + yield $name => $testcase; + } } /** diff --git a/tests/Entity/JsonPointerTest.php b/tests/Entity/JsonPointerTest.php index cb27c68e..f6be6621 100644 --- a/tests/Entity/JsonPointerTest.php +++ b/tests/Entity/JsonPointerTest.php @@ -2,24 +2,12 @@ declare(strict_types=1); -/* - * This file is part of the JsonSchema package. - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace JsonSchema\Tests\Entity; use JsonSchema\Entity\JsonPointer; use JsonSchema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; -/** - * @package JsonSchema\Tests\Entity - * - * @author Joost Nijhuis - */ class JsonPointerTest extends TestCase { /** diff --git a/tests/Exception/InvalidArgumentExceptionTest.php b/tests/Exception/InvalidArgumentExceptionTest.php index 01243760..12b72a7a 100644 --- a/tests/Exception/InvalidArgumentExceptionTest.php +++ b/tests/Exception/InvalidArgumentExceptionTest.php @@ -1,5 +1,7 @@ testObject); - $this->assertInstanceOf('\JsonSchema\Iterator\ObjectIterator', $i); + $this->assertInstanceOf(\JsonSchema\Iterator\ObjectIterator::class, $i); } public function testInitialState(): void diff --git a/tests/RefTest.php b/tests/RefTest.php index 3b66d586..574fe9ca 100644 --- a/tests/RefTest.php +++ b/tests/RefTest.php @@ -1,11 +1,6 @@ getMainSchema(); $mainSchemaPath = 'http://www.example.com/schema.json'; - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(\JsonSchema\UriRetrieverInterface::class); $uriRetriever->retrieve($mainSchemaPath)->willReturn($mainSchema)->shouldBeCalled(); $schemaStorage = new SchemaStorage($uriRetriever->reveal()); @@ -55,7 +50,7 @@ public function testSchemaWithLocalAndExternalReferencesWithCircularReference(): $schema3Path = 'http://www.my-domain.com/schema3.json'; /** @var UriRetriever $uriRetriever */ - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(\JsonSchema\UriRetrieverInterface::class); $uriRetriever->retrieve($mainSchemaPath)->willReturn($mainSchema)->shouldBeCalled(); $uriRetriever->retrieve($schema2Path)->willReturn($schema2)->shouldBeCalled(); $uriRetriever->retrieve($schema3Path)->willReturn($schema3)->shouldBeCalled(); @@ -102,13 +97,13 @@ public function testSchemaWithLocalAndExternalReferencesWithCircularReference(): public function testUnresolvableJsonPointExceptionShouldBeThrown(): void { - $this->expectException('JsonSchema\Exception\UnresolvableJsonPointerException'); + $this->expectException(\JsonSchema\Exception\UnresolvableJsonPointerException::class); $this->expectExceptionMessage('File: http://www.example.com/schema.json is found, but could not resolve fragment: #/definitions/car'); $mainSchema = $this->getInvalidSchema(); $mainSchemaPath = 'http://www.example.com/schema.json'; - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(\JsonSchema\UriRetrieverInterface::class); $uriRetriever->retrieve($mainSchemaPath) ->willReturn($mainSchema) ->shouldBeCalled(); @@ -119,7 +114,7 @@ public function testUnresolvableJsonPointExceptionShouldBeThrown(): void public function testResolveRefWithNoAssociatedFileName(): void { - $this->expectException('JsonSchema\Exception\UnresolvableJsonPointerException'); + $this->expectException(\JsonSchema\Exception\UnresolvableJsonPointerException::class); $this->expectExceptionMessage("Could not resolve fragment '#': no file is defined"); $schemaStorage = new SchemaStorage(); @@ -264,14 +259,14 @@ public function testGetUriRetriever(): void { $s = new SchemaStorage(); $s->addSchema('http://json-schema.org/draft-04/schema#'); - $this->assertInstanceOf('\JsonSchema\Uri\UriRetriever', $s->getUriRetriever()); + $this->assertInstanceOf(\JsonSchema\Uri\UriRetriever::class, $s->getUriRetriever()); } public function testGetUriResolver(): void { $s = new SchemaStorage(); $s->addSchema('http://json-schema.org/draft-04/schema#'); - $this->assertInstanceOf('\JsonSchema\Uri\UriResolver', $s->getUriResolver()); + $this->assertInstanceOf(\JsonSchema\Uri\UriResolver::class, $s->getUriResolver()); } public function testMetaSchemaFixes(): void @@ -291,7 +286,7 @@ public function testNoDoubleResolve(): void { $schemaOne = json_decode('{"id": "test/schema", "$ref": "../test2/schema2"}'); - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(\JsonSchema\UriRetrieverInterface::class); $uriRetriever->retrieve('test/schema')->willReturn($schemaOne)->shouldBeCalled(); $s = new SchemaStorage($uriRetriever->reveal()); diff --git a/tests/Uri/Retrievers/CurlTest.php b/tests/Uri/Retrievers/CurlTest.php index 5715773d..c2c88067 100644 --- a/tests/Uri/Retrievers/CurlTest.php +++ b/tests/Uri/Retrievers/CurlTest.php @@ -1,5 +1,7 @@ expectException('\JsonSchema\Exception\ResourceNotFoundException'); + $this->expectException(\JsonSchema\Exception\ResourceNotFoundException::class); $this->expectExceptionMessage('JSON schema not found'); $c->retrieve(__DIR__ . '/notARealFile'); diff --git a/tests/Uri/Retrievers/FileGetContentsTest.php b/tests/Uri/Retrievers/FileGetContentsTest.php index 57e6c90a..d48d7945 100644 --- a/tests/Uri/Retrievers/FileGetContentsTest.php +++ b/tests/Uri/Retrievers/FileGetContentsTest.php @@ -1,13 +1,12 @@ createMock('JsonSchema\Uri\UriRetriever'); + $retriever = $this->createMock(\JsonSchema\Uri\UriRetriever::class); $retriever->expects($this->at(0)) ->method('retrieve') @@ -235,7 +227,7 @@ public function testResolveExcessLevelUp(): void public function testConfirmMediaTypeAcceptsJsonSchemaType(): void { - $uriRetriever = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $uriRetriever = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $retriever = new UriRetriever(); $uriRetriever->expects($this->at(0)) @@ -247,7 +239,7 @@ public function testConfirmMediaTypeAcceptsJsonSchemaType(): void public function testConfirmMediaTypeAcceptsJsonType(): void { - $uriRetriever = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $uriRetriever = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $retriever = new UriRetriever(); $uriRetriever->expects($this->at(0)) @@ -259,7 +251,7 @@ public function testConfirmMediaTypeAcceptsJsonType(): void public function testConfirmMediaTypeThrowsExceptionForUnsupportedTypes(): void { - $uriRetriever = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $uriRetriever = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $retriever = new UriRetriever(); $uriRetriever->expects($this->at(0)) ->method('getContentType') @@ -274,11 +266,11 @@ private function mockRetriever($schema): void { $retrieverMock = $this->getRetrieverMock($schema); - $factory = new \ReflectionProperty('JsonSchema\Constraints\BaseConstraint', 'factory'); + $factory = new \ReflectionProperty(\JsonSchema\Constraints\BaseConstraint::class, 'factory'); $factory->setAccessible(true); $factory = $factory->getValue($this->validator); - $retriever = new \ReflectionProperty('JsonSchema\Constraints\Factory', 'uriRetriever'); + $retriever = new \ReflectionProperty(\JsonSchema\Constraints\Factory::class, 'uriRetriever'); $retriever->setAccessible(true); $retriever->setValue($factory, $retrieverMock); } @@ -333,7 +325,7 @@ public function testRetrieveSchemaFromPackage(): void public function testInvalidContentTypeEndpointsDefault(): void { - $mock = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $mock = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); @@ -343,7 +335,7 @@ public function testInvalidContentTypeEndpointsDefault(): void public function testInvalidContentTypeEndpointsUnknown(): void { - $mock = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $mock = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); @@ -353,7 +345,7 @@ public function testInvalidContentTypeEndpointsUnknown(): void public function testInvalidContentTypeEndpointsAdded(): void { - $mock = $this->createMock('JsonSchema\Uri\Retrievers\UriRetrieverInterface'); + $mock = $this->createMock(\JsonSchema\Uri\Retrievers\UriRetrieverInterface::class); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); $retriever->addInvalidContentTypeEndpoint('http://example.com'); @@ -386,7 +378,7 @@ public function testLoadSchemaJSONDecodingException(): void { $retriever = new UriRetriever(); - $this->expectException('JsonSchema\Exception\JsonDecodingException'); + $this->expectException(\JsonSchema\Exception\JsonDecodingException::class); $this->expectExceptionMessage('JSON syntax is malformed'); $retriever->retrieve('package://tests/fixtures/bad-syntax.json'); diff --git a/tests/ValidatorTest.php b/tests/ValidatorTest.php index 06eabc89..6c4d13af 100644 --- a/tests/ValidatorTest.php +++ b/tests/ValidatorTest.php @@ -1,5 +1,7 @@