Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
],
"require": {
"php": "^7.4 || ^8.0",
"ext-json": "*",
"symfony/process": "^5 || ^6 || ^7 || ^8",
"friendsofphp/php-cs-fixer": "^3",
"symfony/deprecation-contracts": "^2 || ^3"
},
"require-dev": {
"ext-json": "*",
"ergebnis/composer-normalize": "^2.7",
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": "^2.1",
Expand Down
40 changes: 27 additions & 13 deletions src/Fixer/BlockStringFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ final class BlockStringFixer implements FixerInterface, ConfigurableFixerInterfa
/**
* @var TDeserializedConfig
*/
private array $configuration;
private array $configuration = [
'formatters' => [],
];

public function isRisky(): bool
{
Expand Down Expand Up @@ -79,19 +81,31 @@ public function getConfigurationDefinition(): FixerConfigurationResolverInterfac

public function configure(array $configuration): void
{
if (!is_string($formatters = $configuration['formatters'] ?? 'a:0:{}')
|| ($formatters = @unserialize($formatters, ['allowed_classes' => true])) === false
) {
throw new InvalidArgumentException(
'BlockStringFixer configuration is not valid. '
. 'Did you set it up in your PHP CS Fixer config with `BlockStringFixer::config()`?'
);
$formatters = $configuration['formatters'] ?? [];
if (!is_array($formatters)) {
throw new InvalidArgumentException(sprintf(
'BlockStringFixer configuration is not valid: formatters must be an array, "%s" given.',
is_object($formatters) ? get_class($formatters) : gettype($formatters)
));
}
foreach ($formatters as $key => $formatter) {
if (is_int($key) && $key !== 0) {
throw new InvalidArgumentException(sprintf(
'BlockStringFixer configuration is not valid: formatter for integer key %s will never be used.',
$key
));
}

// @phpstan-ignore assign.propertyType
$this->configuration = [
'formatters' => $formatters,
];
if (!$formatter instanceof AbstractFormatter) {
throw new InvalidArgumentException(sprintf(
'BlockStringFixer configuration is not valid: formatter for key %s must be an instance of %s, %s was given instead.',
$key,
AbstractFormatter::class,
is_object($formatter) ? get_class($formatter) : gettype($formatter)
));
}
}
$this->configuration['formatters'] = $formatters;
}

public function fix(SplFileInfo $file, Tokens $tokens): void
Expand All @@ -117,7 +131,7 @@ public function fix(SplFileInfo $file, Tokens $tokens): void
public static function config(array $formatters): array
{
return [
'formatters' => serialize($formatters),
'formatters' => $formatters,
];
}
}
11 changes: 10 additions & 1 deletion src/Formatter/AbstractFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace uuf6429\PhpCsFixerBlockstring\Formatter;

use JsonSerializable;
use uuf6429\PhpCsFixerBlockstring\BlockString\BlockString;
use uuf6429\PhpCsFixerBlockstring\CacheFingerprintableInterface;
use uuf6429\PhpCsFixerBlockstring\InterpolationCodec\CodecInterface;
Expand All @@ -17,7 +18,7 @@
* 2. Or if, for whatever reason, the {@see CodecInterface} concept does not work for you and you want to write
* something from scratch.
*/
abstract class AbstractFormatter implements CacheFingerprintableInterface
abstract class AbstractFormatter implements CacheFingerprintableInterface, JsonSerializable
{
/**
* @var mixed
Expand Down Expand Up @@ -52,4 +53,12 @@ final public function getCacheFingerprint()
{
return $this->cacheFingerprint;
}

/**
* @return array{cacheFingerprint: mixed, ...}
*/
public function jsonSerialize(): array
{
return ['cacheFingerprint' => $this->getCacheFingerprint()];
}
}
41 changes: 35 additions & 6 deletions tests/Unit/Fixer/BlockStringFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace uuf6429\PhpCsFixerBlockstringTests\Unit\Fixer;

use Exception;
use InvalidArgumentException;
use PhpCsFixer\Tokenizer\Tokens;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -47,20 +48,48 @@ public function testGetConfigurationDefinition(): void
}

/**
* @testWith ["not a serialized string"]
* [[{"some": "invalid", "config": "structure"}]]
* @param mixed $formatters
* @dataProvider invalidConfigurationProvider
*/
public function testConfigureWithInvalidConfiguration($formatters): void
public function testConfigureWithInvalidConfiguration($formatters, Exception $expectedException): void
{
$this->expectExceptionObject(new InvalidArgumentException('BlockStringFixer configuration is not valid.'));
$this->expectExceptionObject($expectedException);

(new BlockStringFixer())->configure(['formatters' => $formatters]);
}

public function testConfig(): void
/**
* @return iterable<string, array{formatters: mixed, expectedException: Exception}>
*/
public static function invalidConfigurationProvider(): iterable
{
$this->assertSame(['formatters' => 'a:0:{}'], BlockStringFixer::config([]));
yield 'invalid value for formatters' => [
'formatters' => 'invalid',
'expectedException' => new InvalidArgumentException(
'BlockStringFixer configuration is not valid: formatters must be an array, "string" given.'
),
];

yield 'invalid numeric key' => [
'formatters' => [1 => 'test'],
'expectedException' => new InvalidArgumentException(
'BlockStringFixer configuration is not valid: formatter for integer key 1 will never be used.'
),
];

yield 'invalid default formatter' => [
'formatters' => [0 => 'invalid'],
'expectedException' => new InvalidArgumentException(
'BlockStringFixer configuration is not valid: formatter for key 0 must be an instance of uuf6429\PhpCsFixerBlockstring\Formatter\AbstractFormatter, string was given instead.',
),
];

yield 'invalid JSON formatter' => [
'formatters' => ['JSON' => 'invalid'],
'expectedException' => new InvalidArgumentException(
'BlockStringFixer configuration is not valid: formatter for key JSON must be an instance of uuf6429\PhpCsFixerBlockstring\Formatter\AbstractFormatter, string was given instead.',
)
];
}

/**
Expand Down
5 changes: 3 additions & 2 deletions tests/Unit/Formatter/AbstractFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ final class AbstractFormatterTest extends TestCase
{
public function testThatAbstractFormatterIsCacheable(): void
{
$formatter = new class('fingerprint') extends AbstractFormatter {
$formatter = new class('the fingerprint') extends AbstractFormatter {
public function formatBlock(BlockString $blockString): BlockString
{
return $blockString;
}
};

$this->assertSame('fingerprint', $formatter->getCacheFingerprint());
$this->assertSame('the fingerprint', $formatter->getCacheFingerprint());
$this->assertSame(['cacheFingerprint' => 'the fingerprint'], $formatter->jsonSerialize());
}
}
Loading