Skip to content

Commit

Permalink
Add more unit tests (#366)
Browse files Browse the repository at this point in the history
* Add test coverage for coercion API

* Complete test coverage for SchemaStorage

* Add test coverage for ObjectIterator

* Add tests for ConstraintError

* Add exception test for JsonPointer

* MabeEnum\Enum appears to use singletons - add testing const

* Don't check this line for coverage

mbstring is on all test platforms, so this line will never be reached.

* Add test for TypeConstraint::validateTypeNameWording()

* Add test for exception on TypeConstraint::validateType()

* PHPunit doesn't like an explanation with its @codeCoverageIgnore...

* Add various tests for UriRetriever

* Add tests for FileGetContents

* Add tests for JsonSchema\Uri\Retrievers\Curl

* Add missing bad-syntax test file

* Restrict ignore to the exception line only

* Fix exception scope
  • Loading branch information
erayd authored and bighappyface committed Mar 17, 2017
1 parent b8d2611 commit 705dcbd
Show file tree
Hide file tree
Showing 14 changed files with 396 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/JsonSchema/ConstraintError.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ConstraintError extends \MabeEnum\Enum
const MAXIMUM = 'maximum';
const MIN_ITEMS = 'minItems';
const MINIMUM = 'minimum';
const MISSING_ERROR = 'missingError';
const MISSING_MAXIMUM = 'missingMaximum';
const MISSING_MINIMUM = 'missingMinimum';
const MAX_ITEMS = 'maxItems';
Expand Down Expand Up @@ -83,6 +84,7 @@ public function getMessage()
self::MINIMUM => 'Must have a minimum value greater than or equal to %d',
self::MISSING_MAXIMUM => 'Use of exclusiveMaximum requires presence of maximum',
self::MISSING_MINIMUM => 'Use of exclusiveMinimum requires presence of minimum',
/*self::MISSING_ERROR => 'Used for tests; this error is deliberately commented out',*/
self::MULTIPLE_OF => 'Must be a multiple of %d',
self::NOT => 'Matched a schema which it should not',
self::ONE_OF => 'Failed to match exactly one schema',
Expand Down
3 changes: 2 additions & 1 deletion src/JsonSchema/Constraints/StringConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private function strlen($string)
return mb_strlen($string, mb_detect_encoding($string));
}

return strlen($string);
// mbstring is present on all test platforms, so strlen() can be ignored for coverage
return strlen($string); // @codeCoverageIgnore
}
}
4 changes: 3 additions & 1 deletion src/JsonSchema/Uri/Retrievers/Curl.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace JsonSchema\Uri\Retrievers;

use JsonSchema\Exception\RuntimeException;
use JsonSchema\Validator;

/**
Expand All @@ -23,7 +24,8 @@ class Curl extends AbstractRetriever
public function __construct()
{
if (!function_exists('curl_init')) {
throw new \RuntimeException('cURL not installed');
// Cannot test this, because curl_init is present on all test platforms plus mock
throw new RuntimeException('cURL not installed'); // @codeCoverageIgnore
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/JsonSchema/Uri/Retrievers/FileGetContents.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ public function retrieve($uri)

$this->messageBody = $response;
if (!empty($http_response_header)) {
$this->fetchContentType($http_response_header);
} else {
// $http_response_header cannot be tested, because it's defined in the method's local scope
// See http://php.net/manual/en/reserved.variables.httpresponseheader.php for more info.
$this->fetchContentType($http_response_header); // @codeCoverageIgnore
} else { // @codeCoverageIgnore
// Could be a "file://" url or something else - fake up the response
$this->contentType = null;
}
Expand Down
32 changes: 32 additions & 0 deletions tests/ConstraintErrorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Tests;

use JsonSchema\ConstraintError;

class ConstraintErrorTest extends \PHPUnit_Framework_TestCase
{
public function testGetValidMessage()
{
$e = ConstraintError::ALL_OF();
$this->assertEquals('Failed to match all schemas', $e->getMessage());
}

public function testGetInvalidMessage()
{
$e = ConstraintError::MISSING_ERROR();

$this->setExpectedException(
'\JsonSchema\Exception\InvalidArgumentException',
'Missing error message for missingError'
);
$e->getMessage();
}
}
9 changes: 9 additions & 0 deletions tests/Constraints/CoerciveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ public function testInvalidCoerceCasesUsingAssoc($input, $schema, $errors = arra
$this->assertFalse($validator->isValid(), print_r($validator->getErrors(), true));
}

public function testCoerceAPI()
{
$input = json_decode('{"propertyOne": "10"}');
$schema = json_decode('{"properties":{"propertyOne":{"type":"number"}}}');
$v = new Validator();
$v->coerce($input, $schema);
$this->assertEquals('{"propertyOne":10}', json_encode($input));
}

public function getValidCoerceTests()
{
return array(
Expand Down
27 changes: 27 additions & 0 deletions tests/Constraints/TypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,31 @@ private function assertTypeConstraintError($expected, TypeConstraint $actual)
$this->assertEquals($expected, $actualMessage); // first equal for the diff
$this->assertSame($expected, $actualMessage); // the same for the strictness
}

public function testValidateTypeNameWording()
{
$t = new TypeConstraint();
$r = new \ReflectionObject($t);
$m = $r->getMethod('validateTypeNameWording');
$m->setAccessible(true);

$this->setExpectedException(
'\UnexpectedValueException',
"No wording for 'notAValidTypeName' available, expected wordings are: [an integer, a number, a boolean, an object, an array, a string, a null]"
);
$m->invoke($t, 'notAValidTypeName');
}

public function testValidateTypeException()
{
$t = new TypeConstraint();
$data = new \StdClass();
$schema = json_decode('{"type": "notAValidTypeName"}');

$this->setExpectedException(
'JsonSchema\Exception\InvalidArgumentException',
'object is an invalid type for notAValidTypeName'
);
$t->check($data, $schema);
}
}
9 changes: 9 additions & 0 deletions tests/Entity/JsonPointerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,13 @@ public function testJsonPointerWithPropertyPaths()
$this->assertEquals(array('~definitions/general', '%custom%'), $modified->getPropertyPaths());
$this->assertEquals('#/~0definitions~1general/%25custom%25', $modified->getPropertyPathAsString());
}

public function testCreateWithInvalidValue()
{
$this->setExpectedException(
'\JsonSchema\Exception\InvalidArgumentException',
'Ref value must be a string'
);
new JsonPointer(null);
}
}
89 changes: 89 additions & 0 deletions tests/Iterators/ObjectIteratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Tests\Iterators;

use JsonSchema\Iterator\ObjectIterator;

class ObjectIteratorTest extends \PHPUnit_Framework_TestCase
{
protected $testObject;

public function setUp()
{
$this->testObject = (object) array(
'subOne' => (object) array(
'propertyOne' => 'valueOne',
'propertyTwo' => 'valueTwo',
'propertyThree' => 'valueThree'
),
'subTwo' => (object) array(
'propertyFour' => 'valueFour',
'subThree' => (object) array(
'propertyFive' => 'valueFive',
'propertySix' => 'valueSix'
)
),
'propertySeven' => 'valueSeven'
);
}

public function testCreate()
{
$i = new ObjectIterator($this->testObject);

$this->assertInstanceOf('\JsonSchema\Iterator\ObjectIterator', $i);
}

public function testInitialState()
{
$i = new ObjectIterator($this->testObject);

$this->assertEquals($this->testObject, $i->current());
}

public function testCount()
{
$i = new ObjectIterator($this->testObject);

$this->assertEquals(4, $i->count());
}

public function testKey()
{
$i = new ObjectIterator($this->testObject);

while ($i->key() != 2) {
$i->next();
}

$this->assertEquals($this->testObject->subTwo->subThree, $i->current());
}

public function testAlwaysObjects()
{
$i= new ObjectIterator($this->testObject);

foreach ($i as $item) {
$this->assertInstanceOf('\StdClass', $item);
}
}

public function testReachesAllProperties()
{
$i = new ObjectIterator($this->testObject);

$count = 0;
foreach ($i as $item) {
$count += count(get_object_vars($item));
}

$this->assertEquals(10, $count);
}
}
14 changes: 14 additions & 0 deletions tests/SchemaStorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,18 @@ private function getInvalidSchema()
)
);
}

public function testGetUriRetriever()
{
$s = new SchemaStorage();
$s->addSchema('http://json-schema.org/draft-04/schema#');
$this->assertInstanceOf('\JsonSchema\Uri\UriRetriever', $s->getUriRetriever());
}

public function testGetUriResolver()
{
$s = new SchemaStorage();
$s->addSchema('http://json-schema.org/draft-04/schema#');
$this->assertInstanceOf('\JsonSchema\Uri\UriResolver', $s->getUriResolver());
}
}
57 changes: 57 additions & 0 deletions tests/Uri/Retrievers/CurlTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace JsonSchema\Tests\Uri\Retrievers
{
use JsonSchema\Uri\Retrievers\Curl;

class CurlTest extends \PHPUnit_Framework_TestCase
{
public function testRetrieveFile()
{
$c = new Curl();
$c->retrieve(realpath(__DIR__ . '/../../fixtures/foobar.json'));
}

public function testRetrieveNonexistantFile()
{
$c = new Curl();

$this->setExpectedException(
'\JsonSchema\Exception\ResourceNotFoundException',
'JSON schema not found'
);
$c->retrieve(__DIR__ . '/notARealFile');
}

public function testNoContentType()
{
$c = new Curl();
$c->retrieve(realpath(__DIR__ . '/../../fixtures') . '/foobar-noheader.json');
}
}
}

namespace JsonSchema\Uri\Retrievers
{
function curl_exec($curl)
{
$uri = curl_getinfo($curl, \CURLINFO_EFFECTIVE_URL);

if ($uri === realpath(__DIR__ . '/../../fixtures/foobar.json')) {
// return file with headers
$headers = implode("\n", array(
'Content-Type: application/json'
));

return sprintf("%s\r\n\r\n%s", $headers, file_get_contents($uri));
} elseif ($uri === realpath(__DIR__ . '/../../fixtures') . '/foobar-noheader.json') {
// return file without headers
$uri = realpath(__DIR__ . '/../../fixtures/foobar.json');

return "\r\n\r\n" . file_get_contents($uri);
}

// fallback to real curl_exec
return \curl_exec($curl);
}
}
Loading

0 comments on commit 705dcbd

Please sign in to comment.