Skip to content

Commit

Permalink
Enhancement: Implement ChainNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Jan 12, 2018
1 parent 7fc0f9d commit a8808df
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ $ composer require localheinz/json-normalizer
This package comes with the following normalizers:

* [`Localheinz\Json\Normalizer\CallableNormalizer`](#callablenormalizer)
* [`Localheinz\Json\Normalizer\ChainNormalizer`](#chainnormalizer)
* [`Localheinz\Json\Normalizer\FinalNewLineNormalizer`](#finalnewlinenormalizer)
* [`Localheinz\Json\Normalizer\IndentNormalizer`](#indentnormalizer)
* [`Localheinz\Json\Normalizer\JsonEncodeNormalizer`](#jsonencodenormalizer)
Expand Down Expand Up @@ -62,6 +63,33 @@ $normalized = $normalizer->normalize($json);

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

### `ChainNormalizer`

If you want to apply multiple normalizers in a chain, you can use the `ChainNormalizer`.

```php
use Localheinz\Json\Normalizer;

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

$normalizer = new Normalizer\ChainNormalizer(
new Normalizer\JsonEncodeNormalizer(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
new Normalizer\IndentNormalizer(' '),
new Normalizer\FinalNewLineNormalizer()
);

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

The normalized version will now contain the result of applying all normalizers in a chain, one after another.

:bulb: Be careful with the order of the normalizers, as one normalizer might override changes a previous normalizer applied.

### `FinalNewLineNormalizer`

If you want to ensure that a JSON file has a single final new line, you can use the `FinalNewLineNormalizer`.
Expand Down
43 changes: 43 additions & 0 deletions src/ChainNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?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 ChainNormalizer implements NormalizerInterface
{
/**
* @var NormalizerInterface[]
*/
private $normalizers;

public function __construct(NormalizerInterface ...$normalizers)
{
$this->normalizers = $normalizers;
}

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
));
}

foreach ($this->normalizers as $normalizer) {
$json = $normalizer->normalize($json);
}

return $json;
}
}
75 changes: 75 additions & 0 deletions test/Unit/ChainNormalizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?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\ChainNormalizer;
use Localheinz\Json\Normalizer\NormalizerInterface;
use Prophecy\Argument;

final class ChainNormalizerTest extends AbstractNormalizerTestCase
{
public function testNormalizePassesJsonThroughNormalizers()
{
$count = $this->faker()->numberBetween(3, 5);

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

$normalize = function (string $json, int $index) {
return \sprintf(
$json,
$index
);
};

$normalized = $normalize(
$json,
$count - 1
);

$normalizers = \array_fill(0, $count, null);

$normalizers = \array_map(function (int $index) use ($json, $normalize) {
$normalized = $normalize(
$json,
$index
);

if (0 < $index) {
$json = $normalize(
$json,
$index - 1
);
}

$normalizer = $this->prophesize(NormalizerInterface::class);

$normalizer
->normalize(Argument::exact($json))
->shouldBeCalled()
->willReturn($normalized);

return $normalizer->reveal();
}, \array_keys($normalizers));

$normalizer = new ChainNormalizer(...$normalizers);

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

0 comments on commit a8808df

Please sign in to comment.