Skip to content

Commit

Permalink
Add more unit tests (jsonrainbow#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 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 committed Mar 17, 2017
1 parent 3d4efc3 commit c53c87b
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 20 deletions.
3 changes: 2 additions & 1 deletion src/JsonSchema/Constraints/StringConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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
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);
}
}
79 changes: 63 additions & 16 deletions tests/Uri/Retrievers/FileGetContentsTest.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,74 @@
<?php

namespace JsonSchema\Tests\Uri\Retrievers;

use JsonSchema\Uri\Retrievers\FileGetContents;

/**
* @group FileGetContents
*/
class FileGetContentsTest extends \PHPUnit_Framework_TestCase
namespace JsonSchema\Tests\Uri\Retrievers
{
use JsonSchema\Uri\Retrievers\FileGetContents;

/**
* @expectedException \JsonSchema\Exception\ResourceNotFoundException
* @group FileGetContents
*/
public function testFetchMissingFile()
class FileGetContentsTest extends \PHPUnit_Framework_TestCase
{
$res = new FileGetContents();
$res->retrieve(__DIR__ . '/Fixture/missing.json');
/**
* @expectedException \JsonSchema\Exception\ResourceNotFoundException
*/
public function testFetchMissingFile()
{
$res = new FileGetContents();
$res->retrieve(__DIR__ . '/Fixture/missing.json');
}

public function testFetchFile()
{
$res = new FileGetContents();
$result = $res->retrieve(__DIR__ . '/../Fixture/child.json');
$this->assertNotEmpty($result);
}

public function testFalseReturn()
{
$res = new FileGetContents();

$this->setExpectedException(
'\JsonSchema\Exception\ResourceNotFoundException',
'JSON schema not found at http://example.com/false'
);
$res->retrieve('http://example.com/false');
}

public function testFetchDirectory()
{
$res = new FileGetContents();

$this->setExpectedException(
'\JsonSchema\Exception\ResourceNotFoundException',
'JSON schema not found at file:///this/is/a/directory/'
);
$res->retrieve('file:///this/is/a/directory/');
}

public function testContentType()
{
$res = new FileGetContents();

$reflector = new \ReflectionObject($res);
$fetchContentType = $reflector->getMethod('fetchContentType');
$fetchContentType->setAccessible(true);

$this->assertTrue($fetchContentType->invoke($res, array('Content-Type: application/json')));
$this->assertFalse($fetchContentType->invoke($res, array('X-Some-Header: whateverValue')));
}
}
}

public function testFetchFile()
namespace JsonSchema\Uri\Retrievers
{
function file_get_contents($uri)
{
$res = new FileGetContents();
$result = $res->retrieve(__DIR__ . '/../Fixture/child.json');
$this->assertNotEmpty($result);
switch ($uri) {
case 'http://example.com/false': return false;
case 'file:///this/is/a/directory/': return '';
default: return \file_get_contents($uri);
}
}
}
Loading

0 comments on commit c53c87b

Please sign in to comment.