Skip to content

Commit

Permalink
Merge pull request #5 from ergebnis/feature/decoder
Browse files Browse the repository at this point in the history
Enhancement: Implement Decoder
  • Loading branch information
ergebnis-bot authored Feb 2, 2021
2 parents 8433d34 + 07a3606 commit 5fbc3a3
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 54 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ For a full diff see [`dcd4cfb...main`][dcd4cfb...main].

* Added `Json` ([#2]), by [@localheinz]
* Added `Schema` ([#3]), by [@localheinz]
* Added `Decoder` ([#5]), by [@localheinz]

[dcd4cfb...main]: https://github.com/ergebnis/json-schema-validator/compare/dcd4cfb...main

[#2]: https://github.com/ergebnis/json-schema-validator/pull/2
[#3]: https://github.com/ergebnis/json-schema-validator/pull/3
[#5]: https://github.com/ergebnis/json-schema-validator/pull/5

[@localheinz]: https://github.com/localheinz
4 changes: 2 additions & 2 deletions infection.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"logs": {
"text": ".build/infection/infection-log.txt"
},
"minCoveredMsi": 92,
"minMsi": 88,
"minCoveredMsi": 82,
"minMsi": 78,
"phpUnit": {
"configDir": "test\/Unit"
},
Expand Down
26 changes: 26 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.4.1@9fd7a7d885b3a216cff8dec9d8c21a132f275224">
<file src="src/Decoder.php">
<MixedAssignment occurrences="2">
<code>$decoded</code>
<code>$decoded</code>
</MixedAssignment>
<MixedInferredReturnType occurrences="2">
<code>null|array|bool|float|int|\stdClass|string</code>
<code>null|array|bool|float|int|string</code>
</MixedInferredReturnType>
<MixedReturnStatement occurrences="2">
<code>$decoded</code>
<code>$decoded</code>
</MixedReturnStatement>
</file>
<file src="src/Json.php">
<MixedAssignment occurrences="2">
<code>$decoded</code>
<code>$decoded</code>
</MixedAssignment>
</file>
<file src="test/DataProvider/JsonProvider.php">
<MoreSpecificReturnType occurrences="2">
<code>\Generator&lt;string, array{0: string}&gt;</code>
<code>\Generator&lt;string, array{0: string}&gt;</code>
</MoreSpecificReturnType>
</file>
<file src="test/Unit/DecoderTest.php">
<MixedAssignment occurrences="2">
<code>$expected</code>
<code>$expected</code>
</MixedAssignment>
</file>
<file src="test/Unit/SchemaTest.php">
<MixedAssignment occurrences="1">
<code>$decoded</code>
Expand Down
55 changes: 55 additions & 0 deletions src/Decoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-schema-validator
*/

namespace Ergebnis\Json\SchemaValidator;

final class Decoder
{
/**
* @throws Exception\InvalidJson
*
* @return null|array|bool|float|int|string
*/
public function decodeAssociative(string $value)
{
$decoded = \json_decode(
$value,
true
);

if (null === $decoded && \JSON_ERROR_NONE !== \json_last_error()) {
throw Exception\InvalidJson::string();
}

return $decoded;
}

/**
* @throws Exception\InvalidJson
*
* @return null|array|bool|float|int|\stdClass|string
*/
public function decodeNonAssociative(string $value)
{
$decoded = \json_decode(
$value,
false
);

if (null === $decoded && \JSON_ERROR_NONE !== \json_last_error()) {
throw Exception\InvalidJson::string();
}

return $decoded;
}
}
66 changes: 66 additions & 0 deletions test/DataProvider/JsonProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-schema-validator
*/

namespace Ergebnis\Json\SchemaValidator\Test\DataProvider;

use Ergebnis\Test\Util;

final class JsonProvider
{
use Util\Helper;

/**
* @return \Generator<string, array{0: string}>
*/
public static function validString(): \Generator
{
yield from self::provideDataForValues(\array_map(static function (string $file): string {
$contents
= \file_get_contents($file);

if (!\is_string($contents)) {
throw new \RuntimeException(\sprintf(
'File "%s" does not exist or can not be read.',
$file
));
}

return $contents;
}, self::filesContainingValidJson()));
}

/**
* @return \Generator<string, array{0: string}>
*/
public function validFile(): \Generator
{
yield from self::provideDataForValues(self::filesContainingValidJson());
}

/**
* @return array<string, string>
*/
private static function filesContainingValidJson(): array
{
return [
'array' => __DIR__ . '/../Fixture/Json/valid/array.json',
'bool-false' => __DIR__ . '/../Fixture/Json/valid/bool-false.json',
'bool-true' => __DIR__ . '/../Fixture/Json/valid/bool-true.json',
'float' => __DIR__ . '/../Fixture/Json/valid/float.json',
'int' => __DIR__ . '/../Fixture/Json/valid/int.json',
'object' => __DIR__ . '/../Fixture/Json/valid/object.json',
'string-arbitrary' => __DIR__ . '/../Fixture/Json/valid/string-arbitrary.json',
'string-empty' => __DIR__ . '/../Fixture/Json/valid/string-empty.json',
];
}
}
93 changes: 93 additions & 0 deletions test/Unit/DecoderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-schema-validator
*/

namespace Ergebnis\Json\SchemaValidator\Test\Unit;

use Ergebnis\Json\SchemaValidator\Decoder;
use Ergebnis\Json\SchemaValidator\Exception;
use Ergebnis\Test\Util;
use PHPUnit\Framework;

/**
* @internal
*
* @covers \Ergebnis\Json\SchemaValidator\Decoder
*
* @uses \Ergebnis\Json\SchemaValidator\Exception\InvalidJson
*/
final class DecoderTest extends Framework\TestCase
{
use Util\Helper;

public function testDecodeAssociativeThrowsExceptionWhenValueCanNotBeDecoded(): void
{
$value = <<<'TXT'
{
"foo:
TXT;

$decoder = new Decoder();

$this->expectException(Exception\InvalidJson::class);

$decoder->decodeAssociative($value);
}

/**
* @dataProvider \Ergebnis\Json\SchemaValidator\Test\DataProvider\JsonProvider::validString()
*/
public function testDecodeAssociativeReturnsJsonDecodedValue(string $encoded): void
{
$decoder = new Decoder();

$decoded = $decoder->decodeAssociative($encoded);

$expected = \json_decode(
$encoded,
true
);

self::assertSame($expected, $decoded);
}

public function testDecodeNonAssociativeThrowsExceptionWhenValueCanNotBeDecoded(): void
{
$value = <<<'TXT'
{
"foo:
TXT;

$decoder = new Decoder();

$this->expectException(Exception\InvalidJson::class);

$decoder->decodeAssociative($value);
}

/**
* @dataProvider \Ergebnis\Json\SchemaValidator\Test\DataProvider\JsonProvider::validString()
*/
public function testDecodeNonAssociativeReturnsJsonDecodedValue(string $encoded): void
{
$decoder = new Decoder();

$decoded = $decoder->decodeNonAssociative($encoded);

$expected = \json_decode(
$encoded,
false
);

self::assertEquals($expected, $decoded);
}
}
54 changes: 2 additions & 52 deletions test/Unit/JsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function testFromStringThrowsWhenValueIsNotJson(): void
}

/**
* @dataProvider provideValidJsonString
* @dataProvider \Ergebnis\Json\SchemaValidator\Test\DataProvider\JsonProvider::validString()
*/
public function testFromStringReturnsJsonWhenValueIsValidJson(string $encoded): void
{
Expand All @@ -52,27 +52,6 @@ public function testFromStringReturnsJsonWhenValueIsValidJson(string $encoded):
self::assertSame($encoded, $json->encoded());
}

/**
* @return \Generator<string, array{0: string}>
*/
public function provideValidJsonString(): \Generator
{
foreach (self::filesContainingValidJson() as $key => $value) {
$content = \file_get_contents($value);

if (!\is_string($content)) {
throw new \RuntimeException(\sprintf(
'File "%s" does not exist or can not be read.',
$value
));
}

yield $key => [
$content,
];
}
}

public function testFromFileThrowsWhenFileDoesNotExist(): void
{
$file = __DIR__ . '/../Fixture/Json/does-not-exist.json';
Expand Down Expand Up @@ -101,41 +80,12 @@ public function testFromFileThrowsWhenFileDoesNotContainValidJson(): void
}

/**
* @dataProvider provideValidJsonFile
* @dataProvider \Ergebnis\Json\SchemaValidator\Test\DataProvider\JsonProvider::validFile()
*/
public function testFromFileReturnsJsonWhenFileContainsValidJson(string $file): void
{
$json = Json::fromFile($file);

self::assertStringEqualsFile($file, $json->encoded());
}

/**
* @return \Generator<string, array{0: string}>
*/
public function provideValidJsonFile(): \Generator
{
foreach (self::filesContainingValidJson() as $key => $value) {
yield $key => [
$value,
];
}
}

/**
* @return array<string, string>
*/
private static function filesContainingValidJson(): array
{
return [
'array' => __DIR__ . '/../Fixture/Json/valid/array.json',
'bool-false' => __DIR__ . '/../Fixture/Json/valid/bool-false.json',
'bool-true' => __DIR__ . '/../Fixture/Json/valid/bool-true.json',
'float' => __DIR__ . '/../Fixture/Json/valid/float.json',
'int' => __DIR__ . '/../Fixture/Json/valid/int.json',
'object' => __DIR__ . '/../Fixture/Json/valid/object.json',
'string-arbitrary' => __DIR__ . '/../Fixture/Json/valid/string-arbitrary.json',
'string-empty' => __DIR__ . '/../Fixture/Json/valid/string-empty.json',
];
}
}

0 comments on commit 5fbc3a3

Please sign in to comment.