Skip to content

refactor: Update test case to current (PHP) standards #831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jun 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e5f35dc
docs: remove class php doc referring to license file
DannyvdSluijs Jun 6, 2025
10aba27
refactor: use array for draft schema memoization to allow for future …
DannyvdSluijs Jun 6, 2025
7327f0f
refactor: consolidate file reading and json decode to single function
DannyvdSluijs Jun 6, 2025
1687224
refactor: use class constant instead of string literal
DannyvdSluijs Jun 6, 2025
379ecf9
refactor: add exception when url isn't being handled; add missing ret…
DannyvdSluijs Jun 6, 2025
ac50f8b
docs: remove class phpdoc
DannyvdSluijs Jun 6, 2025
3c26a8b
refactor: cleanup mock
DannyvdSluijs Jun 6, 2025
8186a9b
refactor: add type hints
DannyvdSluijs Jun 6, 2025
5672d19
refactor: force decoding into object
DannyvdSluijs Jun 6, 2025
c88a55a
refactor: use null coalesce to assign default value
DannyvdSluijs Jun 6, 2025
1867710
test: remove test which doesn't belong in draft 4
DannyvdSluijs Jun 6, 2025
4af2329
test: correct invalid schema in test case
DannyvdSluijs Jun 6, 2025
ef904c7
style: correct code style violations
DannyvdSluijs Jun 6, 2025
6438cc2
fix: add missing schema
DannyvdSluijs Jun 6, 2025
0ce4ffa
refactor: remove class package annotation
DannyvdSluijs Jun 10, 2025
869cc7f
refactor: replace property with class constant
DannyvdSluijs Jun 10, 2025
57b0d05
refactor: add/strengthen type hints
DannyvdSluijs Jun 10, 2025
a9ff7c3
refactor: remove inherit doc on overrides without parent documentation
DannyvdSluijs Jun 10, 2025
ffa6ce1
docs: add changelog entry
DannyvdSluijs Jun 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
155 changes: 155 additions & 0 deletions dist/schema/json-schema-draft-06.json
Original file line number Diff line number Diff line change
@@ -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": {}
}
10 changes: 0 additions & 10 deletions tests/Constraints/ArraysTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,6 @@ public function getValidTests(): array
}
}'
],
'items: true passes validation' => [
'input' => <<<JSON
[1, 1.2, "12"]
JSON
,
'schema' => <<<JSON
{ "type": "array", "items": true }
JSON
,
],
];
}
}
10 changes: 6 additions & 4 deletions tests/Constraints/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,24 @@ abstract class BaseTestCase extends VeryBaseTestCase

/**
* @dataProvider getInvalidTests
*
* @param int-mask-of<Constraint::CHECK_MODE_*> $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));
Expand Down
2 changes: 1 addition & 1 deletion tests/Constraints/ConstTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function getValidTests(): array
"type": "object",
"properties": {
"value": {
"type": "any",
"type": "object",
"const": {
"foo": 12
}
Expand Down
83 changes: 38 additions & 45 deletions tests/Constraints/VeryBaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, stdClass> */
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);
}
}
Loading