File "PhpUnitConstructFixer.php"
Full Path: /var/www/html/back/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php
File size: 7.03 KB
MIME-type: text/x-php
Charset: utf-8
<?php
declare(strict_types=1);
/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace PhpCsFixer\Fixer\PhpUnit;
use PhpCsFixer\Fixer\AbstractPhpUnitFixer;
use PhpCsFixer\Fixer\ConfigurableFixerInterface;
use PhpCsFixer\Fixer\ConfigurableFixerTrait;
use PhpCsFixer\FixerConfiguration\AllowedValueSubset;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
/**
* @phpstan-type _AutogeneratedInputConfiguration array{
* assertions?: list<'assertEquals'|'assertNotEquals'|'assertNotSame'|'assertSame'>,
* }
* @phpstan-type _AutogeneratedComputedConfiguration array{
* assertions: list<'assertEquals'|'assertNotEquals'|'assertNotSame'|'assertSame'>,
* }
*
* @implements ConfigurableFixerInterface<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration>
*
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise.
*/
final class PhpUnitConstructFixer extends AbstractPhpUnitFixer implements ConfigurableFixerInterface
{
/** @use ConfigurableFixerTrait<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration> */
use ConfigurableFixerTrait;
public function isRisky(): bool
{
return true;
}
public function getDefinition(): FixerDefinitionInterface
{
return new FixerDefinition(
'PHPUnit assertion method calls like `->assertSame(true, $foo)` should be written with dedicated method like `->assertTrue($foo)`.',
[
new CodeSample(
<<<'PHP'
<?php
final class FooTest extends \PHPUnit_Framework_TestCase {
public function testSomething() {
$this->assertEquals(false, $b);
$this->assertSame(true, $a);
$this->assertNotEquals(null, $c);
$this->assertNotSame(null, $d);
}
}
PHP,
),
new CodeSample(
<<<'PHP'
<?php
final class FooTest extends \PHPUnit_Framework_TestCase {
public function testSomething() {
$this->assertEquals(false, $b);
$this->assertSame(true, $a);
$this->assertNotEquals(null, $c);
$this->assertNotSame(null, $d);
}
}
PHP,
['assertions' => ['assertSame', 'assertNotSame']],
),
],
null,
'Fixer could be risky if one is overriding PHPUnit\'s native methods.',
);
}
/**
* {@inheritdoc}
*
* Must run before PhpUnitDedicateAssertFixer.
*/
public function getPriority(): int
{
return -8;
}
/**
* @uses fixAssertNegative()
* @uses fixAssertPositive()
*/
protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $endIndex): void
{
// no assertions to be fixed - fast return
if ([] === $this->configuration['assertions']) {
return;
}
foreach ($this->configuration['assertions'] as $assertionMethod) {
for ($index = $startIndex; $index < $endIndex; ++$index) {
$index = \call_user_func_array(
\in_array($assertionMethod, ['assertSame', 'assertEquals'], true)
? [$this, 'fixAssertPositive']
: [$this, 'fixAssertNegative'],
[$tokens, $index, $assertionMethod],
);
if (null === $index) {
break;
}
}
}
}
protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
{
$assertMethods = [
'assertEquals',
'assertNotEquals',
'assertNotSame',
'assertSame',
];
return new FixerConfigurationResolver([
(new FixerOptionBuilder('assertions', 'List of assertion methods to fix.'))
->setAllowedTypes(['string[]'])
->setAllowedValues([new AllowedValueSubset($assertMethods)])
->setDefault($assertMethods)
->getOption(),
]);
}
private function fixAssertNegative(Tokens $tokens, int $index, string $method): ?int
{
return $this->fixAssert([
'false' => 'assertNotFalse',
'null' => 'assertNotNull',
'true' => 'assertNotTrue',
], $tokens, $index, $method);
}
private function fixAssertPositive(Tokens $tokens, int $index, string $method): ?int
{
return $this->fixAssert([
'false' => 'assertFalse',
'null' => 'assertNull',
'true' => 'assertTrue',
], $tokens, $index, $method);
}
/**
* @param array<string, string> $map
*/
private function fixAssert(array $map, Tokens $tokens, int $index, string $method): ?int
{
$functionsAnalyzer = new FunctionsAnalyzer();
$sequence = $tokens->findSequence(
[
[\T_STRING, $method],
'(',
],
$index,
);
if (null === $sequence) {
return null;
}
$sequenceIndices = array_keys($sequence);
if (!$functionsAnalyzer->isTheSameClassCall($tokens, $sequenceIndices[0])) {
return null;
}
$sequenceIndices[2] = $tokens->getNextMeaningfulToken($sequenceIndices[1]);
$firstParameterToken = $tokens[$sequenceIndices[2]];
if (!$firstParameterToken->isNativeConstant()) {
return $sequenceIndices[2];
}
$sequenceIndices[3] = $tokens->getNextMeaningfulToken($sequenceIndices[2]);
// return if first method argument is an expression, not value
if (!$tokens[$sequenceIndices[3]]->equals(',')) {
return $sequenceIndices[3];
}
$tokens[$sequenceIndices[0]] = new Token([\T_STRING, $map[strtolower($firstParameterToken->getContent())]]);
$tokens->clearRange($sequenceIndices[2], $tokens->getNextNonWhitespace($sequenceIndices[3]) - 1);
return $sequenceIndices[3];
}
}