diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e1582d..5dc32e7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Update test case to current (PHP) standards ([#831](https://github.com/jsonrainbow/json-schema/pull/831)) ## [6.4.2] - 2025-06-03 ### Fixed diff --git a/dist/schema/json-schema-draft-06.json b/dist/schema/json-schema-draft-06.json new file mode 100644 index 00000000..bd3e763b --- /dev/null +++ b/dist/schema/json-schema-draft-06.json @@ -0,0 +1,155 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "http://json-schema.org/draft-06/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [ + { "$ref": "#/definitions/nonNegativeInteger" }, + { "default": 0 } + ] + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "uniqueItems": true, + "default": [] + } + }, + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": {}, + "examples": { + "type": "array", + "items": {} + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, + "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { "$ref": "#" }, + "items": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } + ], + "default": {} + }, + "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, + "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": { "$ref": "#" }, + "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, + "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { "$ref": "#" }, + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "propertyNames": { "format": "regex" }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } + }, + "propertyNames": { "$ref": "#" }, + "const": {}, + "enum": { + "type": "array", + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": { "type": "string" }, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "default": {} +} diff --git a/tests/Constraints/ArraysTest.php b/tests/Constraints/ArraysTest.php index 9c63982e..aac3fc7f 100644 --- a/tests/Constraints/ArraysTest.php +++ b/tests/Constraints/ArraysTest.php @@ -272,16 +272,6 @@ public function getValidTests(): array } }' ], - 'items: true passes validation' => [ - 'input' => << << $checkMode */ - public function testInvalidCases($input, $schema, $checkMode = Constraint::CHECK_MODE_NORMAL, $errors = []): void + public function testInvalidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL, array $errors = []): void { - $checkMode = $checkMode === null ? Constraint::CHECK_MODE_NORMAL : $checkMode; + $checkMode = $checkMode ?? Constraint::CHECK_MODE_NORMAL; 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->assertTrue((bool) ($errorMask & Validator::ERROR_DOCUMENT_VALIDATION)); diff --git a/tests/Constraints/ConstTest.php b/tests/Constraints/ConstTest.php index d9801906..ec4f688d 100644 --- a/tests/Constraints/ConstTest.php +++ b/tests/Constraints/ConstTest.php @@ -121,7 +121,7 @@ public function getValidTests(): array "type": "object", "properties": { "value": { - "type": "any", + "type": "object", "const": { "foo": 12 } diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index ea018bda..55d0672d 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -2,80 +2,73 @@ 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\Constraints; +use JsonSchema\UriRetrieverInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; +use stdClass; -/** - * @package JsonSchema\Tests\Constraints - */ abstract class VeryBaseTestCase extends TestCase { - /** @var object */ - private $jsonSchemaDraft03; + private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/'; + private const TEST_SUITE_REMOTES = __DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes'; - /** @var object */ - private $jsonSchemaDraft04; + /** @var array */ + private $draftSchemas = []; protected function getUriRetrieverMock(?object $schema): object { - $relativeTestsRoot = realpath(__DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes'); - - $jsonSchemaDraft03 = $this->getJsonSchemaDraft03(); - $jsonSchemaDraft04 = $this->getJsonSchemaDraft04(); - - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(UriRetrieverInterface::class); $uriRetriever->retrieve('http://www.my-domain.com/schema.json') ->willReturn($schema) ->shouldBeCalled(); + $that = $this; $uriRetriever->retrieve(Argument::any()) - ->will(function ($args) use ($jsonSchemaDraft03, $jsonSchemaDraft04, $relativeTestsRoot) { - if ('http://json-schema.org/draft-03/schema' === $args[0]) { - return $jsonSchemaDraft03; - } elseif ('http://json-schema.org/draft-04/schema' === $args[0]) { - return $jsonSchemaDraft04; - } elseif (0 === strpos($args[0], 'http://localhost:1234')) { - $urlParts = parse_url($args[0]); - - return json_decode(file_get_contents($relativeTestsRoot . $urlParts['path'])); - } elseif (0 === strpos($args[0], 'http://www.my-domain.com')) { - $urlParts = parse_url($args[0]); - - return json_decode(file_get_contents($relativeTestsRoot . '/folder' . $urlParts['path'])); + ->will(function ($args) use ($that): stdClass { + if (strpos($args[0], 'http://json-schema.org/draft-03/schema') === 0) { + return $that->getDraftSchema('json-schema-draft-03.json'); + } + + if (strpos($args[0], 'http://json-schema.org/draft-04/schema') === 0) { + return $that->getDraftSchema('json-schema-draft-04.json'); + } + if (strpos($args[0], 'http://json-schema.org/draft-06/schema') === 0) { + return $that->getDraftSchema('json-schema-draft-06.json'); } + + $urlParts = parse_url($args[0]); + + if (0 === strpos($args[0], 'http://localhost:1234')) { + return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . $urlParts['path']); + } + + if (0 === strpos($args[0], 'http://www.my-domain.com')) { + return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']); + } + + throw new \InvalidArgumentException(sprintf('No handling for %s has been setup', $args[0])); }); return $uriRetriever->reveal(); } - private function getJsonSchemaDraft03(): object + private function getDraftSchema(string $draft): stdClass { - if (!$this->jsonSchemaDraft03) { - $this->jsonSchemaDraft03 = json_decode( - file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-03.json') - ); + if (!array_key_exists($draft, $this->draftSchemas)) { + $this->draftSchemas[$draft] = $this->readAndJsonDecodeFile(self::DRAFT_SCHEMA_DIR . '/' . $draft); } - return $this->jsonSchemaDraft03; + return $this->draftSchemas[$draft]; } - private function getJsonSchemaDraft04(): object + private function readAndJsonDecodeFile(string $file): stdClass { - if (!$this->jsonSchemaDraft04) { - $this->jsonSchemaDraft04 = json_decode( - file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-04.json') - ); + if (!file_exists($file)) { + throw new \InvalidArgumentException(sprintf('File "%s" does not exist', $file)); } - return $this->jsonSchemaDraft04; + return json_decode(file_get_contents($file), false); } } diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 1f8040f2..9a4d564f 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -6,15 +6,15 @@ use JsonSchema\Tests\Constraints\BaseTestCase; -/** - * @package JsonSchema\Tests\Drafts - */ abstract class BaseDraftTestCase extends BaseTestCase { /** @var string */ - protected $relativeTestsRoot = '/../../vendor/json-schema/json-schema-test-suite/tests'; + protected const RELATIVE_TESTS_ROOT = '/../../vendor/json-schema/json-schema-test-suite/tests'; - private function setUpTests($isValid): array + /** + * @return array + */ + private function setUpTests(bool $isValid): array { $filePaths = $this->getFilePaths(); $skippedTests = $this->getSkippedTests(); @@ -27,7 +27,7 @@ private function setUpTests($isValid): array continue; } - $suites = json_decode(file_get_contents($file)); + $suites = json_decode(file_get_contents($file), false); foreach ($suites as $suite) { $suiteDescription = $suite->description; foreach ($suite->tests as $test) { @@ -45,29 +45,23 @@ private function setUpTests($isValid): array return $tests; } - /** - * {@inheritdoc} - */ public function getInvalidTests(): array { return $this->setUpTests(false); } - /** - * {@inheritdoc} - */ public function getValidTests(): array { return $this->setUpTests(true); } /** - * @return string[] + * @return list */ abstract protected function getFilePaths(): array; /** - * @return string[] + * @return list */ abstract protected function getSkippedTests(): array; diff --git a/tests/Drafts/Draft3Test.php b/tests/Drafts/Draft3Test.php index 91c5f6da..bebc6eaf 100644 --- a/tests/Drafts/Draft3Test.php +++ b/tests/Drafts/Draft3Test.php @@ -70,15 +70,14 @@ public function refPreventsASiblingIdFromChangingTheBaseUriProvider(): \Generato yield '$ref resolves to /definitions/base_foo, data validate' => ['data' => 1, 'valid' => true]; } - /** * {@inheritdoc} */ protected function getFilePaths(): array { return [ - realpath(__DIR__ . $this->relativeTestsRoot . '/draft3'), - realpath(__DIR__ . $this->relativeTestsRoot . '/draft3/optional') + realpath(__DIR__ . self::RELATIVE_TESTS_ROOT . '/draft3'), + realpath(__DIR__ . self::RELATIVE_TESTS_ROOT . '/draft3/optional') ]; } diff --git a/tests/Drafts/Draft4Test.php b/tests/Drafts/Draft4Test.php index e2b8a602..16c73b45 100644 --- a/tests/Drafts/Draft4Test.php +++ b/tests/Drafts/Draft4Test.php @@ -14,7 +14,7 @@ */ class Draft4Test extends BaseDraftTestCase { - protected $schemaSpec = 'http://json-schema.org/draft-04/schema#'; + /** @var bool */ protected $validateSchema = true; /** @@ -23,8 +23,8 @@ class Draft4Test extends BaseDraftTestCase protected function getFilePaths(): array { return [ - realpath(__DIR__ . $this->relativeTestsRoot . '/draft4'), - realpath(__DIR__ . $this->relativeTestsRoot . '/draft4/optional') + realpath(__DIR__ . self::RELATIVE_TESTS_ROOT . '/draft4'), + realpath(__DIR__ . self::RELATIVE_TESTS_ROOT . '/draft4/optional') ]; }