Skip to content

feat: update to latest json schema test suite #821

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 14 commits into from
Jun 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Update test case to current (PHP) standards ([#831](https://github.com/jsonrainbow/json-schema/pull/831))
- Upgrade test suite to use generators ([#834](https://github.com/jsonrainbow/json-schema/pull/834))
- update to latest json schema test suite ([#821](https://github.com/jsonrainbow/json-schema/pull/821))

## [6.4.2] - 2025-06-03
### Fixed
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "3.3.0",
"json-schema/json-schema-test-suite": "1.2.0",
"json-schema/json-schema-test-suite": "^23.2",
"phpunit/phpunit": "^8.5",
"phpspec/prophecy": "^1.19",
"phpstan/phpstan": "^1.12",
Expand All @@ -59,11 +59,11 @@
"type": "package",
"package": {
"name": "json-schema/json-schema-test-suite",
"version": "1.2.0",
"version": "23.2.0",
"source": {
"type": "git",
"url": "https://github.com/json-schema/JSON-Schema-Test-Suite",
"reference": "1.2.0"
"reference": "23.2.0"
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@
<directory>./src/JsonSchema/</directory>
</whitelist>
</filter>

<php>
<ini name="memory_limit" value="-1"/>
</php>
</phpunit>
48 changes: 34 additions & 14 deletions tests/Constraints/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ abstract class BaseTestCase extends VeryBaseTestCase
/**
* @dataProvider getInvalidTests
*
* @param int-mask-of<Constraint::CHECK_MODE_*> $checkMode
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
*/
public function testInvalidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL, array $errors = []): void
{
Expand All @@ -28,8 +28,9 @@ public function testInvalidCases(string $input, string $schema, ?int $checkMode
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
}

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

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

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

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

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

/**
* @dataProvider getValidTests
*
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
*/
public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_MODE_NORMAL): void
public function testValidCases(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_NORMAL): void
{
if ($this->validateSchema) {
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
}
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema, false)));
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');

$schema = json_decode($schema, false);
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock($schema));
$schema = $schemaStorage->getSchema($schema->id ?? 'http://www.my-domain.com/schema.json');
if (is_object($schema) && !isset($schema->{'$schema'})) {
$schema->{'$schema'} = $this->schemaSpec;
}
Expand All @@ -103,8 +111,10 @@ public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_M

/**
* @dataProvider getValidForAssocTests
*
* @param ?int-mask-of<Constraint::CHECK_MODE_*> $checkMode
*/
public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constraint::CHECK_MODE_TYPE_CAST): void
public function testValidCasesUsingAssoc(string $input, string $schema, ?int $checkMode = Constraint::CHECK_MODE_TYPE_CAST): void
{
if ($this->validateSchema) {
$checkMode |= Constraint::CHECK_MODE_VALIDATE_SCHEMA;
Expand All @@ -113,9 +123,9 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain
$this->markTestSkipped('Test indicates that it is not for "CHECK_MODE_TYPE_CAST"');
}

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

$errorMask = $validator->validate($value, $schema);
$this->assertEquals(0, $errorMask);
$this->assertEquals(0, $errorMask, $this->validatorErrorsToString($validator));
$this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true));
}

Expand All @@ -141,4 +151,14 @@ public function getInvalidForAssocTests(): Generator
{
yield from $this->getInvalidTests();
}

private function validatorErrorsToString(Validator $validator): string
{
return implode(
', ',
array_map(
static function (array $error) { return $error['message']; }, $validator->getErrors()
)
);
}
}
42 changes: 18 additions & 24 deletions tests/Constraints/NumberAndIntegerTypesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,35 @@ class NumberAndIntegerTypesTest extends BaseTestCase
public function getInvalidTests(): \Generator
{
yield [
'{
"integer": 1.4
}',
'{
'input' => '{ "integer": 1.4 }',
'schema' => '{
"type":"object",
"properties":{
"integer":{"type":"integer"}
}
}'
];
yield [
'{"integer": 1.001}',
'{
'input' => '{"integer": 1.001}',
'schema' => '{
"type": "object",
"properties": {
"integer": {"type": "integer"}
}
}'
];
yield [
'{"integer": true}',
'{
'input' => '{"integer": true}',
'schema' => '{
"type": "object",
"properties": {
"integer": {"type": "integer"}
}
}'
];
yield [
'{"number": "x"}',
'{
'input' => '{"number": "x"}',
'schema' => '{
"type": "object",
"properties": {
"number": {"type": "number"}
Expand All @@ -54,39 +52,35 @@ public function getInvalidTests(): \Generator
public function getValidTests(): \Generator
{
yield [
'{
"integer": 1
}',
'{
'input' => '{ "integer": 1 }',
'schema' => '{
"type":"object",
"properties":{
"integer":{"type":"integer"}
}
}'
];
yield [
'{
"number": 1.4
}',
'{
'input' => '{ "number": 1.4 }',
'schema' => '{
"type":"object",
"properties":{
"number":{"type":"number"}
}
}'
];
yield [
'{"number": 1e5}',
'{
'input' => '{"number": 1e5}',
'schema' => '{
"type": "object",
"properties": {
"number": {"type": "number"}
}
}'
];
yield [
'{"number": 1}',
'{
'input' => '{"number": 1}',
'schema' => '{
"type": "object",
"properties": {
"number": {"type": "number"}
Expand All @@ -95,8 +89,8 @@ public function getValidTests(): \Generator
}'
];
yield [
'{"number": -49.89}',
'{
'input' => '{"number": -49.89}',
'schema' => '{
"type": "object",
"properties": {
"number": {
Expand Down
4 changes: 2 additions & 2 deletions tests/Constraints/PatternPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public function getInvalidTests(): \Generator

public function getValidTests(): \Generator
{
[
yield 'validates pattern schema' => json_encode([
yield 'validates pattern schema' => [
json_encode([
'someobject' => [
'foobar' => 'foo',
'barfoo' => 'bar',
Expand Down
7 changes: 6 additions & 1 deletion tests/Constraints/VeryBaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ abstract class VeryBaseTestCase extends TestCase
protected function getUriRetrieverMock(?object $schema): object
{
$uriRetriever = $this->prophesize(UriRetrieverInterface::class);
$uriRetriever->retrieve('http://www.my-domain.com/schema.json')
$uriRetriever->retrieve($schema->id ?? 'http://www.my-domain.com/schema.json')
->willReturn($schema)
->shouldBeCalled();

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

return json_decode(file_get_contents($file), false);
}

protected function is32Bit(): bool
{
return PHP_INT_SIZE === 4;
}
}
15 changes: 15 additions & 0 deletions tests/Drafts/Draft3Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ protected function getFilePaths(): array
];
}

public function getInvalidTests(): \Generator
{
$skip = [
'ref.json / $ref prevents a sibling id from changing the base uri / $ref resolves to /definitions/base_foo, data does not validate'
];

foreach (parent::getInvalidTests() as $name => $testcase) {
if (in_array($name, $skip, true)) {
continue;
}
yield $name => $testcase;
}
}

public function getInvalidForAssocTests(): \Generator
{
$skip = [
Expand Down Expand Up @@ -113,6 +127,7 @@ protected function getSkippedTests(): array
return [
// Optional
'bignum.json',
'ecmascript-regex.json',
'format.json',
'jsregex.json',
'zeroTerminatedFloats.json'
Expand Down
Loading