SingleImportPerStatementFixerTest.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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\Import;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer
  21. *
  22. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer>
  23. *
  24. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer
  25. */
  26. final class SingleImportPerStatementFixerTest extends AbstractFixerTestCase
  27. {
  28. /**
  29. * @dataProvider provideFixCases
  30. */
  31. public function testFix(string $expected, ?string $input = null): void
  32. {
  33. $this->doTest($expected, $input);
  34. }
  35. /**
  36. * @return iterable<array{string, string}>
  37. */
  38. public static function provideFixCases(): iterable
  39. {
  40. yield [
  41. '<?php
  42. /**/use Foo;
  43. use FooB;
  44. ',
  45. '<?php
  46. /**/use Foo,FooB;
  47. ',
  48. ];
  49. yield [
  50. <<<'EOF'
  51. use Some, Not, PHP, Like, Use, Statement;
  52. <?php
  53. use Foo;
  54. use FooA;
  55. use FooB;
  56. use FooC;
  57. use FooD as D;
  58. use FooE;
  59. use FooF;
  60. use FooG as G;
  61. use FooH;
  62. use FooI;
  63. use FooJ;
  64. use FooZ;
  65. EOF,
  66. <<<'EOF'
  67. use Some, Not, PHP, Like, Use, Statement;
  68. <?php
  69. use Foo;
  70. use FooA, FooB;
  71. use FooC, FooD as D, FooE;
  72. use FooF,
  73. FooG as G,
  74. FooH, FooI,
  75. FooJ;
  76. use FooZ;
  77. EOF,
  78. ];
  79. yield [
  80. <<<'EOF'
  81. <?php
  82. namespace {
  83. use Foo;
  84. use FooA;
  85. use FooB;
  86. use FooC;
  87. use FooD as D;
  88. use FooE;
  89. use FooF;
  90. use FooG as G;
  91. use FooH;
  92. use FooI;
  93. use FooJ;
  94. use FooZ;
  95. }
  96. namespace Boo {
  97. use Bar;
  98. use BarA;
  99. use BarB;
  100. use BarC;
  101. use BarD as D;
  102. use BarE;
  103. use BarF;
  104. use BarG as G;
  105. use BarH;
  106. use BarI;
  107. use BarJ;
  108. use BarZ;
  109. }
  110. EOF,
  111. <<<'EOF'
  112. <?php
  113. namespace {
  114. use Foo;
  115. use FooA, FooB;
  116. use FooC, FooD as D, FooE;
  117. use FooF,
  118. FooG as G,
  119. FooH, FooI,
  120. FooJ;
  121. use FooZ;
  122. }
  123. namespace Boo {
  124. use Bar;
  125. use BarA, BarB;
  126. use BarC, BarD as D, BarE;
  127. use BarF,
  128. BarG as G,
  129. BarH, BarI,
  130. BarJ;
  131. use BarZ;
  132. }
  133. EOF,
  134. ];
  135. yield [
  136. '<?php
  137. use FooA;
  138. use FooB;
  139. ',
  140. '<?php
  141. use FooA, FooB;
  142. ',
  143. ];
  144. yield [
  145. '<?php use FooA;
  146. use FooB?>',
  147. '<?php use FooA, FooB?>',
  148. ];
  149. yield [
  150. '<?php
  151. use B;
  152. use C;
  153. use E;
  154. use F;
  155. use G;
  156. use H;
  157. ',
  158. '<?php
  159. use B,C;
  160. use E,F;
  161. use G,H;
  162. ',
  163. ];
  164. yield [
  165. '<?php
  166. use B;
  167. /*
  168. */use C;
  169. ',
  170. '<?php
  171. use B,
  172. /*
  173. */C;
  174. ',
  175. ];
  176. yield [
  177. '<?php
  178. use A;
  179. use B;
  180. //,{} use ; :
  181. #,{} use ; :
  182. /*,{} use ; :*/
  183. use C ; ',
  184. '<?php
  185. use A,B,
  186. //,{} use ; :
  187. #,{} use ; :
  188. /*,{} use ; :*/
  189. C ; ',
  190. ];
  191. yield [
  192. '<?php use Z ;
  193. use X ?><?php new X(); // run before white space around semicolon',
  194. '<?php use Z , X ?><?php new X(); // run before white space around semicolon',
  195. ];
  196. yield [
  197. '<?php use FooA#
  198. ;#
  199. #
  200. use FooB;',
  201. '<?php use FooA#
  202. ,#
  203. #
  204. FooB;',
  205. ];
  206. yield [
  207. '<?php use some\b\ClassB;
  208. use function some\b\CC as C;
  209. use function some\b\D;
  210. use const some\b\E;
  211. use function some\b\A\B;',
  212. '<?php use some\b\{ClassB, function CC as C, function D, const E, function A\B};',
  213. ];
  214. yield [
  215. '<?php
  216. use Foo\Bar;
  217. use Foo\Baz;',
  218. '<?php
  219. use Foo\ {
  220. Bar, Baz
  221. };',
  222. ];
  223. yield [
  224. '<?php
  225. use Foo\Bar;
  226. use Foo\Baz;',
  227. '<?php
  228. use Foo\
  229. {
  230. Bar, Baz
  231. };',
  232. ];
  233. yield [
  234. '<?php
  235. use function md5;
  236. use function str_repeat;
  237. use const true;
  238. use const false;
  239. use A;
  240. use B;
  241. ',
  242. '<?php
  243. use function md5, str_repeat;
  244. use const true, false;
  245. use A,B;
  246. ',
  247. ];
  248. yield [
  249. '<?php
  250. use D\E;
  251. use D\F;
  252. use G\H;
  253. use G\I/*1*//*2*/;
  254. ',
  255. '<?php
  256. use D\{E,F,};
  257. use G\{H,I/*1*/,/*2*/};
  258. ',
  259. ];
  260. yield [
  261. '<?php
  262. use A\B;
  263. ',
  264. '<?php
  265. use A\{B};
  266. ',
  267. ];
  268. }
  269. public function testWithConfig(): void
  270. {
  271. $expected = '<?php
  272. use Space\Models\TestModelA;
  273. use Space\Models\TestModelB;
  274. use Space\Models\TestModel;';
  275. $input = '<?php
  276. use Space\Models\ {
  277. TestModelA,
  278. TestModelB,
  279. TestModel,
  280. };';
  281. $this->doTest($expected, $input);
  282. $this->fixer->configure(['group_to_single_imports' => false]);
  283. $this->doTest($input);
  284. }
  285. /**
  286. * @dataProvider provideMessyWhitespacesCases
  287. */
  288. public function testMessyWhitespaces(string $expected, ?string $input = null): void
  289. {
  290. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  291. $this->doTest($expected, $input);
  292. }
  293. /**
  294. * @return iterable<array{string, string}>
  295. */
  296. public static function provideMessyWhitespacesCases(): iterable
  297. {
  298. yield [
  299. "<?php\r\n use FooA;\r\n use FooB;",
  300. "<?php\r\n use FooA, FooB;",
  301. ];
  302. }
  303. /**
  304. * @dataProvider provideFixPrePHP80Cases
  305. *
  306. * @requires PHP <8.0
  307. */
  308. public function testFixPrePHP80(string $expected, string $input): void
  309. {
  310. $this->doTest($expected, $input);
  311. }
  312. /**
  313. * @return iterable<int|string, array{string, string}>
  314. */
  315. public static function provideFixPrePHP80Cases(): iterable
  316. {
  317. yield [
  318. '<?php
  319. use some\a\ClassA;
  320. use some\a\ClassB;
  321. use some\a\ClassC as C;
  322. use function some\b\fn_a;
  323. use function some\b\fn_b;
  324. use function some\b\fn_c;
  325. use const some\c\ConstA/**/as/**/E; /* group comment */
  326. use const some\c\ConstB as D;
  327. use const some\c\// use.,{}
  328. ConstC;
  329. use A\B;
  330. use D\E;
  331. use D\F;
  332. ',
  333. '<?php
  334. use some\a\{ClassA, ClassB, ClassC as C};
  335. use function some\b\{fn_a, fn_b, fn_c};
  336. use const/* group comment */some\c\{ConstA/**/as/**/ E , ConstB AS D, '.'
  337. // use.,{}
  338. ConstC};
  339. use A\{B};
  340. use D\{E,F};
  341. ',
  342. ];
  343. yield 'messy comments' => [
  344. '<?php
  345. use D\/*1*//*2*//*3*/E;
  346. use D\/*4*//*5*//*6*//*7*//*8*//*9*/F/*10*//*11*//*12*/;
  347. ',
  348. '<?php
  349. use D\{
  350. /*1*//*2*//*3*/E,/*4*//*5*//*6*/
  351. /*7*//*8*//*9*/F/*10*//*11*//*12*/
  352. };
  353. ',
  354. ];
  355. }
  356. }