Skip to content

Commit

Permalink
Enhancement: Implement IndentNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Jan 12, 2018
1 parent 86915d2 commit fa0c00b
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ Run
$ composer require localheinz/json-normalizer
```

## Usage

This package comes with the following normalizers:

* [`Localheinz\Json\Normalizer\IndentNormalizer`](#IndentNormalizer)

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

### `IndentNormalizer`

If you need to adjust the indentation of a JSON file, you can use the `IndentNormalizer`.

```php
use Localheinz\Json\Normalizer;

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

$indent = ' ';

$normalizer = new Normalizer\IndentNormalizer($indent);

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

The normalized version will now be indented with 2 spaces.

## Contributing

Please have a look at [`CONTRIBUTING.md`](.github/CONTRIBUTING.md).
Expand Down
Empty file removed src/.gitkeep
Empty file.
65 changes: 65 additions & 0 deletions src/IndentNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?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;

use Localheinz\Json\Printer\Printer;
use Localheinz\Json\Printer\PrinterInterface;

final class IndentNormalizer implements NormalizerInterface
{
/**
* @var string
*/
private $indent;

/**
* @var PrinterInterface
*/
private $printer;

/**
* @param string $indent
* @param null|PrinterInterface $printer
*
* @throws \InvalidArgumentException
*/
public function __construct(string $indent, PrinterInterface $printer = null)
{
if (1 !== \preg_match('/^[ \t]+$/', $indent)) {
throw new \InvalidArgumentException(\sprintf(
'"%s" is not a valid indent.',
$indent
));
}

$this->indent = $indent;

$this->printer = $printer ?: new Printer();
}

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

return $this->printer->print(
$json,
$this->indent
);
}
}
27 changes: 27 additions & 0 deletions src/NormalizerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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;

interface NormalizerInterface
{
/**
* @param string $json
*
* @throws \InvalidArgumentException
* @throws \RuntimeException
*
* @return string
*/
public function normalize(string $json): string;
}
120 changes: 120 additions & 0 deletions test/Unit/IndentNormalizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?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\IndentNormalizer;
use Localheinz\Json\Normalizer\NormalizerInterface;
use Localheinz\Json\Printer\PrinterInterface;
use Localheinz\Test\Util\Helper;
use PHPUnit\Framework;
use Prophecy\Argument;

final class IndentNormalizerTest extends Framework\TestCase
{
use Helper;

public function testImplementsNormalizerInterface()
{
$this->assertClassImplementsInterface(NormalizerInterface::class, IndentNormalizer::class);
}

public function testNormalizeRejectsInvalidJson()
{
$indent = ' ';

$json = $this->faker()->realText();

$normalizer = new IndentNormalizer(
$indent,
$this->prophesize(PrinterInterface::class)->reveal()
);

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(\sprintf(
'"%s" is not valid JSON.',
$json
));

$normalizer->normalize($json);
}

/**
* @dataProvider providerInvalidIndent
*
* @param string $indent
*/
public function testConstructorRejectsInvalidIndent(string $indent)
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(\sprintf(
'"%s" is not a valid indent.',
$indent
));

new IndentNormalizer(
$indent,
$this->prophesize(PrinterInterface::class)->reveal()
);
}

public function providerInvalidIndent(): \Generator
{
$values = [
'not-whitespace' => $this->faker()->sentence,
'contains-line-feed' => " \n ",
];

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

public function testNormalizeUsesPrinterToNormalizeJsonWithIndent()
{
$indent = ' ';

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

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

$printer = $this->prophesize(PrinterInterface::class);

$printer
->print(
Argument::is($json),
Argument::is($indent)
)
->shouldBeCalled()
->willReturn($normalized);

$normalizer = new IndentNormalizer(
$indent,
$printer->reveal()
);

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

0 comments on commit fa0c00b

Please sign in to comment.