Skip to content
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

Improve no property behavior and schema storage #6

Merged
merged 6 commits into from
Nov 20, 2020
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
vendor/
.phpunit*
.vscode/
.vscode/
/.idea/
/composer.lock
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"license": "GPL-3.0-or-later",
"require": {
"opis/json-schema": "^1.0",
"galbar/jsonpath": "^1.1"
"galbar/jsonpath": "^1.1",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^9.4"
Expand Down
62 changes: 39 additions & 23 deletions src/RootedJsonData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace RootedData;

use InvalidArgumentException;
use JsonPath\InvalidJsonException;
use Opis\JsonSchema\Schema;
use Opis\JsonSchema\Validator;
use JsonPath\JsonObject;
Expand All @@ -25,16 +27,19 @@ class RootedJsonData
* String of JSON data.
* @param string $schema
* JSON schema document for validation.
* @throws InvalidJsonException
*/
public function __construct(string $json = "{}", string $schema = "{}")
{
$decoded = json_decode($json);

if (!isset($decoded)) {
throw new \InvalidArgumentException("Invalid JSON: " . json_last_error_msg());
throw new InvalidArgumentException("Invalid JSON: " . json_last_error_msg());
}

$this->schema = Schema::fromJsonString($schema);
if (Schema::fromJsonString($schema)) {
$this->schema = $schema;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Occurs to me, another option to storing the schema as a string would be to store it as another JsonObject...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or on second thought, maybe as an decoded json object? That way the validator doesn't need to re-decode it every time, which is probably a bit expensive, althought, not THAT expensive. Probably fine as a string for now? Could go either way.

}

$data = new JsonObject($json, true);
$result = self::validate($data, $this->schema);
Expand All @@ -48,19 +53,19 @@ public function __construct(string $json = "{}", string $schema = "{}")
/**
* Validate a JsonObject.
*
* @param JsonPath\JsonObject $data
* @param JsonObject $data
* JsonData object to validate against schema.
* @param Opis\JsonSchema\Schema $schema
* And Opis Json-Schema schema object to validate data against.
* @param string $schema
* JSON Schema string.
*
* @return Opis\JsonSchema\ValidationResult
* @return ValidationResult
* Validation result object, contains error report if invalid.
*/
public static function validate(JsonObject $data, Schema $schema): ValidationResult
public static function validate(JsonObject $data, string $schema): ValidationResult
{
$opiSchema = Schema::fromJsonString($schema);
$validator = new Validator();
$result = $validator->schemaValidation(json_decode("{$data}"), $schema);
return $result;
return $validator->schemaValidation(json_decode("{$data}"), $opiSchema);
}

/**
Expand All @@ -80,26 +85,25 @@ public function __toString()
* @return mixed
* Result of JsonPath\JsonObject::__get()
*/
public function get($path)
public function get(string $path)
{
$result = $this->data->get($path);
if ($result === false) {
throw new \Exception("Property {$path} is not set");
if ($this->__isset($path) === false) {
return null;
}
return $result;
return $this->data->get($path);
}

/**
* @see JsonPath\JsonObject::__get()
*
* @param string $path
*
* @return mixed
* Result of JsonPath\JsonObject::__get()
* @see \JsonPath\JsonObject::__get()
*
*/
public function __get($path)
public function __get(string $path)
{
return $this->get($path);
return $this->data->get($path);
}

/**
Expand All @@ -108,9 +112,10 @@ public function __get($path)
* @param string $path
* @param mixed $value
*
* @return JsonPath\JsonObject
* @return JsonObject
* @throws InvalidJsonException
*/
public function set($path, $value)
public function set(string $path, $value)
{
$validationJsonObject = new JsonObject((string) $this->data);
$validationJsonObject->set($path, $value);
Expand All @@ -126,15 +131,26 @@ public function set($path, $value)
}

/**
* @see JsonPath\JsonObject::__set()
* @see \JsonPath\JsonObject::__get()
*
* @param mixed $path
* @param mixed $value
*
* @return JsonPath\JsonObject
* @return JsonObject
*/
public function __set($path, $value)
{
return $this->set($path, $value);
return $this->data->set($path, $value);
}

public function __isset($name)
{
$notSmart = new JsonObject("{$this->data}");
return $notSmart->get($name) ? true : false;
}

public function getSchema()
{
return $this->schema;
}
}
13 changes: 11 additions & 2 deletions tests/RootedJsonDatatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PHPUnit\Framework\TestCase;
use RootedData\RootedJsonData;
use Opis\JsonSchema\Exception\InvalidSchemaException;
use Opis\JsonSchema\Schema;
use RootedData\Exception\ValidationException;

class RootedJsonDataTest extends TestCase
Expand Down Expand Up @@ -39,9 +40,9 @@ public function testBracketSyntax()

public function testAccessToNonExistentProperties()
{
$this->expectExceptionMessage("Property $.city is not set");
$data = new RootedJsonData();
$city = $data->get("$.city");
$this->assertNull($data->get("$.city"));
$this->assertFalse(isset($data->{"$.city"}));
}

public function testJsonFormat()
Expand Down Expand Up @@ -110,4 +111,12 @@ public function testJsonPathSetter()
$data->set("$.container.number", 52);
$this->assertEquals(52, $data->get("$.container.number"));
}

public function testSchemaGetter()
{
$json = '{"number":51}';
$schema = '{"type": "object","properties":{"number":{"type":"number"}}}';
$data = new RootedJsonData($json, $schema);
$this->assertEquals($schema, $data->getSchema());
}
}