OrderedInterfacesFixerTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of PHP CS Fixer.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  12. namespace PhpCsFixer\Tests\Fixer\ClassNotation;
  13. use PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. /**
  16. * @author Dave van der Brugge <dmvdbrugge@gmail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer
  21. */
  22. final class OrderedInterfacesFixerTest extends AbstractFixerTestCase
  23. {
  24. /**
  25. * @dataProvider provideFixAlphaCases
  26. */
  27. public function testFixAlpha(string $expected, ?string $input = null): void
  28. {
  29. $this->doTest($expected, $input);
  30. }
  31. public static function provideFixAlphaCases(): iterable
  32. {
  33. yield 'single' => [
  34. '<?php class T implements A {}',
  35. ];
  36. yield 'multiple' => [
  37. '<?php class T implements A, B, C {}',
  38. '<?php class T implements C, A, B {}',
  39. ];
  40. yield 'newlines' => [
  41. "<?php class T implements\nB,\nC\n{}",
  42. "<?php class T implements\nC,\nB\n{}",
  43. ];
  44. yield 'newlines and comments' => [
  45. "<?php class T implements\n// Here's A\nA,\n// Here's B\nB\n{}",
  46. "<?php class T implements\n// Here's B\nB,\n// Here's A\nA\n{}",
  47. ];
  48. yield 'no whitespace' => [
  49. '<?php class T implements/*An*/AnInterface/*end*/,/*Second*/SecondInterface{}',
  50. '<?php class T implements/*Second*/SecondInterface,/*An*/AnInterface/*end*/{}',
  51. ];
  52. yield 'FQCN' => [
  53. '<?php class T implements \F\Q\C\N, \F\Q\I\N {}',
  54. '<?php class T implements \F\Q\I\N, \F\Q\C\N {}',
  55. ];
  56. yield 'mixed' => [
  57. '<?php class T implements \F\Q\C\N, Partially\Q\C\N, /* Who mixes these? */ UnNamespaced {}',
  58. '<?php class T implements /* Who mixes these? */ UnNamespaced, \F\Q\C\N, Partially\Q\C\N {}',
  59. ];
  60. yield 'multiple in file' => [
  61. '<?php
  62. class A1 implements A\B\C, Z\X\Y {}
  63. class B2 implements A\B, Z\X {}
  64. class C3 implements A, Z\X {}
  65. class D4 implements A\B, B\V, Z\X\V {}
  66. class E5 implements U\B, X\B, Y\V, Z\X\V {}
  67. ',
  68. '<?php
  69. class A1 implements Z\X\Y, A\B\C {}
  70. class B2 implements Z\X, A\B {}
  71. class C3 implements Z\X, A {}
  72. class D4 implements Z\X\V, B\V, A\B {}
  73. class E5 implements Z\X\V, Y\V, X\B, U\B {}
  74. ',
  75. ];
  76. yield 'interface extends' => [
  77. '<?php interface T extends A, B, C {}',
  78. '<?php interface T extends C, A, B {}',
  79. ];
  80. yield 'nested anonymous classes' => [
  81. '<?php
  82. class T implements A, B, C
  83. {
  84. public function getAnonymousClassObject()
  85. {
  86. return new class() implements C, D, E
  87. {
  88. public function getNestedAnonymousClassObject()
  89. {
  90. return new class() implements E, F, G {};
  91. }
  92. };
  93. }
  94. }
  95. ',
  96. '<?php
  97. class T implements C, A, B
  98. {
  99. public function getAnonymousClassObject()
  100. {
  101. return new class() implements E, C, D
  102. {
  103. public function getNestedAnonymousClassObject()
  104. {
  105. return new class() implements F, G, E {};
  106. }
  107. };
  108. }
  109. }
  110. ',
  111. ];
  112. }
  113. /**
  114. * @dataProvider provideFixAlphaDescendCases
  115. */
  116. public function testFixAlphaDescend(string $expected, ?string $input = null): void
  117. {
  118. $this->fixer->configure([OrderedInterfacesFixer::OPTION_DIRECTION => OrderedInterfacesFixer::DIRECTION_DESCEND]);
  119. $this->doTest($expected, $input);
  120. }
  121. public static function provideFixAlphaDescendCases(): iterable
  122. {
  123. yield 'single' => [
  124. '<?php class T implements A {}',
  125. ];
  126. yield 'multiple' => [
  127. '<?php class T implements C, B, A {}',
  128. '<?php class T implements C, A, B {}',
  129. ];
  130. yield 'mixed' => [
  131. '<?php class T implements /* Who mixes these? */ UnNamespaced, Partially\Q\C\N, \F\Q\C\N {}',
  132. '<?php class T implements /* Who mixes these? */ UnNamespaced, \F\Q\C\N, Partially\Q\C\N {}',
  133. ];
  134. }
  135. /**
  136. * @dataProvider provideFixLengthCases
  137. */
  138. public function testFixLength(string $expected, ?string $input = null): void
  139. {
  140. $this->fixer->configure([OrderedInterfacesFixer::OPTION_ORDER => OrderedInterfacesFixer::ORDER_LENGTH]);
  141. $this->doTest($expected, $input);
  142. }
  143. public static function provideFixLengthCases(): iterable
  144. {
  145. yield 'single' => [
  146. '<?php class A implements A {}',
  147. ];
  148. yield 'multiple' => [
  149. '<?php class A implements Short, Longer, MuchLonger {}',
  150. '<?php class A implements MuchLonger, Short, Longer {}',
  151. ];
  152. yield 'mixed' => [
  153. '<?php class T implements \F\Q\C\N, /* Who mixes these? */ UnNamespaced, Partially\Q\C\N {}',
  154. '<?php class T implements /* Who mixes these? */ UnNamespaced, \F\Q\C\N, Partially\Q\C\N {}',
  155. ];
  156. yield 'normalized' => [
  157. '<?php
  158. class A implements
  159. ABCDE,
  160. A\B\C\D
  161. { /* */ }
  162. ',
  163. '<?php
  164. class A implements
  165. A\B\C\D,
  166. ABCDE
  167. { /* */ }
  168. ',
  169. ];
  170. }
  171. /**
  172. * @dataProvider provideFixLengthDescendCases
  173. */
  174. public function testFixLengthDescend(string $expected, ?string $input = null): void
  175. {
  176. $this->fixer->configure([
  177. OrderedInterfacesFixer::OPTION_ORDER => OrderedInterfacesFixer::ORDER_LENGTH,
  178. OrderedInterfacesFixer::OPTION_DIRECTION => OrderedInterfacesFixer::DIRECTION_DESCEND,
  179. ]);
  180. $this->doTest($expected, $input);
  181. }
  182. public static function provideFixLengthDescendCases(): iterable
  183. {
  184. yield 'single' => [
  185. '<?php class A implements A {}',
  186. ];
  187. yield 'multiple' => [
  188. '<?php class A implements MuchLonger, Longer, Short {}',
  189. '<?php class A implements MuchLonger, Short, Longer {}',
  190. ];
  191. yield 'mixed' => [
  192. '<?php class T implements Partially\Q\C\N, /* Who mixes these? */ UnNamespaced, \F\Q\C\N {}',
  193. '<?php class T implements /* Who mixes these? */ UnNamespaced, \F\Q\C\N, Partially\Q\C\N {}',
  194. ];
  195. yield 'normalized' => [
  196. '<?php
  197. class A implements
  198. A\B\C\D,
  199. ABCDE
  200. { /* */ }
  201. ',
  202. '<?php
  203. class A implements
  204. ABCDE,
  205. A\B\C\D
  206. { /* */ }
  207. ',
  208. ];
  209. }
  210. /**
  211. * @dataProvider provideFixCaseSensitiveAlphaCases
  212. */
  213. public function testFixCaseSensitiveAlpha(string $expected, ?string $input = null): void
  214. {
  215. $this->fixer->configure([
  216. OrderedInterfacesFixer::OPTION_ORDER => OrderedInterfacesFixer::ORDER_ALPHA,
  217. 'case_sensitive' => true,
  218. ]);
  219. $this->doTest($expected, $input);
  220. }
  221. public static function provideFixCaseSensitiveAlphaCases(): iterable
  222. {
  223. return [
  224. 'single' => [
  225. '<?php class A implements A {}',
  226. ],
  227. 'multiple' => [
  228. '<?php class A implements AA, Aaa, FF, Fff {}',
  229. '<?php class A implements Fff, Aaa, FF, AA {}',
  230. ],
  231. 'mixed' => [
  232. '<?php class T implements \F\Q\C\N, Partially\Q\C\N, /* Who mixes these? */ UnNamespaced {}',
  233. '<?php class T implements /* Who mixes these? */ UnNamespaced, \F\Q\C\N, Partially\Q\C\N {}',
  234. ],
  235. 'normalized' => [
  236. '<?php
  237. class A implements
  238. A\B\C\D,
  239. AAa\B\C\D,
  240. ABCDE,
  241. Aaa\B\C\D
  242. { /* */ }
  243. ',
  244. '<?php
  245. class A implements
  246. Aaa\B\C\D,
  247. AAa\B\C\D,
  248. ABCDE,
  249. A\B\C\D
  250. { /* */ }
  251. ',
  252. ],
  253. ];
  254. }
  255. }