Skip to content

Commit e75e20d

Browse files
authored
BREAKING CHANGE: Upgrade libraries, changing interfaces and introduci… (#19)
BREAKING CHANGE: Upgrade libraries, changing interfaces and introducing schema storage * `justinrainbow/json-schema` has been upgraded to the latest version (5.x) * Interface for `assertJsonMatchesSchema` has changed from `assertJsonMatchesSchema($schema, $content)` to `assertJsonMatchesSchema($content, $schema = null)` * Support for schema storage within traits (see README.md)
1 parent 2f66884 commit e75e20d

File tree

6 files changed

+141
-23
lines changed

6 files changed

+141
-23
lines changed

README.md

+58-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class MyTestCase extends \PHPUnit_Framework_TestCase
7979

8080
$json = json_decode('{"foo":1}');
8181

82-
$this->assertJsonMatchesSchema('./my-schema.json', $json);
82+
$this->assertJsonMatchesSchema($json, './my-schema.json');
8383
$this->assertJsonValueEquals(1, '* | [0]', $json);
8484
}
8585
}
@@ -115,7 +115,63 @@ class MyTestCase extends \PHPUnit_Framework_TestCase
115115

116116
$json = json_decode('{"foo":1}');
117117

118-
JsonAssert::assertJsonMatchesSchema('./my-schema.json', $json);
118+
JsonAssert::assertJsonMatchesSchema($json, './my-schema.json');
119+
JsonAssert::assertJsonValueEquals(1, '* | [0]', $json);
120+
}
121+
}
122+
```
123+
124+
## Schema storage
125+
126+
The [schema storage](https://github.com/justinrainbow/json-schema/blob/master/src/JsonSchema/SchemaStorage.php) of `justinrainbow/json-schema` allows to register schemas which will effectively override the actual schema location.
127+
128+
Example:
129+
```json
130+
{"$ref" : "https://iglu.foobar.com/myschema.json#/definitions/positiveInteger"}
131+
```
132+
133+
The resolver will fetch the schema from this endpoint and match the JSON document against it. Using schema storage you're able to override this behaviour.
134+
135+
```php
136+
$schemastorage->addSchema('https://iglu.foobar.com/myschema.json', (object)['type' => 'string']);
137+
```
138+
139+
With this in place the resolver will take the schema that is already in place without downloading it again.
140+
141+
```php
142+
<?php
143+
144+
namespace EnricoStahn\JsonAssert\Tests;
145+
146+
use EnricoStahn\JsonAssert\AssertClass as JsonAssert;
147+
148+
class MyTestCase extends \PHPUnit_Framework_TestCase
149+
{
150+
public function setUp()
151+
{
152+
self::$schemaStorage = new SchemaStorage();
153+
154+
self::$schemaStorage->addSchema('<id>', obj);
155+
...
156+
}
157+
158+
public function testJsonDocumentIsValid()
159+
{
160+
// my-schema.json
161+
//
162+
// {
163+
// "type" : "object",
164+
// "properties" : {
165+
// "foo" : {
166+
// "type" : "integer"
167+
// }
168+
// },
169+
// "required" : [ "foo" ]
170+
// }
171+
172+
$json = json_decode('{"foo":1}');
173+
174+
JsonAssert::assertJsonMatchesSchema($json, './my-schema.json');
119175
JsonAssert::assertJsonValueEquals(1, '* | [0]', $json);
120176
}
121177
}

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"minimum-stability": "stable",
1515
"require": {
1616
"php": "^7.0",
17-
"justinrainbow/json-schema": "^2.0",
17+
"justinrainbow/json-schema": "^5.0",
1818
"mtdowling/jmespath.php": "^2.3"
1919
},
2020
"require-dev": {

src/Assert.php

+45-13
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
namespace EnricoStahn\JsonAssert;
1313

14-
use JsonSchema\RefResolver;
15-
use JsonSchema\Uri\UriResolver;
16-
use JsonSchema\Uri\UriRetriever;
14+
use JsonSchema\Constraints\Factory;
15+
use JsonSchema\SchemaStorage;
1716
use JsonSchema\Validator;
17+
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
1818

1919
/**
2020
* Asserts to validate JSON data.
@@ -25,25 +25,40 @@
2525
*/
2626
trait Assert
2727
{
28+
/**
29+
* @var SchemaStorage
30+
*/
31+
private static $schemaStorage = null;
32+
2833
/**
2934
* Asserts that json content is valid according to the provided schema file.
3035
*
3136
* Example:
3237
*
33-
* static::assertJsonMatchesSchema('./schema.json', json_decode('{"foo":1}'))
38+
* static::assertJsonMatchesSchema(json_decode('{"foo":1}'), './schema.json')
3439
*
35-
* @param string $schema Path to the schema file
40+
* @param string|null $schema Path to the schema file
3641
* @param array|object $content JSON array or object
3742
*/
38-
public static function assertJsonMatchesSchema($schema, $content)
43+
public static function assertJsonMatchesSchema($content, $schema = null)
3944
{
40-
// Assume references are relative to the current file
41-
// Create an issue or pull request if you need more complex use cases
42-
$refResolver = new RefResolver(new UriRetriever(), new UriResolver());
43-
$schemaObj = $refResolver->resolve('file://'.realpath($schema));
45+
if (self::$schemaStorage === null) {
46+
self::$schemaStorage = new SchemaStorage();
47+
}
48+
49+
if ($schema !== null && !file_exists($schema)) {
50+
throw new FileNotFoundException($schema);
51+
}
52+
53+
$schemaObject = null;
4454

45-
$validator = new Validator();
46-
$validator->check($content, $schemaObj);
55+
if ($schema !== null) {
56+
$schemaObject = json_decode(file_get_contents($schema));
57+
self::$schemaStorage->addSchema('file://'.$schema, $schemaObject);
58+
}
59+
60+
$validator = new Validator(new Factory(self::$schemaStorage));
61+
$validator->validate($content, $schemaObject);
4762

4863
$message = '- Property: %s, Contraint: %s, Message: %s';
4964
$messages = array_map(function ($exception) use ($message) {
@@ -54,6 +69,23 @@ public static function assertJsonMatchesSchema($schema, $content)
5469
\PHPUnit\Framework\Assert::assertTrue($validator->isValid(), implode("\n", $messages));
5570
}
5671

72+
/**
73+
* Asserts that json content is valid according to the provided schema file.
74+
*
75+
* Example:
76+
*
77+
* static::assertJsonMatchesSchema(json_decode('{"foo":1}'), './schema.json')
78+
*
79+
* @param string|null $schema Path to the schema file
80+
* @param array|object $content JSON array or object
81+
*
82+
* @deprecated This will be removed in the next major version (4.x).
83+
*/
84+
public static function assertJsonMatchesSchemaDepr($schema, $content)
85+
{
86+
self::assertJsonMatchesSchema($content, $schema);
87+
}
88+
5789
/**
5890
* Asserts that json content is valid according to the provided schema string.
5991
*
@@ -65,7 +97,7 @@ public static function assertJsonMatchesSchemaString($schema, $content)
6597
$file = tempnam(sys_get_temp_dir(), 'json-schema-');
6698
file_put_contents($file, $schema);
6799

68-
self::assertJsonMatchesSchema($file, $content);
100+
self::assertJsonMatchesSchema($content, $file);
69101
}
70102

71103
/**

src/Extension/Symfony.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ trait Symfony
2828
*/
2929
public static function assertJsonMatchesSchema($schema, Response $response)
3030
{
31-
Assert::assertJsonMatchesSchema($schema, json_decode($response->getContent()));
31+
Assert::assertJsonMatchesSchemaDepr($schema, json_decode($response->getContent()));
3232
}
3333

3434
/**

tests/AssertTraitImpl.php

+19
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,28 @@
1212
namespace EnricoStahn\JsonAssert\Tests;
1313

1414
use EnricoStahn\JsonAssert\Assert as JsonAssert;
15+
use JsonSchema\SchemaStorage;
1516
use PHPUnit\Framework\TestCase;
1617

1718
class AssertTraitImpl extends TestCase
1819
{
1920
use JsonAssert;
21+
22+
public function setUp()
23+
{
24+
self::$schemaStorage = new SchemaStorage();
25+
}
26+
27+
/**
28+
* @param string $id
29+
* @param string $schema
30+
*
31+
* @return SchemaStorage
32+
*/
33+
public function testWithSchemaStore($id, $schema)
34+
{
35+
self::$schemaStorage->addSchema($id, $schema);
36+
37+
return self::$schemaStorage;
38+
}
2039
}

tests/AssertTraitTest.php

+17-6
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ public function testAssertJsonMatchesSchemaSimple()
2525
{
2626
$content = json_decode(file_get_contents(Utils::getJsonPath('assertJsonMatchesSchema_simple.json')));
2727

28-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('assertJsonMatchesSchema_simple.schema.json'), $content);
28+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('assertJsonMatchesSchema_simple.schema.json'), $content);
2929
}
3030

3131
public function testAssertJsonMatchesSchema()
3232
{
3333
$content = json_decode('{"foo":123}');
3434

35-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('test.schema.json'), $content);
35+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('test.schema.json'), $content);
3636
}
3737

3838
/**
@@ -42,7 +42,7 @@ public function testAssertJsonMatchesSchemaFail()
4242
{
4343
$content = json_decode('{"foo":"123"}');
4444

45-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('test.schema.json'), $content);
45+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('test.schema.json'), $content);
4646
}
4747

4848
public function testAssertJsonMatchesSchemaFailMessage()
@@ -52,7 +52,7 @@ public function testAssertJsonMatchesSchemaFailMessage()
5252
$exception = null;
5353

5454
try {
55-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('test.schema.json'), $content);
55+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('test.schema.json'), $content);
5656
} catch (ExpectationFailedException $exception) {
5757
self::assertContains('- Property: foo, Contraint: type, Message: String value found, but an integer is required', $exception->getMessage());
5858
self::assertContains('- Response: {"foo":"123"}', $exception->getMessage());
@@ -68,7 +68,7 @@ public function testAssertJsonMatchesSchemaWithRefs()
6868
{
6969
$content = json_decode('{"code":123, "message":"Nothing works."}');
7070

71-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('error.schema.json'), $content);
71+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('error.schema.json'), $content);
7272
}
7373

7474
/**
@@ -78,7 +78,7 @@ public function testAssertJsonMatchesSchemaWithRefsFails()
7878
{
7979
$content = json_decode('{"code":"123", "message":"Nothing works."}');
8080

81-
AssertTraitImpl::assertJsonMatchesSchema(Utils::getSchemaPath('error.schema.json'), $content);
81+
AssertTraitImpl::assertJsonMatchesSchemaDepr(Utils::getSchemaPath('error.schema.json'), $content);
8282
}
8383

8484
public function testAssertJsonMatchesSchemaString()
@@ -104,6 +104,17 @@ public function testAssertJsonValueEquals($expression, $value)
104104
AssertTraitImpl::assertJsonValueEquals($value, $expression, $content);
105105
}
106106

107+
public function testAssertWithSchemaStore()
108+
{
109+
$obj = new AssertTraitImpl();
110+
$obj->setUp();
111+
112+
$schemastore = $obj->testWithSchemaStore('foobar', (object) ['type' => 'string']);
113+
114+
self::assertInstanceOf('JsonSchema\SchemaStorage', $schemastore);
115+
self::assertEquals($schemastore->getSchema('foobar'), (object) ['type' => 'string']);
116+
}
117+
107118
public function assertJsonValueEqualsProvider()
108119
{
109120
return [

0 commit comments

Comments
 (0)