Skip to content

Commit 43df498

Browse files
committed
Initial version
1 parent a496882 commit 43df498

File tree

11 files changed

+468
-17
lines changed

11 files changed

+468
-17
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
composer.phar
2-
/vendor/
3-
4-
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
5-
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6-
# composer.lock
1+
vendor/
2+
tests/log/
3+
composer.lock

.travis.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
sudo: false
2+
3+
language: php
4+
5+
php:
6+
- 5.4
7+
- 5.5
8+
- 5.6
9+
- 7
10+
- hhvm
11+
12+
matrix:
13+
include:
14+
- php: 5.4
15+
env: 'COMPOSER_FLAGS="--prefer-stable --prefer-lowest"'
16+
allow_failures:
17+
- php: hhvm
18+
19+
before_script:
20+
- travis_retry composer self-update
21+
- travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source
22+
23+
script:
24+
- phpunit --coverage-text
25+
26+
after_script:
27+
- php vendor/bin/codacycoverage clover build/logs/clover.xml
28+
- wget https://scrutinizer-ci.com/ocular.phar
29+
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml

README.md

Lines changed: 102 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,113 @@ JSON assertions for PHPUnit includes traits/methods to help validate your JSON d
55
## Features
66

77
* Validate your JSON data via JSON Schema
8+
* describes your existing data format
9+
* clear, human- and machine-readable documentation
10+
* complete structural validation, useful for
11+
* automated testing
12+
* validating client-submitted data
13+
* See more details [here](http://json-schema.org/)
14+
* Access JSON data through expressions (e.g. `foo.bar[3]`)
15+
* See more details [here](http://jmespath.org/examples.html)
816

9-
## JSON Schema
17+
## Install
1018

11-
* describes your existing data format
12-
* clear, human- and machine-readable documentation
13-
* complete structural validation, useful for
14-
* automated testing
15-
* validating client-submitted data
19+
$ composer require estahn/phpunit-json-assertions --dev
20+
21+
or in your `composer.json`:
1622

17-
See more details [here](http://json-schema.org/).
23+
{
24+
"require-dev": {
25+
"estahn/phpunit-json-assertions": "@stable"
26+
}
27+
}
1828

19-
## Install
20-
### Composer
29+
## Asserts
2130

22-
composer require estahn/phpunit-json-assertions
31+
| Assert | Description |
32+
| ----------------------------- | ---------------------------------------------------------------------------- |
33+
| assertJsonMatchesSchema | Asserts that json content is valid according to the provided schema file |
34+
| assertJsonMatchesSchemaString | Asserts that json content is valid according to the provided schema string |
35+
| assertJsonValueEquals | Asserts if the value retrieved with the expression equals the expected value |
2336

2437
## Usage
2538

26-
## Demo
39+
You can either use the `trait` or `class` version.
40+
41+
### Trait
42+
43+
<?php
44+
45+
namespace EnricoStahn\JsonAssert\Tests;
46+
47+
use EnricoStahn\JsonAssert\Assert as JsonAssert;
48+
49+
class MyTestCase extends \PHPUnit_Framework_TestCase
50+
{
51+
use JsonAssert;
52+
53+
public function testJsonDocumentIsValid()
54+
{
55+
// my-schema.json
56+
//
57+
// {
58+
// "type" : "object",
59+
// "properties" : {
60+
// "foo" : {
61+
// "type" : "integer"
62+
// }
63+
// },
64+
// "required" : [ "foo" ]
65+
// }
66+
67+
$json = json_decode('{"foo":1}');
68+
69+
$this->assertJsonMatchesSchemaString('./my-schema.json', $json);
70+
$this->assertJsonValueEquals(1, '* | [0]', $json);
71+
}
72+
}
73+
74+
### Class
75+
76+
In case you don't want to use the `trait` you can use the provided class wich extends from `\PHPUnit_Framework_TestCase`.
77+
You can either extend your test case or use the static methods like below.
78+
79+
<?php
80+
81+
namespace EnricoStahn\JsonAssert\Tests;
82+
83+
use EnricoStahn\JsonAssert\AssertClass as JsonAssert;
84+
85+
class MyTestCase extends \PHPUnit_Framework_TestCase
86+
{
87+
public function testJsonDocumentIsValid()
88+
{
89+
// my-schema.json
90+
//
91+
// {
92+
// "type" : "object",
93+
// "properties" : {
94+
// "foo" : {
95+
// "type" : "integer"
96+
// }
97+
// },
98+
// "required" : [ "foo" ]
99+
// }
100+
101+
$json = json_decode('{"foo":1}');
102+
103+
JsonAssert::assertJsonMatchesSchemaString('./my-schema.json', $json);
104+
JsonAssert::assertJsonValueEquals(1, '* | [0]', $json);
105+
}
106+
}
107+
108+
## Tests
109+
110+
To run the test suite, you need [composer](http://getcomposer.org).
111+
112+
$ composer install
113+
$ bin/phpunit
114+
115+
## License
116+
117+
The phpunit-json-assertions library is licensed under the [MIT](LICENSE).

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "estahn/phpunit-json-assertions",
3+
"type": "library",
4+
"description": "JSON assertions for PHPUnit (including JSON Schema)",
5+
"keywords": ["json", "phpunit", "schema"],
6+
"homepage": "https://github.com/estahn/phpunit-json-assertions",
7+
"license": "MIT",
8+
"authors": [
9+
{
10+
"name": "Enrico Stahn",
11+
"email": "enrico.stahn@gmail.com"
12+
}
13+
],
14+
"minimum-stability": "dev",
15+
"require": {
16+
"php": ">=5.4.0",
17+
"justinrainbow/json-schema": "^1.6",
18+
"mtdowling/jmespath.php": "^2.3"
19+
},
20+
"require-dev": {
21+
"phpunit/phpunit": "^5.2"
22+
},
23+
"autoload": {
24+
"psr-4": {
25+
"EnricoStahn\\JsonAssert\\": "src/"
26+
}
27+
},
28+
"autoload-dev": {
29+
"psr-4": {
30+
"EnricoStahn\\JsonAssert\\Tests\\": "tests/"
31+
}
32+
}
33+
}

phpunit.xml.dist

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
4+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
6+
backupGlobals="false"
7+
colors="true"
8+
bootstrap="vendor/autoload.php"
9+
>
10+
<testsuites>
11+
<testsuite name="phpunit-json-assertions Test Suite">
12+
<directory>tests/</directory>
13+
</testsuite>
14+
</testsuites>
15+
16+
<filter>
17+
<whitelist>
18+
<directory suffix=".php">src/JsonAssert/</directory>
19+
</whitelist>
20+
</filter>
21+
22+
<logging>
23+
<log type="coverage-clover" target="build/logs/clover.xml"/>
24+
<log type="coverage-html" target="build/logs/report" charset="UTF-8"
25+
yui="true" highlight="true"
26+
lowUpperBound="50" highLowerBound="80"/>
27+
<log type="testdox-html" target="build/logs/testdox.html" />
28+
</logging>
29+
30+
</phpunit>

src/Assert.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpunit-json-assertions package.
5+
*
6+
* (c) Enrico Stahn <enrico.stahn@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace EnricoStahn\JsonAssert;
13+
14+
use JsonSchema\RefResolver;
15+
use JsonSchema\Uri\UriRetriever;
16+
use JsonSchema\Validator;
17+
18+
/**
19+
* Asserts to validate JSON data
20+
*
21+
* - All assert methods expect deserialised JSON data (an actual object or array)
22+
* since the deserialisation method should be up to the user.
23+
* - We provide a convenience method to transfer whatever into a JSON object (see ::getJsonObject(mixed))
24+
*/
25+
trait Assert
26+
{
27+
/**
28+
* Asserts that json content is valid according to the provided schema file
29+
*
30+
* Example:
31+
*
32+
* static::assertJsonMatchesSchema(json_decode('{"foo":1}'), './schema.json')
33+
*
34+
* @param string $schema Path to the schema file
35+
* @param array|object $content JSON array or object
36+
*/
37+
public static function assertJsonMatchesSchema($schema, $content)
38+
{
39+
$retriever = new UriRetriever();
40+
$schema = $retriever->retrieve('file://' . realpath($schema));
41+
42+
$refResolver = new RefResolver($retriever);
43+
$refResolver->resolve($schema, 'file://' . __DIR__ . '/../Resources/schemas/');
44+
45+
$validator = new Validator();
46+
$validator->check($content, $schema);
47+
48+
$message = '- Property: %s, Contraint: %s, Message: %s';
49+
$messages = array_map(function ($e) use ($message) {
50+
return sprintf($message, $e['property'], $e['constraint'], $e['message']);
51+
}, $validator->getErrors());
52+
$messages[] = '- Response: ' . json_encode($content);
53+
54+
self::assertTrue($validator->isValid(), implode("\n", $messages));
55+
}
56+
57+
/**
58+
* Asserts that json content is valid according to the provided schema string
59+
*
60+
* @param string $schema Schema data
61+
* @param array|object $content JSON content
62+
*/
63+
public static function assertJsonMatchesSchemaString($schema, $content)
64+
{
65+
$file = tempnam(sys_get_temp_dir(), 'json-schema-');
66+
file_put_contents($file, $schema);
67+
68+
self::assertJsonMatchesSchema($file, $content);
69+
}
70+
71+
/**
72+
* Asserts if the value retrieved with the expression equals the expected value
73+
*
74+
* Example:
75+
*
76+
* static::assertJsonValueEquals(33, 'foo.bar[0]', $json);
77+
*
78+
* @param mixed $expected Expected value
79+
* @param string $expression Expression to retrieve the result (e.g. locations[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)})
80+
* @param array|object $json JSON Content
81+
*/
82+
public static function assertJsonValueEquals($expected, $expression, $json)
83+
{
84+
$result = self::search($expression, $json);
85+
86+
self::assertEquals($expected, $result);
87+
self::assertInternalType(gettype($expected), $result);
88+
}
89+
90+
/**
91+
* @param $expression
92+
* @param $data
93+
* @return mixed|null
94+
*/
95+
public static function search($expression, $data)
96+
{
97+
return \JmesPath\Env::search($expression, $data);
98+
}
99+
100+
/**
101+
* Helper method to deserialise a JSON string into an object
102+
*
103+
* @param mixed $data The JSON string
104+
* @return array|object
105+
*/
106+
public static function getJsonObject($data)
107+
{
108+
return (is_array($data) || is_object($data)) ? $data : json_decode($data);
109+
}
110+
}

src/AssertClass.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace EnricoStahn\JsonAssert;
4+
5+
class AssertClass extends \PHPUnit_Framework_TestCase
6+
{
7+
use Assert;
8+
}

tests/AssertTraitImpl.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpunit-json-assertions package.
5+
*
6+
* (c) Enrico Stahn <enrico.stahn@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace EnricoStahn\JsonAssert\Tests;
13+
14+
use EnricoStahn\JsonAssert\Assert as JsonAssert;
15+
16+
class AssertTraitImpl extends \PHPUnit_Framework_TestCase
17+
{
18+
use JsonAssert;
19+
}

0 commit comments

Comments
 (0)