| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- <?php
- /*
- * 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\ConfigurationDefinitionFixerInterface;
- use PhpCsFixer\FixerConfiguration\AllowedValueSubset;
- use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverRootless;
- use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
- use PhpCsFixer\FixerDefinition\CodeSample;
- use PhpCsFixer\FixerDefinition\FixerDefinition;
- use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
- use PhpCsFixer\Tokenizer\Token;
- use PhpCsFixer\Tokenizer\Tokens;
- /**
- * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
- */
- final class PhpUnitConstructFixer extends AbstractPhpUnitFixer implements ConfigurationDefinitionFixerInterface
- {
- private static $assertionFixers = [
- 'assertSame' => 'fixAssertPositive',
- 'assertEquals' => 'fixAssertPositive',
- 'assertNotEquals' => 'fixAssertNegative',
- 'assertNotSame' => 'fixAssertNegative',
- ];
- /**
- * {@inheritdoc}
- */
- public function isRisky()
- {
- return true;
- }
- /**
- * {@inheritdoc}
- */
- public function getDefinition()
- {
- return new FixerDefinition(
- 'PHPUnit assertion method calls like `->assertSame(true, $foo)` should be written with dedicated method like `->assertTrue($foo)`.',
- [
- new CodeSample(
- '<?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);
- }
- }
- '
- ),
- new CodeSample(
- '<?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);
- }
- }
- ',
- ['assertions' => ['assertSame', 'assertNotSame']]
- ),
- ],
- null,
- 'Fixer could be risky if one is overriding PHPUnit\'s native methods.'
- );
- }
- /**
- * {@inheritdoc}
- *
- * Must run before PhpUnitDedicateAssertFixer.
- */
- public function getPriority()
- {
- return -10;
- }
- /**
- * {@inheritdoc}
- */
- protected function applyPhpUnitClassFix(Tokens $tokens, $startIndex, $endIndex)
- {
- // no assertions to be fixed - fast return
- if (empty($this->configuration['assertions'])) {
- return;
- }
- foreach ($this->configuration['assertions'] as $assertionMethod) {
- $assertionFixer = self::$assertionFixers[$assertionMethod];
- for ($index = $startIndex; $index < $endIndex; ++$index) {
- $index = $this->{$assertionFixer}($tokens, $index, $assertionMethod);
- if (null === $index) {
- break;
- }
- }
- }
- }
- /**
- * {@inheritdoc}
- */
- protected function createConfigurationDefinition()
- {
- return new FixerConfigurationResolverRootless('assertions', [
- (new FixerOptionBuilder('assertions', 'List of assertion methods to fix.'))
- ->setAllowedTypes(['array'])
- ->setAllowedValues([new AllowedValueSubset(array_keys(self::$assertionFixers))])
- ->setDefault([
- 'assertEquals',
- 'assertSame',
- 'assertNotEquals',
- 'assertNotSame',
- ])
- ->getOption(),
- ], $this->getName());
- }
- /**
- * @param int $index
- * @param string $method
- *
- * @return null|int
- */
- private function fixAssertNegative(Tokens $tokens, $index, $method)
- {
- static $map = [
- 'false' => 'assertNotFalse',
- 'null' => 'assertNotNull',
- 'true' => 'assertNotTrue',
- ];
- return $this->fixAssert($map, $tokens, $index, $method);
- }
- /**
- * @param int $index
- * @param string $method
- *
- * @return null|int
- */
- private function fixAssertPositive(Tokens $tokens, $index, $method)
- {
- static $map = [
- 'false' => 'assertFalse',
- 'null' => 'assertNull',
- 'true' => 'assertTrue',
- ];
- return $this->fixAssert($map, $tokens, $index, $method);
- }
- /**
- * @param array<string, string> $map
- * @param int $index
- * @param string $method
- *
- * @return null|int
- */
- private function fixAssert(array $map, Tokens $tokens, $index, $method)
- {
- $functionsAnalyzer = new FunctionsAnalyzer();
- $sequence = $tokens->findSequence(
- [
- [T_STRING, $method],
- '(',
- ],
- $index
- );
- if (null === $sequence) {
- return null;
- }
- $sequenceIndexes = array_keys($sequence);
- if (!$functionsAnalyzer->isTheSameClassCall($tokens, $sequenceIndexes[0])) {
- return null;
- }
- $sequenceIndexes[2] = $tokens->getNextMeaningfulToken($sequenceIndexes[1]);
- $firstParameterToken = $tokens[$sequenceIndexes[2]];
- if (!$firstParameterToken->isNativeConstant()) {
- return $sequenceIndexes[2];
- }
- $sequenceIndexes[3] = $tokens->getNextMeaningfulToken($sequenceIndexes[2]);
- // return if first method argument is an expression, not value
- if (!$tokens[$sequenceIndexes[3]]->equals(',')) {
- return $sequenceIndexes[3];
- }
- $tokens[$sequenceIndexes[0]] = new Token([T_STRING, $map[strtolower($firstParameterToken->getContent())]]);
- $tokens->clearRange($sequenceIndexes[2], $tokens->getNextNonWhitespace($sequenceIndexes[3]) - 1);
- return $sequenceIndexes[3];
- }
- }
|