FixerFactoryTest.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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;
  12. use PhpCsFixer\Fixer\FixerInterface;
  13. use PhpCsFixer\FixerFactory;
  14. use PhpCsFixer\RuleSet;
  15. /**
  16. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\FixerFactory
  21. */
  22. final class FixerFactoryTest extends TestCase
  23. {
  24. public function testInterfaceIsFluent()
  25. {
  26. $factory = new FixerFactory();
  27. $testInstance = $factory->registerBuiltInFixers();
  28. $this->assertSame($factory, $testInstance);
  29. $testInstance = $factory->registerCustomFixers(
  30. [$this->createFixerDouble('Foo/f1'), $this->createFixerDouble('Foo/f2')]
  31. );
  32. $this->assertSame($factory, $testInstance);
  33. $testInstance = $factory->registerFixer(
  34. $this->createFixerDouble('f3'),
  35. false
  36. );
  37. $this->assertSame($factory, $testInstance);
  38. $ruleSetProphecy = $this->prophesize(\PhpCsFixer\RuleSetInterface::class);
  39. $ruleSetProphecy->getRules()->willReturn([]);
  40. $testInstance = $factory->useRuleSet(
  41. $ruleSetProphecy->reveal()
  42. );
  43. $this->assertSame($factory, $testInstance);
  44. }
  45. /**
  46. * @covers \PhpCsFixer\FixerFactory::create
  47. */
  48. public function testCreate()
  49. {
  50. $factory = FixerFactory::create();
  51. $this->assertInstanceOf(\PhpCsFixer\FixerFactory::class, $factory);
  52. }
  53. /**
  54. * @covers \PhpCsFixer\FixerFactory::registerBuiltInFixers
  55. */
  56. public function testRegisterBuiltInFixers()
  57. {
  58. $factory = new FixerFactory();
  59. $factory->registerBuiltInFixers();
  60. $this->assertGreaterThan(0, count($factory->getFixers()));
  61. }
  62. /**
  63. * @covers \PhpCsFixer\FixerFactory::getFixers
  64. */
  65. public function testThatFixersAreSorted()
  66. {
  67. $factory = new FixerFactory();
  68. $fxs = [
  69. $this->createFixerDouble('f1', 0),
  70. $this->createFixerDouble('f2', -10),
  71. $this->createFixerDouble('f3', 10),
  72. $this->createFixerDouble('f4', -10),
  73. ];
  74. foreach ($fxs as $fx) {
  75. $factory->registerFixer($fx, false);
  76. }
  77. // There are no rules that forces $fxs[1] to be prioritized before $fxs[3]. We should not test against that
  78. $this->assertSame([$fxs[2], $fxs[0]], array_slice($factory->getFixers(), 0, 2));
  79. }
  80. /**
  81. * @covers \PhpCsFixer\FixerFactory::getFixers
  82. * @covers \PhpCsFixer\FixerFactory::registerCustomFixers
  83. * @covers \PhpCsFixer\FixerFactory::registerFixer
  84. */
  85. public function testThatCanRegisterAndGetFixers()
  86. {
  87. $factory = new FixerFactory();
  88. $f1 = $this->createFixerDouble('f1');
  89. $f2 = $this->createFixerDouble('Foo/f2');
  90. $f3 = $this->createFixerDouble('Foo/f3');
  91. $factory->registerFixer($f1, false);
  92. $factory->registerCustomFixers([$f2, $f3]);
  93. $this->assertTrue(in_array($f1, $factory->getFixers(), true));
  94. $this->assertTrue(in_array($f2, $factory->getFixers(), true));
  95. $this->assertTrue(in_array($f3, $factory->getFixers(), true));
  96. }
  97. /**
  98. * @covers \PhpCsFixer\FixerFactory::registerFixer
  99. */
  100. public function testRegisterFixerWithOccupiedName()
  101. {
  102. $this->expectException(\UnexpectedValueException::class);
  103. $this->expectExceptionMessage('Fixer named "non_unique_name" is already registered.');
  104. $factory = new FixerFactory();
  105. $f1 = $this->createFixerDouble('non_unique_name');
  106. $f2 = $this->createFixerDouble('non_unique_name');
  107. $factory->registerFixer($f1, false);
  108. $factory->registerFixer($f2, false);
  109. }
  110. /**
  111. * @covers \PhpCsFixer\FixerFactory::useRuleSet
  112. */
  113. public function testUseRuleSet()
  114. {
  115. $factory = FixerFactory::create()
  116. ->registerBuiltInFixers()
  117. ->useRuleSet(new RuleSet([]))
  118. ;
  119. $this->assertCount(0, $factory->getFixers());
  120. $factory = FixerFactory::create()
  121. ->registerBuiltInFixers()
  122. ->useRuleSet(new RuleSet(['strict_comparison' => true, 'blank_line_before_statement' => false]))
  123. ;
  124. $fixers = $factory->getFixers();
  125. $this->assertCount(1, $fixers);
  126. $this->assertSame('strict_comparison', $fixers[0]->getName());
  127. }
  128. /**
  129. * @covers \PhpCsFixer\FixerFactory::useRuleSet
  130. */
  131. public function testUseRuleSetWithNonExistingRule()
  132. {
  133. $this->expectException(\UnexpectedValueException::class);
  134. $this->expectExceptionMessage('Rule "non_existing_rule" does not exist.');
  135. $factory = FixerFactory::create()
  136. ->registerBuiltInFixers()
  137. ->useRuleSet(new RuleSet(['non_existing_rule' => true]))
  138. ;
  139. $fixers = $factory->getFixers();
  140. $this->assertCount(1, $fixers);
  141. $this->assertSame('strict_comparison', $fixers[0]->getName());
  142. }
  143. public function testHasRule()
  144. {
  145. $factory = new FixerFactory();
  146. $f1 = $this->createFixerDouble('f1');
  147. $f2 = $this->createFixerDouble('Foo/f2');
  148. $f3 = $this->createFixerDouble('Foo/f3');
  149. $factory->registerFixer($f1, false);
  150. $factory->registerCustomFixers([$f2, $f3]);
  151. $this->assertTrue($factory->hasRule('f1'), 'Should have f1 fixer');
  152. $this->assertTrue($factory->hasRule('Foo/f2'), 'Should have f2 fixer');
  153. $this->assertTrue($factory->hasRule('Foo/f3'), 'Should have f3 fixer');
  154. $this->assertFalse($factory->hasRule('dummy'), 'Should not have dummy fixer');
  155. }
  156. public function testHasRuleWithChangedRuleSet()
  157. {
  158. $factory = new FixerFactory();
  159. $f1 = $this->createFixerDouble('f1');
  160. $f2 = $this->createFixerDouble('f2');
  161. $factory->registerFixer($f1, false);
  162. $factory->registerFixer($f2, false);
  163. $this->assertTrue($factory->hasRule('f1'), 'Should have f1 fixer');
  164. $this->assertTrue($factory->hasRule('f2'), 'Should have f2 fixer');
  165. $factory->useRuleSet(new RuleSet(['f2' => true]));
  166. $this->assertFalse($factory->hasRule('f1'), 'Should not have f1 fixer');
  167. $this->assertTrue($factory->hasRule('f2'), 'Should have f2 fixer');
  168. }
  169. /**
  170. * @dataProvider provideConflictingFixersCases
  171. */
  172. public function testConflictingFixers(RuleSet $ruleSet)
  173. {
  174. $this->expectException(\UnexpectedValueException::class);
  175. $this->expectExceptionMessageRegExp('#^Rule contains conflicting fixers:\n#');
  176. FixerFactory::create()->registerBuiltInFixers()->useRuleSet($ruleSet);
  177. }
  178. public function provideConflictingFixersCases()
  179. {
  180. return [
  181. [new RuleSet(['no_blank_lines_before_namespace' => true, 'single_blank_line_before_namespace' => true])],
  182. [new RuleSet(['single_blank_line_before_namespace' => true, 'no_blank_lines_before_namespace' => true])],
  183. ];
  184. }
  185. public function testNoDoubleConflictReporting()
  186. {
  187. $factory = new FixerFactory();
  188. $method = new \ReflectionMethod($factory, 'generateConflictMessage');
  189. $method->setAccessible(true);
  190. $this->assertSame(
  191. 'Rule contains conflicting fixers:
  192. - "a" with "b"
  193. - "c" with "d", "e", "f"
  194. - "d" with "g", "h"
  195. - "e" with "a"',
  196. $method->invoke(
  197. $factory,
  198. [
  199. 'a' => ['b'],
  200. 'b' => ['a'],
  201. 'c' => ['d', 'e', 'f'],
  202. 'd' => ['c', 'g', 'h'],
  203. 'e' => ['a'],
  204. ]
  205. )
  206. );
  207. }
  208. private function createFixerDouble($name, $priority = 0)
  209. {
  210. /** @var FixerInterface $fixer */
  211. $fixer = $this->prophesize(\PhpCsFixer\Fixer\FixerInterface::class);
  212. $fixer->getName()->willReturn($name);
  213. $fixer->getPriority()->willReturn($priority);
  214. return $fixer->reveal();
  215. }
  216. }