Skip to content

Commit

Permalink
Enhancement: Implement CallableNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Jan 12, 2018
1 parent 021e387 commit 49fde58
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,49 @@ $ composer require localheinz/json-normalizer

This package comes with the following normalizers:

* [`Localheinz\Json\Normalizer\CallableNormalizer`](#callablenormalizer)
* [`Localheinz\Json\Normalizer\FinalNewLineNormalizer`](#finalnewlinenormalizer)
* [`Localheinz\Json\Normalizer\IndentNormalizer`](#indentnormalizer)
* [`Localheinz\Json\Normalizer\JsonEncodeNormalizer`](#jsonencodenormalizer)
* [`Localheinz\Json\Normalizer\NoFinalNewLineNormalizer`](#nofinalnewlinenormalizer)

:bulb: All of these normalizers implement the `Localheinz\Json\Normalizer\NormalizerInterface`.

### `CallableNormalizer`

If you want to normalize a JSON file with a `callable`, you can use the `CallableNormalizer`.

```php
use Localheinz\Json\Normalizer;

$json = <<<'JSON'
{
"name": "Andreas Möller",
"url": "https://localheinz.com"
}
JSON;

$callable = function (string $json): string {
$decoded = json_decode($json);

foreach (get_object_vars($decoded) as $name => $value) {
if ('https://localheinz.com' !== $value) {
continue;
}

$decoded->{$name} .= '/open-source/';
}

return json_encode($decoded);
};

$normalizer = new Normalizer\CallableNormalizer($callable);

$normalized = $normalizer->normalize($json);
```

The normalized version will now have the callable applied to it.

### `FinalNewLineNormalizer`

If you want to ensure that a JSON file has a single final new line, you can use the `FinalNewLineNormalizer`.
Expand Down
41 changes: 41 additions & 0 deletions src/CallableNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

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

namespace Localheinz\Json\Normalizer;

final class CallableNormalizer implements NormalizerInterface
{
/**
* @var callable
*/
private $callable;

public function __construct(callable $callable)
{
$this->callable = $callable;
}

public function normalize(string $json): string
{
if (null === \json_decode($json) && JSON_ERROR_NONE !== \json_last_error()) {
throw new \InvalidArgumentException(\sprintf(
'"%s" is not valid JSON.',
$json
));
}

$callable = $this->callable;

return $callable($json);
}
}
86 changes: 86 additions & 0 deletions test/Unit/CallableNormalizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

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

namespace Localheinz\Json\Normalizer\Test\Unit;

use Localheinz\Json\Normalizer\CallableNormalizer;

final class CallableNormalizerTest extends AbstractNormalizerTestCase
{
/**
* @dataProvider providerCallable
*
* @param callable $callable
*/
public function testNormalizePassesJsonThroughCallable(callable $callable)
{
$json = <<<'JSON'
{
"name": "Andreas Möller",
"url": "https://localheinz.com",
"level": 1
}
JSON;

$normalized = $callable($json);

$normalizer = new CallableNormalizer($callable);

$this->assertSame($normalized, $normalizer->normalize($json));
}

public function providerCallable(): \Generator
{
$values = [
'closure' => function (string $json): string {
$decoded = \json_decode($json);

foreach (\get_object_vars($decoded) as $name => $value) {
if (!\is_int($value)) {
continue;
}

$decoded->{$name} = $value + 1;
}

return \json_encode($decoded);
},
'function-name' => 'trim',
'method' => [
self::class,
'callable',
],
];

foreach ($values as $key => $value) {
yield $key => [
$value,
];
}
}

public static function callable(string $json)
{
$decoded = \json_decode($json);

foreach (\get_object_vars($decoded) as $name => $value) {
if (!\is_string($value)) {
continue;
}

$decoded->{$name} = $value . ' (ok)';
}

return \json_encode($decoded);
}
}

0 comments on commit 49fde58

Please sign in to comment.