From e5f35dc78866ecfb962f0f0b47dc41067c4a2c3a Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:09:51 +0200 Subject: [PATCH 01/19] docs: remove class php doc referring to license file --- tests/Constraints/VeryBaseTestCase.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index ea018bda..38a97eba 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -2,13 +2,6 @@ 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 PHPUnit\Framework\TestCase; From 10aba27c8f76fa2f7168359f2a8610a51894103e Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:20:54 +0200 Subject: [PATCH 02/19] refactor: use array for draft schema memoization to allow for future growth --- tests/Constraints/VeryBaseTestCase.php | 46 ++++++++++---------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 38a97eba..1db27bcc 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -6,24 +6,21 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; +use stdClass; /** * @package JsonSchema\Tests\Constraints */ abstract class VeryBaseTestCase extends TestCase { - /** @var object */ - private $jsonSchemaDraft03; - - /** @var object */ - private $jsonSchemaDraft04; + private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/'; + /** @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->retrieve('http://www.my-domain.com/schema.json') @@ -31,12 +28,16 @@ protected function getUriRetrieverMock(?object $schema): object ->shouldBeCalled(); $uriRetriever->retrieve(Argument::any()) - ->will(function ($args) use ($jsonSchemaDraft03, $jsonSchemaDraft04, $relativeTestsRoot) { + ->will(function ($args) use ($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')) { + return $this->getDraftSchema('json-schema-draft-03.json'); + } + + if ('http://json-schema.org/draft-04/schema' === $args[0]) { + return $this->getDraftSchema('json-schema-draft-04.json'); + } + + if (0 === strpos($args[0], 'http://localhost:1234')) { $urlParts = parse_url($args[0]); return json_decode(file_get_contents($relativeTestsRoot . $urlParts['path'])); @@ -50,25 +51,12 @@ protected function getUriRetrieverMock(?object $schema): object return $uriRetriever->reveal(); } - private function getJsonSchemaDraft03(): object - { - if (!$this->jsonSchemaDraft03) { - $this->jsonSchemaDraft03 = json_decode( - file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-03.json') - ); - } - - return $this->jsonSchemaDraft03; - } - - private function getJsonSchemaDraft04(): object + private function getDraftSchema(string $draft): stdClass { - if (!$this->jsonSchemaDraft04) { - $this->jsonSchemaDraft04 = json_decode( - file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-04.json') - ); + if (!array_key_exists($draft, $this->draftSchemas)) { + $this->draftSchemas[$draft] = json_decode(file_get_contents(self::DRAFT_SCHEMA_DIR . '/' . $draft), false); } - return $this->jsonSchemaDraft04; + return $this->draftSchemas[$draft]; } } From 7327f0f5c159b088f803a68e7387d0e3d185b851 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:27:22 +0200 Subject: [PATCH 03/19] refactor: consolidate file reading and json decode to single function --- tests/Constraints/VeryBaseTestCase.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 1db27bcc..634b7876 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -14,21 +14,20 @@ abstract class VeryBaseTestCase extends TestCase { private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/'; + private const TEST_SUITE_REMOTES = __DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes'; + /** @var array */ private $draftSchemas = []; protected function getUriRetrieverMock(?object $schema): object { - $relativeTestsRoot = realpath(__DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes'); - - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); $uriRetriever->retrieve('http://www.my-domain.com/schema.json') ->willReturn($schema) ->shouldBeCalled(); $uriRetriever->retrieve(Argument::any()) - ->will(function ($args) use ($relativeTestsRoot) { + ->will(function ($args) { if ('http://json-schema.org/draft-03/schema' === $args[0]) { return $this->getDraftSchema('json-schema-draft-03.json'); } @@ -37,14 +36,14 @@ protected function getUriRetrieverMock(?object $schema): object return $this->getDraftSchema('json-schema-draft-04.json'); } - if (0 === strpos($args[0], 'http://localhost:1234')) { - $urlParts = parse_url($args[0]); + $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]); + if (0 === strpos($args[0], 'http://localhost:1234')) { + return $this->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . $urlParts['path']); + } - return json_decode(file_get_contents($relativeTestsRoot . '/folder' . $urlParts['path'])); + if (0 === strpos($args[0], 'http://www.my-domain.com')) { + return $this->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']); } }); @@ -54,9 +53,14 @@ protected function getUriRetrieverMock(?object $schema): object private function getDraftSchema(string $draft): stdClass { if (!array_key_exists($draft, $this->draftSchemas)) { - $this->draftSchemas[$draft] = json_decode(file_get_contents(self::DRAFT_SCHEMA_DIR . '/' . $draft), false); + $this->draftSchemas[$draft] = $this->readAndJsonDecodeFile(self::DRAFT_SCHEMA_DIR . '/' . $draft); } return $this->draftSchemas[$draft]; } + + private function readAndJsonDecodeFile(string $file): stdClass + { + return json_decode(file_get_contents($file), false); + } } From 1687224d69ed8e3e19e4805d1fd054b36a43cee7 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:29:42 +0200 Subject: [PATCH 04/19] refactor: use class constant instead of string literal --- tests/Constraints/VeryBaseTestCase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 634b7876..617e005c 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; use stdClass; +use JsonSchema\UriRetrieverInterface; /** * @package JsonSchema\Tests\Constraints @@ -21,7 +22,7 @@ abstract class VeryBaseTestCase extends TestCase protected function getUriRetrieverMock(?object $schema): object { - $uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface'); + $uriRetriever = $this->prophesize(UriRetrieverInterface::class); $uriRetriever->retrieve('http://www.my-domain.com/schema.json') ->willReturn($schema) ->shouldBeCalled(); From 379ecf9d95e874fd37a9575dbc97409d0ee1a853 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:30:13 +0200 Subject: [PATCH 05/19] refactor: add exception when url isn't being handled; add missing return type --- tests/Constraints/VeryBaseTestCase.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 617e005c..237f207f 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -28,7 +28,7 @@ protected function getUriRetrieverMock(?object $schema): object ->shouldBeCalled(); $uriRetriever->retrieve(Argument::any()) - ->will(function ($args) { + ->will(function ($args): stdClass { if ('http://json-schema.org/draft-03/schema' === $args[0]) { return $this->getDraftSchema('json-schema-draft-03.json'); } @@ -46,6 +46,8 @@ protected function getUriRetrieverMock(?object $schema): object if (0 === strpos($args[0], 'http://www.my-domain.com')) { return $this->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']); } + + throw new \InvalidArgumentException(sprintf('No handling for %s has been setup', $args[0])); }); return $uriRetriever->reveal(); From ac50f8b99edc7618c02eb14aae1c8748fd12e246 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 15:30:35 +0200 Subject: [PATCH 06/19] docs: remove class phpdoc --- tests/Constraints/VeryBaseTestCase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 237f207f..90c02ccf 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -9,9 +9,6 @@ use stdClass; use JsonSchema\UriRetrieverInterface; -/** - * @package JsonSchema\Tests\Constraints - */ abstract class VeryBaseTestCase extends TestCase { private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/'; From 3c26a8b982c60866939b0870bce4d9fb02d639b6 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:36:21 +0200 Subject: [PATCH 07/19] refactor: cleanup mock --- tests/Constraints/VeryBaseTestCase.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 90c02ccf..9faf2121 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -24,24 +24,28 @@ protected function getUriRetrieverMock(?object $schema): object ->willReturn($schema) ->shouldBeCalled(); + $that = $this; $uriRetriever->retrieve(Argument::any()) - ->will(function ($args): stdClass { - if ('http://json-schema.org/draft-03/schema' === $args[0]) { - return $this->getDraftSchema('json-schema-draft-03.json'); + ->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 ('http://json-schema.org/draft-04/schema' === $args[0]) { - return $this->getDraftSchema('json-schema-draft-04.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 $this->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . $urlParts['path']); + return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . $urlParts['path']); } if (0 === strpos($args[0], 'http://www.my-domain.com')) { - return $this->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']); + return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']); } throw new \InvalidArgumentException(sprintf('No handling for %s has been setup', $args[0])); @@ -61,6 +65,9 @@ private function getDraftSchema(string $draft): stdClass private function readAndJsonDecodeFile(string $file): stdClass { + if (!file_exists($file)) { + throw new \InvalidArgumentException(sprintf('File "%s" does not exist', $file)); + } return json_decode(file_get_contents($file), false); } } From 8186a9b4248b645346045d43421f750f11b8f526 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:36:59 +0200 Subject: [PATCH 08/19] refactor: add type hints --- tests/Constraints/BaseTestCase.php | 4 +++- tests/Drafts/BaseDraftTestCase.php | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Constraints/BaseTestCase.php b/tests/Constraints/BaseTestCase.php index ba55b461..f0fdd0fb 100644 --- a/tests/Constraints/BaseTestCase.php +++ b/tests/Constraints/BaseTestCase.php @@ -25,8 +25,10 @@ abstract class BaseTestCase extends VeryBaseTestCase /** * @dataProvider getInvalidTests + * + * @param int-mask-of $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; if ($this->validateSchema) { diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 1f8040f2..967983f1 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -14,6 +14,9 @@ abstract class BaseDraftTestCase extends BaseTestCase /** @var string */ protected $relativeTestsRoot = '/../../vendor/json-schema/json-schema-test-suite/tests'; + /** + * @return array + */ private function setUpTests($isValid): array { $filePaths = $this->getFilePaths(); From 5672d19673cca0d853936cbb3005d1a6d2c3c13f Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:37:27 +0200 Subject: [PATCH 09/19] refactor: force decoding into object --- tests/Constraints/BaseTestCase.php | 4 ++-- tests/Drafts/BaseDraftTestCase.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Constraints/BaseTestCase.php b/tests/Constraints/BaseTestCase.php index f0fdd0fb..e4438151 100644 --- a/tests/Constraints/BaseTestCase.php +++ b/tests/Constraints/BaseTestCase.php @@ -35,14 +35,14 @@ public function testInvalidCases(string $input, string $schema, ?int $checkMode $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/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 967983f1..c71a7299 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -30,7 +30,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) { From c88a55a6c5816b099f1a8fbd02ca858fe760cee0 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:38:27 +0200 Subject: [PATCH 10/19] refactor: use null coalesce to assign default value --- tests/Constraints/BaseTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Constraints/BaseTestCase.php b/tests/Constraints/BaseTestCase.php index e4438151..84daaf13 100644 --- a/tests/Constraints/BaseTestCase.php +++ b/tests/Constraints/BaseTestCase.php @@ -30,7 +30,7 @@ abstract class BaseTestCase extends VeryBaseTestCase */ 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; } From 18677100d093fc4a8ee9fdc0cf04c2315985d30f Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:39:04 +0200 Subject: [PATCH 11/19] test: remove test which doesn't belong in draft 4 https://github.com/jsonrainbow/json-schema/issues/799#issuecomment-2950060175 --- tests/Constraints/ArraysTest.php | 10 ---------- 1 file changed, 10 deletions(-) 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' => << << Date: Fri, 6 Jun 2025 20:47:15 +0200 Subject: [PATCH 12/19] test: correct invalid schema in test case --- tests/Constraints/ConstTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 } From ef904c781d4c9230fd5664bea310cc7abc99c684 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 20:48:00 +0200 Subject: [PATCH 13/19] style: correct code style violations --- tests/Constraints/VeryBaseTestCase.php | 7 ++++--- tests/Drafts/Draft3Test.php | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Constraints/VeryBaseTestCase.php b/tests/Constraints/VeryBaseTestCase.php index 9faf2121..55d0672d 100644 --- a/tests/Constraints/VeryBaseTestCase.php +++ b/tests/Constraints/VeryBaseTestCase.php @@ -4,17 +4,17 @@ namespace JsonSchema\Tests\Constraints; +use JsonSchema\UriRetrieverInterface; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use stdClass; -use JsonSchema\UriRetrieverInterface; abstract class VeryBaseTestCase extends TestCase { private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/'; private const TEST_SUITE_REMOTES = __DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes'; - /** @var array */ + /** @var array */ private $draftSchemas = []; protected function getUriRetrieverMock(?object $schema): object @@ -26,7 +26,7 @@ protected function getUriRetrieverMock(?object $schema): object $that = $this; $uriRetriever->retrieve(Argument::any()) - ->will(function ($args) use ($that): stdClass { + ->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'); } @@ -68,6 +68,7 @@ private function readAndJsonDecodeFile(string $file): stdClass if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('File "%s" does not exist', $file)); } + return json_decode(file_get_contents($file), false); } } diff --git a/tests/Drafts/Draft3Test.php b/tests/Drafts/Draft3Test.php index 91c5f6da..20e964c4 100644 --- a/tests/Drafts/Draft3Test.php +++ b/tests/Drafts/Draft3Test.php @@ -70,7 +70,6 @@ public function refPreventsASiblingIdFromChangingTheBaseUriProvider(): \Generato yield '$ref resolves to /definitions/base_foo, data validate' => ['data' => 1, 'valid' => true]; } - /** * {@inheritdoc} */ From 6438cc25a30f366bb73de297dcd35530a262b960 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Fri, 6 Jun 2025 21:41:24 +0200 Subject: [PATCH 14/19] fix: add missing schema --- dist/schema/json-schema-draft-06.json | 155 ++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 dist/schema/json-schema-draft-06.json 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": {} +} From 0ce4ffa6a84b61de9a6786ca14d251943a46775c Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Tue, 10 Jun 2025 20:24:57 +0200 Subject: [PATCH 15/19] refactor: remove class package annotation --- tests/Drafts/BaseDraftTestCase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index c71a7299..09cf47e0 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -6,9 +6,6 @@ use JsonSchema\Tests\Constraints\BaseTestCase; -/** - * @package JsonSchema\Tests\Drafts - */ abstract class BaseDraftTestCase extends BaseTestCase { /** @var string */ From 869cc7f19ce29a6a014b466a9a44ed159d9b2a54 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Tue, 10 Jun 2025 20:25:50 +0200 Subject: [PATCH 16/19] refactor: replace property with class constant --- tests/Drafts/BaseDraftTestCase.php | 2 +- tests/Drafts/Draft3Test.php | 4 ++-- tests/Drafts/Draft4Test.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 09cf47e0..4d3d4963 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -9,7 +9,7 @@ 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'; /** * @return array diff --git a/tests/Drafts/Draft3Test.php b/tests/Drafts/Draft3Test.php index 20e964c4..bebc6eaf 100644 --- a/tests/Drafts/Draft3Test.php +++ b/tests/Drafts/Draft3Test.php @@ -76,8 +76,8 @@ public function refPreventsASiblingIdFromChangingTheBaseUriProvider(): \Generato 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..832f5ccc 100644 --- a/tests/Drafts/Draft4Test.php +++ b/tests/Drafts/Draft4Test.php @@ -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') ]; } From 57b0d050456be1a1b7cbaaf15eb79f597b625486 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Tue, 10 Jun 2025 20:27:22 +0200 Subject: [PATCH 17/19] refactor: add/strengthen type hints --- tests/Drafts/BaseDraftTestCase.php | 6 +++--- tests/Drafts/Draft4Test.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 4d3d4963..2b687133 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -14,7 +14,7 @@ abstract class BaseDraftTestCase extends BaseTestCase /** * @return array */ - private function setUpTests($isValid): array + private function setUpTests(bool $isValid): array { $filePaths = $this->getFilePaths(); $skippedTests = $this->getSkippedTests(); @@ -62,12 +62,12 @@ public function getValidTests(): array } /** - * @return string[] + * @return list */ abstract protected function getFilePaths(): array; /** - * @return string[] + * @return list */ abstract protected function getSkippedTests(): array; diff --git a/tests/Drafts/Draft4Test.php b/tests/Drafts/Draft4Test.php index 832f5ccc..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; /** From a9ff7c361e6a1c7327f63d10cb81a71449ea2bfc Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Tue, 10 Jun 2025 20:27:56 +0200 Subject: [PATCH 18/19] refactor: remove inherit doc on overrides without parent documentation --- tests/Drafts/BaseDraftTestCase.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/Drafts/BaseDraftTestCase.php b/tests/Drafts/BaseDraftTestCase.php index 2b687133..9a4d564f 100644 --- a/tests/Drafts/BaseDraftTestCase.php +++ b/tests/Drafts/BaseDraftTestCase.php @@ -45,17 +45,11 @@ private function setUpTests(bool $isValid): array return $tests; } - /** - * {@inheritdoc} - */ public function getInvalidTests(): array { return $this->setUpTests(false); } - /** - * {@inheritdoc} - */ public function getValidTests(): array { return $this->setUpTests(true); From ffa6ce13dfd47beaf671bc2ff554090c9352fbd6 Mon Sep 17 00:00:00 2001 From: Danny van der Sluijs Date: Tue, 10 Jun 2025 20:33:38 +0200 Subject: [PATCH 19/19] docs: add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) 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