Skip to content

Commit

Permalink
chore: DescribeCommand - better handling of deprecations (PHP-CS-Fi…
Browse files Browse the repository at this point in the history
  • Loading branch information
kubawerlos authored and danog committed Feb 2, 2024
1 parent 60cbd8a commit 280f52a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
5 changes: 4 additions & 1 deletion src/Console/Command/DescribeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,11 @@ private function describeRule(OutputInterface $output, string $name): void
if ($fixer instanceof DeprecatedFixerInterface) {
$successors = $fixer->getSuccessorsNames();
$message = [] === $successors
? 'will be removed in the next major version'
? sprintf('it will be removed in version %d.0', Application::getMajorVersion() + 1)
: sprintf('use %s instead', Utils::naturalLanguageJoinWithBackticks($successors));

$endMessage = '. '.ucfirst($message);
Utils::triggerDeprecation(new \RuntimeException(str_replace('`', '"', "Rule \"{$name}\" is deprecated{$endMessage}.")));
$message = Preg::replace('/(`[^`]+`)/', '<info>$1</info>', $message);
$output->writeln(sprintf('<error>DEPRECATED</error>: %s.', $message));
$output->writeln('');
Expand Down
20 changes: 18 additions & 2 deletions tests/AutoReview/DescribeCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

use PhpCsFixer\Console\Application;
use PhpCsFixer\Console\Command\DescribeCommand;
use PhpCsFixer\Fixer\DeprecatedFixerInterface;
use PhpCsFixer\FixerFactory;
use PhpCsFixer\Tests\TestCase;
use PhpCsFixer\Utils;
use Symfony\Component\Console\Tester\CommandTester;

/**
Expand All @@ -33,9 +35,19 @@ final class DescribeCommandTest extends TestCase
{
/**
* @dataProvider provideDescribeCommandCases
*
* @param list<string> $successorsNames
*/
public function testDescribeCommand(FixerFactory $factory, string $fixerName): void
public function testDescribeCommand(FixerFactory $factory, string $fixerName, ?array $successorsNames): void
{
if (null !== $successorsNames) {
$message = "Rule \"{$fixerName}\" is deprecated. "
.([] === $successorsNames
? 'It will be removed in version 4.0.'
: sprintf('Use %s instead.', Utils::naturalLanguageJoin($successorsNames)));
$this->expectDeprecation($message);
}

// @TODO 4.0 Remove this expectation
$this->expectDeprecation('Rule set "@PER" is deprecated. Use "@PER-CS" instead.');
$this->expectDeprecation('Rule set "@PER:risky" is deprecated. Use "@PER-CS:risky" instead.');
Expand All @@ -60,7 +72,11 @@ public static function provideDescribeCommandCases(): iterable
$factory->registerBuiltInFixers();

foreach ($factory->getFixers() as $fixer) {
yield [$factory, $fixer->getName()];
yield [
$factory,
$fixer->getName(),
$fixer instanceof DeprecatedFixerInterface ? $fixer->getSuccessorsNames() : null,
];
}
}
}
23 changes: 15 additions & 8 deletions tests/Console/Command/DescribeCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ final class DescribeCommandTest extends TestCase
/**
* @dataProvider provideExecuteOutputCases
*/
public function testExecuteOutput(string $expected, bool $expectedIsRegEx, bool $decorated, ?FixerInterface $fixer = null): void
public function testExecuteOutput(string $expected, bool $expectedIsRegEx, bool $decorated, FixerInterface $fixer): void
{
// @TODO 4.0 Remove this expectation
if ($fixer instanceof DeprecatedFixerInterface) {
$this->expectDeprecation(sprintf('Rule "%s" is deprecated. Use "%s" instead.', $fixer->getName(), implode('", "', $fixer->getSuccessorsNames())));
}

// @TODO 4.0 Remove these expectations:
$this->expectDeprecation('Rule set "@PER" is deprecated. Use "@PER-CS" instead.');
$this->expectDeprecation('Rule set "@PER:risky" is deprecated. Use "@PER-CS:risky" instead.');

$actual = $this->execute(null !== $fixer ? $fixer->getName() : 'Foo/bar', $decorated, $fixer)->getDisplay(true);
$actual = $this->execute($fixer->getName(), $decorated, $fixer)->getDisplay(true);

if (true === $expectedIsRegEx) {
self::assertMatchesRegularExpression($expected, $actual);
Expand Down Expand Up @@ -107,6 +111,7 @@ public static function provideExecuteOutputCases(): iterable
',
false,
false,
self::createConfigurableDeprecatedFixerDouble(),
];

yield 'rule is configurable, risky and deprecated [with decoration]' => [
Expand Down Expand Up @@ -148,6 +153,7 @@ public static function provideExecuteOutputCases(): iterable
",
false,
true,
self::createConfigurableDeprecatedFixerDouble(),
];

yield 'rule without code samples' => [
Expand Down Expand Up @@ -281,7 +287,8 @@ public static function provideExecuteOutputCases(): iterable

public function testExecuteStatusCode(): void
{
// @TODO 4.0 Remove this expectations
$this->expectDeprecation('Rule "Foo/bar" is deprecated. Use "Foo/baz" instead.');
// @TODO 4.0 Remove these expectations:
$this->expectDeprecation('Rule set "@PER" is deprecated. Use "@PER-CS" instead.');
$this->expectDeprecation('Rule set "@PER:risky" is deprecated. Use "@PER-CS:risky" instead.');

Expand Down Expand Up @@ -347,7 +354,7 @@ public function testGetAlternativeSuggestion(): void

public function testFixerClassNameIsExposedWhenVerbose(): void
{
// @TODO 4.0 Remove this expectations
// @TODO 4.0 Remove these expectations:
$this->expectDeprecation('Rule set "@PER" is deprecated. Use "@PER-CS" instead.');
$this->expectDeprecation('Rule set "@PER:risky" is deprecated. Use "@PER-CS:risky" instead.');

Expand Down Expand Up @@ -412,7 +419,7 @@ public function supports(\SplFileInfo $file): bool

public function testCommandDescribesCustomFixer(): void
{
// @TODO 4.0 Remove this expectations
// @TODO 4.0 Remove these expectations:
$this->expectDeprecation('Rule set "@PER" is deprecated. Use "@PER-CS" instead.');
$this->expectDeprecation('Rule set "@PER:risky" is deprecated. Use "@PER-CS:risky" instead.');

Expand Down Expand Up @@ -501,7 +508,7 @@ public function applyFix(\SplFileInfo $file, Tokens $tokens): void
};
}

private function createConfigurableDeprecatedFixerDouble(): FixerInterface
private static function createConfigurableDeprecatedFixerDouble(): FixerInterface
{
return new class() implements ConfigurableFixerInterface, DeprecatedFixerInterface {
/** @var array<string, mixed> */
Expand Down Expand Up @@ -590,7 +597,7 @@ public function supports(\SplFileInfo $file): bool

private function execute(string $name, bool $decorated, ?FixerInterface $fixer = null): CommandTester
{
$fixer ??= $this->createConfigurableDeprecatedFixerDouble();
$fixer ??= self::createConfigurableDeprecatedFixerDouble();

$fixerClassName = \get_class($fixer);
$isBuiltIn = str_starts_with($fixerClassName, 'PhpCsFixer') && !str_contains($fixerClassName, '@anon');
Expand Down

0 comments on commit 280f52a

Please sign in to comment.