diff --git a/.php_cs.dist b/.php_cs.dist index 0b5e2b2c..5a7a578e 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -21,8 +21,11 @@ $config 'phpdoc_order' => true, 'phpdoc_summary' => false, 'pre_increment' => false, + 'increment_style' => false, 'simplified_null_return' => false, 'trailing_comma_in_multiline_array' => false, + 'yoda_style' => false, + 'phpdoc_types_order' => array('null_adjustment' => 'none', 'sort_algorithm' => 'none'), )) ->setFinder($finder) ; diff --git a/.travis.yml b/.travis.yml index 3b4f5fc1..be79e9fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,12 +12,17 @@ matrix: - php: 5.3 dist: precise - php: 5.4 + dist: trusty - php: 5.5 + dist: trusty - php: 5.6 - php: 7.0 - env: WITH_COVERAGE=true WITH_PHPCSFIXER=true + env: WITH_COVERAGE=true + - php: 7.0 + env: WITH_PHPCSFIXER=true - php: 7.1 - php: 7.2 + - php: 7.3 - php: 'nightly' - php: hhvm dist: trusty diff --git a/composer.json b/composer.json index 20e85fc3..884a6971 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "php": ">=5.3.3" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20", + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", "json-schema/JSON-Schema-Test-Suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, diff --git a/src/JsonSchema/Constraints/UndefinedConstraint.php b/src/JsonSchema/Constraints/UndefinedConstraint.php index 257db155..e194cb0e 100644 --- a/src/JsonSchema/Constraints/UndefinedConstraint.php +++ b/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -150,6 +150,12 @@ protected function validateCommonProperties(&$value, $schema = null, JsonPointer 'required' ); } + } else { + // If the value is both undefined and not required, skip remaining checks + // in this method which assume an actual, defined instance when validating. + if ($value instanceof self) { + return; + } } } diff --git a/src/JsonSchema/Validator.php b/src/JsonSchema/Validator.php index 448091cd..431b3781 100644 --- a/src/JsonSchema/Validator.php +++ b/src/JsonSchema/Validator.php @@ -34,9 +34,7 @@ class Validator extends BaseConstraint * Both the php object and the schema are supposed to be a result of a json_decode call. * The validation works as defined by the schema proposal in http://json-schema.org. * - * Note that the first argument is passwd by reference, so you must pass in a variable. - * - * {@inheritdoc} + * Note that the first argument is passed by reference, so you must pass in a variable. */ public function validate(&$value, $schema = null, $checkMode = null) { diff --git a/tests/Constraints/ArraysTest.php b/tests/Constraints/ArraysTest.php index dac14358..63b97bf1 100644 --- a/tests/Constraints/ArraysTest.php +++ b/tests/Constraints/ArraysTest.php @@ -71,6 +71,51 @@ public function getInvalidTests() } } }' + ), + array( // Test array items.enum where type string fail validation if value(s) is/are not in items.enum + '{"data": ["a", "b"]}', + '{ + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string", + "enum": ["b", "c"] + } + } + } + }' + ), + array( // Test array items.enum where type integer fail validation if value(s) is/are not in items.enum + '{"data": [1, 2]}', + '{ + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer", + "enum": [2, 3] + } + } + } + }' + ), + array( // 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", + "properties": { + "data": { + "type": "array", + "items": { + "type": "number", + "enum": [1.25, 2] + } + } + } + }' ) ); } @@ -168,6 +213,51 @@ public function getValidTests() } } }' + ), + array( // Test array items.enum where type string passes validation if value(s) is/are in items.enum + '{"data": ["c", "c", "b"]}', + '{ + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string", + "enum": ["b", "c"] + } + } + } + }' + ), + array( // Test array items.enum where type integer passes validation if value(s) is/are in items.enum + '{"data": [1, 1, 2]}', + '{ + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer", + "enum": [1, 2] + } + } + } + }' + ), + array( // 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", + "properties": { + "data": { + "type": "array", + "items": { + "type": "number", + "enum": [1.25, 2.25] + } + } + } + }' ) ); } diff --git a/tests/Constraints/NotTest.php b/tests/Constraints/NotTest.php index 3a950f57..6183f684 100644 --- a/tests/Constraints/NotTest.php +++ b/tests/Constraints/NotTest.php @@ -31,6 +31,20 @@ public function getInvalidTests() } } }' + ), + array( // check that a missing, required property is correctly validated + '{"y": "foo"}', + '{ + "type": "object", + "required": ["x"], + "properties": { + "x": { + "not": { + "type": "null" + } + } + } + }' ) ); } @@ -69,6 +83,19 @@ public function getValidTests() } } }' + ), + array( // check that a missing, non-required property isn't validated + '{"y": "foo"}', + '{ + "type": "object", + "properties": { + "x": { + "not": { + "type": "null" + } + } + } + }' ) ); }