Skip to content

Commit

Permalink
Enhancement: Implement ConfigHashNormalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Jan 13, 2018
1 parent a9beb1a commit 077ec60
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 0 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ Run
$ composer global require localheinz/composer-normalize
```

## Usage

This package comes with the following normalizers:

* [`Localheinz\Composer\Normalize\Normalizer\ConfigHashNormalizer`](#confighashnormalizer)

### `ConfigHashNormalizer`

If `composer.json` contains any configuration in the `config` section,
the `ConfigHashNormalizer` will sort the `config` section by key in ascending order.

:bulb: Find out more about the `config` section at https://getcomposer.org/doc/06-config.md.

## Contributing

Please have a look at [`CONTRIBUTING.md`](.github/CONTRIBUTING.md).
Expand Down
43 changes: 43 additions & 0 deletions src/Normalizer/ConfigHashNormalizer.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/composer-normalize
*/

namespace Localheinz\Composer\Normalize\Normalizer;

use Localheinz\Json\Normalizer\NormalizerInterface;

final class ConfigHashNormalizer implements NormalizerInterface
{
public function normalize(string $json): string
{
$decoded = \json_decode($json);

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

if (!\property_exists($decoded, 'config')) {
return $json;
}

$config = (array) $decoded->config;

\ksort($config);

$decoded->config = $config;

return \json_encode($decoded);
}
}
58 changes: 58 additions & 0 deletions test/Unit/Normalizer/AbstractNormalizerTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?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/composer-normalize
*/

namespace Localheinz\Composer\Normalize\Test\Unit\Normalizer;

use Localheinz\Json\Normalizer\NormalizerInterface;
use Localheinz\Test\Util\Helper;
use PHPUnit\Framework;

abstract class AbstractNormalizerTestCase extends Framework\TestCase
{
use Helper;

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

final public function testNormalizeRejectsInvalidJson()
{
$json = $this->faker()->realText();

$reflection = new \ReflectionClass($this->className());

$normalizer = $reflection->newInstanceWithoutConstructor();

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

$normalizer->normalize($json);
}

final protected function className(): string
{
return \preg_replace(
'/Test$/',
'',
\str_replace(
'Localheinz\\Composer\\Normalize\\Test\\Unit\\',
'Localheinz\\Composer\\Normalize\\',
static::class
)
);
}
}
68 changes: 68 additions & 0 deletions test/Unit/Normalizer/ConfigHashNormalizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?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/composer-normalize
*/

namespace Localheinz\Composer\Normalize\Test\Unit\Normalizer;

use Localheinz\Composer\Normalize\Normalizer\ConfigHashNormalizer;

final class ConfigHashNormalizerTest extends AbstractNormalizerTestCase
{
public function testNormalizeDoesNotModifyOtherProperty()
{
$json = <<<'JSON'
{
"foo": {
"qux": "quux",
"bar": "baz"
}
}
JSON;

$normalizer = new ConfigHashNormalizer();

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

public function testNormalizeSortsConfigHashIfPropertyExists()
{
$json = <<<'JSON'
{
"config": {
"sort-packages": true,
"preferred-install": "dist"
},
"foo": {
"qux": "quux",
"bar": "baz"
}
}
JSON;

$normalized = <<<'JSON'
{
"config": {
"preferred-install": "dist",
"sort-packages": true
},
"foo": {
"qux": "quux",
"bar": "baz"
}
}
JSON;

$normalizer = new ConfigHashNormalizer();

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

0 comments on commit 077ec60

Please sign in to comment.