FixerTest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace PhpCsFixer\Tests\AutoReview;
  12. use PhpCsFixer\Fixer\ConfigurableFixerInterface;
  13. use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
  14. use PhpCsFixer\Fixer\FixerInterface;
  15. use PhpCsFixer\FixerDefinition\FileSpecificCodeSampleInterface;
  16. use PhpCsFixer\FixerDefinition\VersionSpecificCodeSampleInterface;
  17. use PhpCsFixer\FixerFactory;
  18. use PhpCsFixer\StdinFileInfo;
  19. use PhpCsFixer\Tokenizer\Tokens;
  20. use PHPUnit\Framework\TestCase;
  21. /**
  22. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  23. *
  24. * @internal
  25. *
  26. * @coversNothing
  27. * @group auto-review
  28. */
  29. final class FixerTest extends TestCase
  30. {
  31. /**
  32. * @param FixerInterface $fixer
  33. *
  34. * @dataProvider provideFixerDefinitionsCases
  35. */
  36. public function testFixerDefinitions(FixerInterface $fixer)
  37. {
  38. $this->assertInstanceOf('PhpCsFixer\Fixer\DefinedFixerInterface', $fixer);
  39. $definition = $fixer->getDefinition();
  40. $this->assertRegExp('/^[A-Z@].*\.$/', $definition->getSummary(), sprintf('[%s] Description must start with capital letter or an @ and end with dot.', $fixer->getName()));
  41. $samples = $definition->getCodeSamples();
  42. $this->assertNotEmpty($samples, sprintf('[%s] Code samples are required.', $fixer->getName()));
  43. $dummyFileInfo = new StdinFileInfo();
  44. foreach ($samples as $sampleCounter => $sample) {
  45. $this->assertInstanceOf('PhpCsFixer\FixerDefinition\CodeSampleInterface', $sample, sprintf('[%s] Sample #%d', $fixer->getName(), $sampleCounter));
  46. $code = $sample->getCode();
  47. $this->assertStringIsNotEmpty($code, sprintf('[%s] Sample #%d', $fixer->getName(), $sampleCounter));
  48. if ($sample instanceof VersionSpecificCodeSampleInterface && !$sample->isSuitableFor(PHP_VERSION_ID)) {
  49. continue;
  50. }
  51. $config = $sample->getConfiguration();
  52. if (null !== $config) {
  53. $this->assertInternalType('array', $config, sprintf('[%s] Sample #%d configuration must be an array or null.', $fixer->getName(), $sampleCounter));
  54. if ($fixer instanceof ConfigurableFixerInterface) {
  55. $fixer->configure($config);
  56. } else {
  57. $this->assertInternalType('array', $config, sprintf('[%s] Sample #%d has configuration, but the fixer is not configurable.', $fixer->getName(), $sampleCounter));
  58. }
  59. }
  60. Tokens::clearCache();
  61. $tokens = Tokens::fromCode($code);
  62. $fixer->fix(
  63. $sample instanceof FileSpecificCodeSampleInterface ? $sample->getSplFileInfo() : $dummyFileInfo,
  64. $tokens
  65. );
  66. $this->assertTrue($tokens->isChanged(), sprintf('[%s] Sample #%d is not changed during fixing.', $fixer->getName(), $sampleCounter));
  67. $duplicatedCodeSample = array_search(
  68. $sample,
  69. array_slice($samples, 0, $sampleCounter),
  70. false
  71. );
  72. $this->assertFalse(
  73. $duplicatedCodeSample,
  74. sprintf('[%s] Code sample #%d duplicates #%d.', $fixer->getName(), $sampleCounter, $duplicatedCodeSample)
  75. );
  76. }
  77. if ($fixer->isRisky()) {
  78. $this->assertStringIsNotEmpty($definition->getRiskyDescription(), sprintf('[%s] Risky reasoning is required.', $fixer->getName()));
  79. } else {
  80. $this->assertNull($definition->getRiskyDescription(), sprintf('[%s] Fixer is not risky so no description of it expected.', $fixer->getName()));
  81. }
  82. }
  83. /**
  84. * @param FixerInterface $fixer
  85. *
  86. * @group legacy
  87. * @dataProvider provideFixerDefinitionsCases
  88. * @expectedDeprecation PhpCsFixer\FixerDefinition\FixerDefinition::getConfigurationDescription is deprecated and will be removed in 3.0.
  89. * @expectedDeprecation PhpCsFixer\FixerDefinition\FixerDefinition::getDefaultConfiguration is deprecated and will be removed in 3.0.
  90. */
  91. public function testLegacyFixerDefinitions(FixerInterface $fixer)
  92. {
  93. $definition = $fixer->getDefinition();
  94. $this->assertNull($definition->getConfigurationDescription(), sprintf('[%s] No configuration description expected.', $fixer->getName()));
  95. $this->assertNull($definition->getDefaultConfiguration(), sprintf('[%s] No default configuration expected.', $fixer->getName()));
  96. }
  97. /**
  98. * @dataProvider provideFixerDefinitionsCases
  99. */
  100. public function testFixersAreFinal(FixerInterface $fixer)
  101. {
  102. $reflection = new \ReflectionClass($fixer);
  103. $this->assertTrue(
  104. $reflection->isFinal(),
  105. sprintf('Fixer "%s" must be declared "final".', $fixer->getName())
  106. );
  107. }
  108. /**
  109. * @dataProvider provideFixerDefinitionsCases
  110. */
  111. public function testFixersAreDefined(FixerInterface $fixer)
  112. {
  113. $this->assertInstanceOf('PhpCsFixer\Fixer\DefinedFixerInterface', $fixer);
  114. }
  115. public function provideFixerDefinitionsCases()
  116. {
  117. return array_map(function (FixerInterface $fixer) {
  118. return array($fixer);
  119. }, $this->getAllFixers());
  120. }
  121. /**
  122. * @param ConfigurationDefinitionFixerInterface $fixer
  123. *
  124. * @dataProvider provideFixerConfigurationDefinitionsCases
  125. */
  126. public function testFixerConfigurationDefinitions(ConfigurationDefinitionFixerInterface $fixer)
  127. {
  128. $configurationDefinition = $fixer->getConfigurationDefinition();
  129. $this->assertInstanceOf('PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface', $configurationDefinition);
  130. foreach ($configurationDefinition->getOptions() as $option) {
  131. $this->assertNotEmpty($option->getDescription());
  132. }
  133. }
  134. public function provideFixerConfigurationDefinitionsCases()
  135. {
  136. $fixers = array_filter($this->getAllFixers(), function (FixerInterface $fixer) {
  137. return $fixer instanceof ConfigurationDefinitionFixerInterface;
  138. });
  139. return array_map(function (FixerInterface $fixer) {
  140. return array($fixer);
  141. }, $fixers);
  142. }
  143. private function getAllFixers()
  144. {
  145. $factory = new FixerFactory();
  146. return $factory->registerBuiltInFixers()->getFixers();
  147. }
  148. /**
  149. * copy paste from GeckoPackages/GeckoPHPUnit StringsAssertTrait, to replace with Trait when possible.
  150. *
  151. * @param mixed $actual
  152. * @param string $message
  153. */
  154. private static function assertStringIsNotEmpty($actual, $message = '')
  155. {
  156. self::assertInternalType('string', $actual, $message);
  157. self::assertNotEmpty($actual, $message);
  158. }
  159. }