Skip to content

Commit 0b25270

Browse files
refactor: Update test case to current (PHP) standards (#831)
This PR improves the test cases classes and addresses some small fixes of issues which exposed themselves.
1 parent ce1fd2d commit 0b25270

File tree

9 files changed

+215
-80
lines changed

9 files changed

+215
-80
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Changed
10+
- Update test case to current (PHP) standards ([#831](https://github.com/jsonrainbow/json-schema/pull/831))
911

1012
## [6.4.2] - 2025-06-03
1113
### Fixed

dist/schema/json-schema-draft-06.json

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-06/schema#",
3+
"$id": "http://json-schema.org/draft-06/schema#",
4+
"title": "Core schema meta-schema",
5+
"definitions": {
6+
"schemaArray": {
7+
"type": "array",
8+
"minItems": 1,
9+
"items": { "$ref": "#" }
10+
},
11+
"nonNegativeInteger": {
12+
"type": "integer",
13+
"minimum": 0
14+
},
15+
"nonNegativeIntegerDefault0": {
16+
"allOf": [
17+
{ "$ref": "#/definitions/nonNegativeInteger" },
18+
{ "default": 0 }
19+
]
20+
},
21+
"simpleTypes": {
22+
"enum": [
23+
"array",
24+
"boolean",
25+
"integer",
26+
"null",
27+
"number",
28+
"object",
29+
"string"
30+
]
31+
},
32+
"stringArray": {
33+
"type": "array",
34+
"items": { "type": "string" },
35+
"uniqueItems": true,
36+
"default": []
37+
}
38+
},
39+
"type": ["object", "boolean"],
40+
"properties": {
41+
"$id": {
42+
"type": "string",
43+
"format": "uri-reference"
44+
},
45+
"$schema": {
46+
"type": "string",
47+
"format": "uri"
48+
},
49+
"$ref": {
50+
"type": "string",
51+
"format": "uri-reference"
52+
},
53+
"title": {
54+
"type": "string"
55+
},
56+
"description": {
57+
"type": "string"
58+
},
59+
"default": {},
60+
"examples": {
61+
"type": "array",
62+
"items": {}
63+
},
64+
"multipleOf": {
65+
"type": "number",
66+
"exclusiveMinimum": 0
67+
},
68+
"maximum": {
69+
"type": "number"
70+
},
71+
"exclusiveMaximum": {
72+
"type": "number"
73+
},
74+
"minimum": {
75+
"type": "number"
76+
},
77+
"exclusiveMinimum": {
78+
"type": "number"
79+
},
80+
"maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
81+
"minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
82+
"pattern": {
83+
"type": "string",
84+
"format": "regex"
85+
},
86+
"additionalItems": { "$ref": "#" },
87+
"items": {
88+
"anyOf": [
89+
{ "$ref": "#" },
90+
{ "$ref": "#/definitions/schemaArray" }
91+
],
92+
"default": {}
93+
},
94+
"maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
95+
"minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
96+
"uniqueItems": {
97+
"type": "boolean",
98+
"default": false
99+
},
100+
"contains": { "$ref": "#" },
101+
"maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
102+
"minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
103+
"required": { "$ref": "#/definitions/stringArray" },
104+
"additionalProperties": { "$ref": "#" },
105+
"definitions": {
106+
"type": "object",
107+
"additionalProperties": { "$ref": "#" },
108+
"default": {}
109+
},
110+
"properties": {
111+
"type": "object",
112+
"additionalProperties": { "$ref": "#" },
113+
"default": {}
114+
},
115+
"patternProperties": {
116+
"type": "object",
117+
"additionalProperties": { "$ref": "#" },
118+
"propertyNames": { "format": "regex" },
119+
"default": {}
120+
},
121+
"dependencies": {
122+
"type": "object",
123+
"additionalProperties": {
124+
"anyOf": [
125+
{ "$ref": "#" },
126+
{ "$ref": "#/definitions/stringArray" }
127+
]
128+
}
129+
},
130+
"propertyNames": { "$ref": "#" },
131+
"const": {},
132+
"enum": {
133+
"type": "array",
134+
"minItems": 1,
135+
"uniqueItems": true
136+
},
137+
"type": {
138+
"anyOf": [
139+
{ "$ref": "#/definitions/simpleTypes" },
140+
{
141+
"type": "array",
142+
"items": { "$ref": "#/definitions/simpleTypes" },
143+
"minItems": 1,
144+
"uniqueItems": true
145+
}
146+
]
147+
},
148+
"format": { "type": "string" },
149+
"allOf": { "$ref": "#/definitions/schemaArray" },
150+
"anyOf": { "$ref": "#/definitions/schemaArray" },
151+
"oneOf": { "$ref": "#/definitions/schemaArray" },
152+
"not": { "$ref": "#" }
153+
},
154+
"default": {}
155+
}

tests/Constraints/ArraysTest.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,6 @@ public function getValidTests(): array
272272
}
273273
}'
274274
],
275-
'items: true passes validation' => [
276-
'input' => <<<JSON
277-
[1, 1.2, "12"]
278-
JSON
279-
,
280-
'schema' => <<<JSON
281-
{ "type": "array", "items": true }
282-
JSON
283-
,
284-
],
285275
];
286276
}
287277
}

tests/Constraints/BaseTestCase.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,24 @@ abstract class BaseTestCase extends VeryBaseTestCase
2525

2626
/**
2727
* @dataProvider getInvalidTests
28+
*
29+
* @param int-mask-of<Constraint::CHECK_MODE_*> $checkMode
2830
*/
29-
public function testInvalidCases($input, $schema, $checkMode = Constraint::CHECK_MODE_NORMAL, $errors = []): void
31+
public function testInvalidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL, array $errors = []): void
3032
{
31-
$checkMode = $checkMode === null ? Constraint::CHECK_MODE_NORMAL : $checkMode;
33+
$checkMode = $checkMode ?? Constraint::CHECK_MODE_NORMAL;
3234
if ($this->validateSchema) {
3335
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
3436
}
3537

36-
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema)));
38+
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema, false)));
3739
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
3840
if (is_object($schema) && !isset($schema->{'$schema'})) {
3941
$schema->{'$schema'} = $this->schemaSpec;
4042
}
4143

4244
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
43-
$checkValue = json_decode($input);
45+
$checkValue = json_decode($input, false);
4446
$errorMask = $validator->validate($checkValue, $schema);
4547

4648
$this->assertTrue((bool) ($errorMask & Validator::ERROR_DOCUMENT_VALIDATION));

tests/Constraints/ConstTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function getValidTests(): array
121121
"type": "object",
122122
"properties": {
123123
"value": {
124-
"type": "any",
124+
"type": "object",
125125
"const": {
126126
"foo": 12
127127
}

tests/Constraints/VeryBaseTestCase.php

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,80 +2,73 @@
22

33
declare(strict_types=1);
44

5-
/*
6-
* This file is part of the JsonSchema package.
7-
*
8-
* For the full copyright and license information, please view the LICENSE
9-
* file that was distributed with this source code.
10-
*/
11-
125
namespace JsonSchema\Tests\Constraints;
136

7+
use JsonSchema\UriRetrieverInterface;
148
use PHPUnit\Framework\TestCase;
159
use Prophecy\Argument;
10+
use stdClass;
1611

17-
/**
18-
* @package JsonSchema\Tests\Constraints
19-
*/
2012
abstract class VeryBaseTestCase extends TestCase
2113
{
22-
/** @var object */
23-
private $jsonSchemaDraft03;
14+
private const DRAFT_SCHEMA_DIR = __DIR__ . '/../../dist/schema/';
15+
private const TEST_SUITE_REMOTES = __DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes';
2416

25-
/** @var object */
26-
private $jsonSchemaDraft04;
17+
/** @var array<string, stdClass> */
18+
private $draftSchemas = [];
2719

2820
protected function getUriRetrieverMock(?object $schema): object
2921
{
30-
$relativeTestsRoot = realpath(__DIR__ . '/../../vendor/json-schema/json-schema-test-suite/remotes');
31-
32-
$jsonSchemaDraft03 = $this->getJsonSchemaDraft03();
33-
$jsonSchemaDraft04 = $this->getJsonSchemaDraft04();
34-
35-
$uriRetriever = $this->prophesize('JsonSchema\UriRetrieverInterface');
22+
$uriRetriever = $this->prophesize(UriRetrieverInterface::class);
3623
$uriRetriever->retrieve('http://www.my-domain.com/schema.json')
3724
->willReturn($schema)
3825
->shouldBeCalled();
3926

27+
$that = $this;
4028
$uriRetriever->retrieve(Argument::any())
41-
->will(function ($args) use ($jsonSchemaDraft03, $jsonSchemaDraft04, $relativeTestsRoot) {
42-
if ('http://json-schema.org/draft-03/schema' === $args[0]) {
43-
return $jsonSchemaDraft03;
44-
} elseif ('http://json-schema.org/draft-04/schema' === $args[0]) {
45-
return $jsonSchemaDraft04;
46-
} elseif (0 === strpos($args[0], 'http://localhost:1234')) {
47-
$urlParts = parse_url($args[0]);
48-
49-
return json_decode(file_get_contents($relativeTestsRoot . $urlParts['path']));
50-
} elseif (0 === strpos($args[0], 'http://www.my-domain.com')) {
51-
$urlParts = parse_url($args[0]);
52-
53-
return json_decode(file_get_contents($relativeTestsRoot . '/folder' . $urlParts['path']));
29+
->will(function ($args) use ($that): stdClass {
30+
if (strpos($args[0], 'http://json-schema.org/draft-03/schema') === 0) {
31+
return $that->getDraftSchema('json-schema-draft-03.json');
32+
}
33+
34+
if (strpos($args[0], 'http://json-schema.org/draft-04/schema') === 0) {
35+
return $that->getDraftSchema('json-schema-draft-04.json');
36+
}
37+
if (strpos($args[0], 'http://json-schema.org/draft-06/schema') === 0) {
38+
return $that->getDraftSchema('json-schema-draft-06.json');
5439
}
40+
41+
$urlParts = parse_url($args[0]);
42+
43+
if (0 === strpos($args[0], 'http://localhost:1234')) {
44+
return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . $urlParts['path']);
45+
}
46+
47+
if (0 === strpos($args[0], 'http://www.my-domain.com')) {
48+
return $that->readAndJsonDecodeFile(self::TEST_SUITE_REMOTES . '/folder' . $urlParts['path']);
49+
}
50+
51+
throw new \InvalidArgumentException(sprintf('No handling for %s has been setup', $args[0]));
5552
});
5653

5754
return $uriRetriever->reveal();
5855
}
5956

60-
private function getJsonSchemaDraft03(): object
57+
private function getDraftSchema(string $draft): stdClass
6158
{
62-
if (!$this->jsonSchemaDraft03) {
63-
$this->jsonSchemaDraft03 = json_decode(
64-
file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-03.json')
65-
);
59+
if (!array_key_exists($draft, $this->draftSchemas)) {
60+
$this->draftSchemas[$draft] = $this->readAndJsonDecodeFile(self::DRAFT_SCHEMA_DIR . '/' . $draft);
6661
}
6762

68-
return $this->jsonSchemaDraft03;
63+
return $this->draftSchemas[$draft];
6964
}
7065

71-
private function getJsonSchemaDraft04(): object
66+
private function readAndJsonDecodeFile(string $file): stdClass
7267
{
73-
if (!$this->jsonSchemaDraft04) {
74-
$this->jsonSchemaDraft04 = json_decode(
75-
file_get_contents(__DIR__ . '/../../dist/schema/json-schema-draft-04.json')
76-
);
68+
if (!file_exists($file)) {
69+
throw new \InvalidArgumentException(sprintf('File "%s" does not exist', $file));
7770
}
7871

79-
return $this->jsonSchemaDraft04;
72+
return json_decode(file_get_contents($file), false);
8073
}
8174
}

0 commit comments

Comments
 (0)