Skip to content

Commit 3763af1

Browse files
feat: update to latest json schema test suite (#821)
This pull request updates the `json-schema/json-schema-test-suite` dependency to a newer version and introduces a new test suite for validating JSON schemas. The goal here is to have a quicker turnaround then just the bowtie reports. The most important changes are grouped below: ### Dependency Updates: * Updated `json-schema/json-schema-test-suite` dependency in `composer.json` from version `1.2.0` to `^23.2` and updated the package version and reference in the `repositories` section to match the new version. [[1]](diffhunk://#diff-d2ab9925cad7eac58e0ff4cc0d251a937ecf49e4b6bf57f8b95aab76648a9d34L36-R36) [[2]](diffhunk://#diff-d2ab9925cad7eac58e0ff4cc0d251a937ecf49e4b6bf57f8b95aab76648a9d34L62-R66) ### New Test Suite: * Added a new `JsonSchemaTestSuite` class in `tests/JsonSchemaTestSuite.php` to run validation tests using the `json-schema/json-schema-test-suite`. This includes: - A `testIt` method to validate test cases and assert results. - A `casesDataProvider` method to dynamically load test cases from the `json-schema-test-suite` repository, skipping certain drafts. - A `loadRemotesIntoStorage` helper method to load remote schemas into the schema storage.
1 parent 4118460 commit 3763af1

10 files changed

+296
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Changed
1010
- Update test case to current (PHP) standards ([#831](https://github.com/jsonrainbow/json-schema/pull/831))
1111
- Upgrade test suite to use generators ([#834](https://github.com/jsonrainbow/json-schema/pull/834))
12+
- update to latest json schema test suite ([#821](https://github.com/jsonrainbow/json-schema/pull/821))
1213

1314
## [6.4.2] - 2025-06-03
1415
### Fixed

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
},
3434
"require-dev": {
3535
"friendsofphp/php-cs-fixer": "3.3.0",
36-
"json-schema/json-schema-test-suite": "1.2.0",
36+
"json-schema/json-schema-test-suite": "^23.2",
3737
"phpunit/phpunit": "^8.5",
3838
"phpspec/prophecy": "^1.19",
3939
"phpstan/phpstan": "^1.12",
@@ -59,11 +59,11 @@
5959
"type": "package",
6060
"package": {
6161
"name": "json-schema/json-schema-test-suite",
62-
"version": "1.2.0",
62+
"version": "23.2.0",
6363
"source": {
6464
"type": "git",
6565
"url": "https://github.com/json-schema/JSON-Schema-Test-Suite",
66-
"reference": "1.2.0"
66+
"reference": "23.2.0"
6767
}
6868
}
6969
}

phpunit.xml.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
<directory>./src/JsonSchema/</directory>
2525
</whitelist>
2626
</filter>
27+
28+
<php>
29+
<ini name="memory_limit" value="-1"/>
30+
</php>
2731
</phpunit>

tests/Constraints/BaseTestCase.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ abstract class BaseTestCase extends VeryBaseTestCase
1919
/**
2020
* @dataProvider getInvalidTests
2121
*
22-
* @param int-mask-of<Constraint::CHECK_MODE_*> $checkMode
22+
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
2323
*/
2424
public function testInvalidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL, array $errors = []): void
2525
{
@@ -28,8 +28,9 @@ public function testInvalidCases(string $input, string $schema, ?int $checkMode
2828
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
2929
}
3030

31-
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema, false)));
32-
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
31+
$schema = json_decode($schema, false);
32+
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock($schema));
33+
$schema = $schemaStorage->getSchema($schema->id ?? 'http://www.my-domain.com/schema.json');
3334
if (is_object($schema) && !isset($schema->{'$schema'})) {
3435
$schema->{'$schema'} = $this->schemaSpec;
3536
}
@@ -38,7 +39,7 @@ public function testInvalidCases(string $input, string $schema, ?int $checkMode
3839
$checkValue = json_decode($input, false);
3940
$errorMask = $validator->validate($checkValue, $schema);
4041

41-
$this->assertTrue((bool) ($errorMask & Validator::ERROR_DOCUMENT_VALIDATION));
42+
$this->assertTrue((bool) ($errorMask & Validator::ERROR_DOCUMENT_VALIDATION), 'Document is invalid');
4243
$this->assertGreaterThan(0, $validator->numErrors());
4344

4445
if ([] !== $errors) {
@@ -49,8 +50,10 @@ public function testInvalidCases(string $input, string $schema, ?int $checkMode
4950

5051
/**
5152
* @dataProvider getInvalidForAssocTests
53+
*
54+
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
5255
*/
53-
public function testInvalidCasesUsingAssoc($input, $schema, $checkMode = Constraint::CHECK_MODE_TYPE_CAST, $errors = []): void
56+
public function testInvalidCasesUsingAssoc(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_TYPE_CAST, array $errors = []): void
5457
{
5558
$checkMode = $checkMode ?? Constraint::CHECK_MODE_TYPE_CAST;
5659
if ($this->validateSchema) {
@@ -60,8 +63,9 @@ public function testInvalidCasesUsingAssoc($input, $schema, $checkMode = Constra
6063
$this->markTestSkipped('Test indicates that it is not for "CHECK_MODE_TYPE_CAST"');
6164
}
6265

63-
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema)));
64-
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
66+
$schema = json_decode($schema, false);
67+
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock($schema));
68+
$schema = $schemaStorage->getSchema($schema->id ?? 'http://www.my-domain.com/schema.json');
6569
if (is_object($schema) && !isset($schema->{'$schema'})) {
6670
$schema->{'$schema'} = $this->schemaSpec;
6771
}
@@ -81,14 +85,18 @@ public function testInvalidCasesUsingAssoc($input, $schema, $checkMode = Constra
8185

8286
/**
8387
* @dataProvider getValidTests
88+
*
89+
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
8490
*/
85-
public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_MODE_NORMAL): void
91+
public function testValidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL): void
8692
{
8793
if ($this->validateSchema) {
8894
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
8995
}
90-
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema, false)));
91-
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
96+
97+
$schema = json_decode($schema, false);
98+
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock($schema));
99+
$schema = $schemaStorage->getSchema($schema->id ?? 'http://www.my-domain.com/schema.json');
92100
if (is_object($schema) && !isset($schema->{'$schema'})) {
93101
$schema->{'$schema'} = $this->schemaSpec;
94102
}
@@ -103,8 +111,10 @@ public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_M
103111

104112
/**
105113
* @dataProvider getValidForAssocTests
114+
*
115+
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
106116
*/
107-
public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constraint::CHECK_MODE_TYPE_CAST): void
117+
public function testValidCasesUsingAssoc(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_TYPE_CAST): void
108118
{
109119
if ($this->validateSchema) {
110120
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
@@ -113,9 +123,9 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain
113123
$this->markTestSkipped('Test indicates that it is not for "CHECK_MODE_TYPE_CAST"');
114124
}
115125

116-
$schema = json_decode($schema);
126+
$schema = json_decode($schema, false);
117127
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock($schema), new UriResolver());
118-
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
128+
$schema = $schemaStorage->getSchema($schema->id ?? 'http://www.my-domain.com/schema.json');
119129
if (is_object($schema) && !isset($schema->{'$schema'})) {
120130
$schema->{'$schema'} = $this->schemaSpec;
121131
}
@@ -124,7 +134,7 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain
124134
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
125135

126136
$errorMask = $validator->validate($value, $schema);
127-
$this->assertEquals(0, $errorMask);
137+
$this->assertEquals(0, $errorMask, $this->validatorErrorsToString($validator));
128138
$this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true));
129139
}
130140

@@ -141,4 +151,14 @@ public function getInvalidForAssocTests(): Generator
141151
{
142152
yield from $this->getInvalidTests();
143153
}
154+
155+
private function validatorErrorsToString(Validator $validator): string
156+
{
157+
return implode(
158+
', ',
159+
array_map(
160+
static function (array $error) { return $error['message']; }, $validator->getErrors()
161+
)
162+
);
163+
}
144164
}

tests/Constraints/NumberAndIntegerTypesTest.php

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,35 @@ class NumberAndIntegerTypesTest extends BaseTestCase
1212
public function getInvalidTests(): \Generator
1313
{
1414
yield [
15-
'{
16-
"integer": 1.4
17-
}',
18-
'{
15+
'input' => '{ "integer": 1.4 }',
16+
'schema' => '{
1917
"type":"object",
2018
"properties":{
2119
"integer":{"type":"integer"}
2220
}
2321
}'
2422
];
2523
yield [
26-
'{"integer": 1.001}',
27-
'{
24+
'input' => '{"integer": 1.001}',
25+
'schema' => '{
2826
"type": "object",
2927
"properties": {
3028
"integer": {"type": "integer"}
3129
}
3230
}'
3331
];
3432
yield [
35-
'{"integer": true}',
36-
'{
33+
'input' => '{"integer": true}',
34+
'schema' => '{
3735
"type": "object",
3836
"properties": {
3937
"integer": {"type": "integer"}
4038
}
4139
}'
4240
];
4341
yield [
44-
'{"number": "x"}',
45-
'{
42+
'input' => '{"number": "x"}',
43+
'schema' => '{
4644
"type": "object",
4745
"properties": {
4846
"number": {"type": "number"}
@@ -54,39 +52,35 @@ public function getInvalidTests(): \Generator
5452
public function getValidTests(): \Generator
5553
{
5654
yield [
57-
'{
58-
"integer": 1
59-
}',
60-
'{
55+
'input' => '{ "integer": 1 }',
56+
'schema' => '{
6157
"type":"object",
6258
"properties":{
6359
"integer":{"type":"integer"}
6460
}
6561
}'
6662
];
6763
yield [
68-
'{
69-
"number": 1.4
70-
}',
71-
'{
64+
'input' => '{ "number": 1.4 }',
65+
'schema' => '{
7266
"type":"object",
7367
"properties":{
7468
"number":{"type":"number"}
7569
}
7670
}'
7771
];
7872
yield [
79-
'{"number": 1e5}',
80-
'{
73+
'input' => '{"number": 1e5}',
74+
'schema' => '{
8175
"type": "object",
8276
"properties": {
8377
"number": {"type": "number"}
8478
}
8579
}'
8680
];
8781
yield [
88-
'{"number": 1}',
89-
'{
82+
'input' => '{"number": 1}',
83+
'schema' => '{
9084
"type": "object",
9185
"properties": {
9286
"number": {"type": "number"}
@@ -95,8 +89,8 @@ public function getValidTests(): \Generator
9589
}'
9690
];
9791
yield [
98-
'{"number": -49.89}',
99-
'{
92+
'input' => '{"number": -49.89}',
93+
'schema' => '{
10094
"type": "object",
10195
"properties": {
10296
"number": {

tests/Constraints/PatternPropertiesTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ public function getInvalidTests(): \Generator
7979

8080
public function getValidTests(): \Generator
8181
{
82-
[
83-
yield 'validates pattern schema' => json_encode([
82+
yield 'validates pattern schema' => [
83+
json_encode([
8484
'someobject' => [
8585
'foobar' => 'foo',
8686
'barfoo' => 'bar',

tests/Constraints/VeryBaseTestCase.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ abstract class VeryBaseTestCase extends TestCase
2020
protected function getUriRetrieverMock(?object $schema): object
2121
{
2222
$uriRetriever = $this->prophesize(UriRetrieverInterface::class);
23-
$uriRetriever->retrieve('http://www.my-domain.com/schema.json')
23+
$uriRetriever->retrieve($schema->id ?? 'http://www.my-domain.com/schema.json')
2424
->willReturn($schema)
2525
->shouldBeCalled();
2626

@@ -71,4 +71,9 @@ private function readAndJsonDecodeFile(string $file): stdClass
7171

7272
return json_decode(file_get_contents($file), false);
7373
}
74+
75+
protected function is32Bit(): bool
76+
{
77+
return PHP_INT_SIZE === 4;
78+
}
7479
}

tests/Drafts/Draft3Test.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ protected function getFilePaths(): array
7575
];
7676
}
7777

78+
public function getInvalidTests(): \Generator
79+
{
80+
$skip = [
81+
'ref.json / $ref prevents a sibling id from changing the base uri / $ref resolves to /definitions/base_foo, data does not validate'
82+
];
83+
84+
foreach (parent::getInvalidTests() as $name => $testcase) {
85+
if (in_array($name, $skip, true)) {
86+
continue;
87+
}
88+
yield $name => $testcase;
89+
}
90+
}
91+
7892
public function getInvalidForAssocTests(): \Generator
7993
{
8094
$skip = [
@@ -113,6 +127,7 @@ protected function getSkippedTests(): array
113127
return [
114128
// Optional
115129
'bignum.json',
130+
'ecmascript-regex.json',
116131
'format.json',
117132
'jsregex.json',
118133
'zeroTerminatedFloats.json'

0 commit comments

Comments
 (0)