OrderedImportsFixerTest.php 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
  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\ConfigurationException\InvalidFixerConfigurationException;
  14. use PhpCsFixer\Fixer\Import\OrderedImportsFixer;
  15. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  16. /**
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Import\OrderedImportsFixer
  20. */
  21. final class OrderedImportsFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideFixWithMultipleNamespaceCases
  25. */
  26. public function testFixWithMultipleNamespace(string $expected, string $input): void
  27. {
  28. $this->doTest($expected, $input);
  29. }
  30. public static function provideFixWithMultipleNamespaceCases(): iterable
  31. {
  32. $expected = <<<'EOF'
  33. <?php
  34. namespace FooRoo {
  35. use Foo\Bar;
  36. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar as FooBaz;
  37. use Foo\Bir as FBB;
  38. use Foo\Zar\Baz;
  39. use SomeClass;
  40. use Symfony\Annotation\Template, Zoo\Bar as ZooBar;
  41. use Zoo\Tar1;
  42. $a = new Bar();
  43. $a = new FooBaz();
  44. $a = new someclass();
  45. use Zoo\Tar2;
  46. class AnnotatedClass
  47. {
  48. /**
  49. * @Template(foobar=21)
  50. * @param Entity $foo
  51. */
  52. public function doSomething($foo)
  53. {
  54. $bar = $foo->toArray();
  55. /** @var ArrayInterface $bar */
  56. return function () use ($bar, $foo) {};
  57. }
  58. }
  59. }
  60. namespace BlaRoo {
  61. use Foo\Zar\Baz;
  62. use SomeClass;
  63. use Symfony\Annotation\Template;
  64. use Symfony\Doctrine\Entities\Entity, Zoo\Bar;
  65. class AnnotatedClass
  66. {
  67. /**
  68. * @Template(foobar=21)
  69. * @param Entity $foo
  70. */
  71. public function doSomething($foo)
  72. {
  73. $bar = $foo->toArray();
  74. /** @var ArrayInterface $bar */
  75. return function () use ($bar, $foo) {};
  76. }
  77. }
  78. }
  79. EOF;
  80. $input = <<<'EOF'
  81. <?php
  82. namespace FooRoo {
  83. use Foo\Bar\FooBar as FooBaz;
  84. use Zoo\Bar as ZooBar, Zoo\Tar1;
  85. use Foo\Bar;
  86. use Foo\Zar\Baz;
  87. use Symfony\Annotation\Template;
  88. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  89. use SomeClass;
  90. $a = new Bar();
  91. $a = new FooBaz();
  92. $a = new someclass();
  93. use Zoo\Tar2;
  94. class AnnotatedClass
  95. {
  96. /**
  97. * @Template(foobar=21)
  98. * @param Entity $foo
  99. */
  100. public function doSomething($foo)
  101. {
  102. $bar = $foo->toArray();
  103. /** @var ArrayInterface $bar */
  104. return function () use ($bar, $foo) {};
  105. }
  106. }
  107. }
  108. namespace BlaRoo {
  109. use Foo\Zar\Baz;
  110. use Zoo\Bar;
  111. use SomeClass;
  112. use Symfony\Annotation\Template, Symfony\Doctrine\Entities\Entity;
  113. class AnnotatedClass
  114. {
  115. /**
  116. * @Template(foobar=21)
  117. * @param Entity $foo
  118. */
  119. public function doSomething($foo)
  120. {
  121. $bar = $foo->toArray();
  122. /** @var ArrayInterface $bar */
  123. return function () use ($bar, $foo) {};
  124. }
  125. }
  126. }
  127. EOF;
  128. yield [$expected, $input];
  129. $expected = <<<'EOF'
  130. <?php namespace Space1 {
  131. use Foo\Bar\Foo;
  132. use Symfony\Annotation\Template;
  133. }
  134. namespace Space2 { use A,B; }
  135. namespace Space3 {
  136. use Symfony\Annotation\Template;
  137. use Symfony\Doctrine\Entities\Entity0, Zoo\Bar;
  138. echo Bar::C;
  139. use A\B;
  140. }
  141. namespace Space4{}
  142. EOF;
  143. $input = <<<'EOF'
  144. <?php namespace Space1 {
  145. use Symfony\Annotation\Template;
  146. use Foo\Bar\Foo;
  147. }
  148. namespace Space2 { use B,A; }
  149. namespace Space3 {
  150. use Zoo\Bar;
  151. use Symfony\Annotation\Template, Symfony\Doctrine\Entities\Entity0;
  152. echo Bar::C;
  153. use A\B;
  154. }
  155. namespace Space4{}
  156. EOF;
  157. yield [$expected, $input];
  158. $expected =
  159. '<?php
  160. use B;
  161. use C;
  162. $foo = new C();
  163. use A;
  164. ';
  165. $input =
  166. '<?php
  167. use C;
  168. use B;
  169. $foo = new C();
  170. use A;
  171. ';
  172. yield [$expected, $input];
  173. yield 'open-close groups' => [
  174. '
  175. <?php use X ?>
  176. <?php use Z ?>
  177. <?php echo X::class ?>
  178. <?php use E ?> output
  179. <?php use F ?><?php echo E::class; use A; ?>
  180. ',
  181. '
  182. <?php use Z ?>
  183. <?php use X ?>
  184. <?php echo X::class ?>
  185. <?php use F ?> output
  186. <?php use E ?><?php echo E::class; use A; ?>
  187. ',
  188. ];
  189. }
  190. public function testFixWithComment(): void
  191. {
  192. $expected = <<<'EOF'
  193. The normal
  194. use of this fixer
  195. should not change this sentence nor those statements below
  196. use Zoo\Bar;
  197. use Foo\Bar;
  198. use Foo\Zar\Baz;
  199. <?php
  200. use Foo\Bar;
  201. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar /* He there */ as FooBaz;
  202. use Foo\Bir as FBB;
  203. use Foo\Zar\Baz;
  204. use SomeClass;
  205. use /* check */Symfony\Annotation\Template, Zoo\Bar as ZooBar;
  206. use Zoo\Tar;
  207. $a = new Bar();
  208. $a = new FooBaz();
  209. $a = new someclass();
  210. class AnnotatedClass
  211. {
  212. /**
  213. * @Template(foobar=21)
  214. * @param Entity $foo
  215. */
  216. public function doSomething($foo)
  217. {
  218. $bar = $foo->toArray();
  219. /** @var ArrayInterface $bar */
  220. return function () use ($bar, $foo) {};
  221. }
  222. }
  223. EOF;
  224. $input = <<<'EOF'
  225. The normal
  226. use of this fixer
  227. should not change this sentence nor those statements below
  228. use Zoo\Bar;
  229. use Foo\Bar;
  230. use Foo\Zar\Baz;
  231. <?php
  232. use Foo\Bar\FooBar /* He there */ as FooBaz;
  233. use Zoo\Bar as ZooBar, Zoo\Tar;
  234. use Foo\Bar;
  235. use Foo\Zar\Baz;
  236. use /* check */Symfony\Annotation\Template;
  237. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  238. use SomeClass;
  239. $a = new Bar();
  240. $a = new FooBaz();
  241. $a = new someclass();
  242. class AnnotatedClass
  243. {
  244. /**
  245. * @Template(foobar=21)
  246. * @param Entity $foo
  247. */
  248. public function doSomething($foo)
  249. {
  250. $bar = $foo->toArray();
  251. /** @var ArrayInterface $bar */
  252. return function () use ($bar, $foo) {};
  253. }
  254. }
  255. EOF;
  256. $this->doTest($expected, $input);
  257. }
  258. public function testWithTraits(): void
  259. {
  260. $expected = <<<'EOF'
  261. <?php
  262. use Foo\Bar;
  263. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar as FooBaz;
  264. use Foo\Bir as FBB;
  265. use Foo\Zar\Baz;
  266. use SomeClass;
  267. use Symfony\Annotation\Template, Zoo\Bar as ZooBar;
  268. use Zoo\Tar;
  269. trait Foo {}
  270. trait Zoo {}
  271. class AnnotatedClass
  272. {
  273. use Foo, Bar;
  274. /**
  275. * @Template(foobar=21)
  276. * @param Entity $foo
  277. */
  278. public function doSomething($foo)
  279. {
  280. $bar = $foo->toArray();
  281. /** @var ArrayInterface $bar */
  282. return function () use ($bar, $foo) {};
  283. }
  284. }
  285. EOF;
  286. $input = <<<'EOF'
  287. <?php
  288. use Foo\Bar\FooBar as FooBaz;
  289. use Zoo\Bar as ZooBar, Zoo\Tar;
  290. use Foo\Bar;
  291. use Foo\Zar\Baz;
  292. use Symfony\Annotation\Template;
  293. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  294. use SomeClass;
  295. trait Foo {}
  296. trait Zoo {}
  297. class AnnotatedClass
  298. {
  299. use Foo, Bar;
  300. /**
  301. * @Template(foobar=21)
  302. * @param Entity $foo
  303. */
  304. public function doSomething($foo)
  305. {
  306. $bar = $foo->toArray();
  307. /** @var ArrayInterface $bar */
  308. return function () use ($bar, $foo) {};
  309. }
  310. }
  311. EOF;
  312. $this->doTest($expected, $input);
  313. }
  314. public function testFixWithTraitImports(): void
  315. {
  316. $expected = <<<'EOF'
  317. The normal
  318. use of this fixer
  319. should not change this sentence nor those statements below
  320. use Zoo\Bar;
  321. use Foo\Bar;
  322. use Foo\Zar\Baz;
  323. <?php
  324. use Acme\MyReusableTrait;
  325. use Foo\Bar, Foo\Bar\Foo as Fooo;
  326. use Foo\Bar\FooBar as FooBaz;
  327. use Foo\Bir as FBB;
  328. use Foo\Zar\Baz;
  329. use SomeClass;
  330. use Symfony\Annotation\Template, Zoo\Bar as ZooBar;
  331. use Zoo\Tar;
  332. $a = new Bar();
  333. $a = new FooBaz();
  334. $a = new someclass();
  335. class AnnotatedClass
  336. {
  337. use MyReusableTrait;
  338. /**
  339. * @Template(foobar=21)
  340. * @param Entity $foo
  341. */
  342. public function doSomething($foo)
  343. {
  344. $bar = $foo->toArray();
  345. /** @var ArrayInterface $bar */
  346. return function () use ($bar, $baz) {};
  347. }
  348. }
  349. EOF;
  350. $input = <<<'EOF'
  351. The normal
  352. use of this fixer
  353. should not change this sentence nor those statements below
  354. use Zoo\Bar;
  355. use Foo\Bar;
  356. use Foo\Zar\Baz;
  357. <?php
  358. use Foo\Bar\FooBar as FooBaz;
  359. use Zoo\Bar as ZooBar, Zoo\Tar;
  360. use Foo\Bar;
  361. use Foo\Zar\Baz;
  362. use Acme\MyReusableTrait;
  363. use Symfony\Annotation\Template;
  364. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  365. use SomeClass;
  366. $a = new Bar();
  367. $a = new FooBaz();
  368. $a = new someclass();
  369. class AnnotatedClass
  370. {
  371. use MyReusableTrait;
  372. /**
  373. * @Template(foobar=21)
  374. * @param Entity $foo
  375. */
  376. public function doSomething($foo)
  377. {
  378. $bar = $foo->toArray();
  379. /** @var ArrayInterface $bar */
  380. return function () use ($bar, $baz) {};
  381. }
  382. }
  383. EOF;
  384. $this->doTest($expected, $input);
  385. }
  386. public function testFixWithDifferentCases(): void
  387. {
  388. $expected = <<<'EOF'
  389. The normal
  390. use of this fixer
  391. should not change this sentence nor those statements below
  392. use Zoo\Baz;
  393. use abc\Bar;
  394. <?php
  395. use abc\Bar;
  396. use Zoo\Baz;
  397. class Test
  398. {
  399. }
  400. EOF;
  401. $input = <<<'EOF'
  402. The normal
  403. use of this fixer
  404. should not change this sentence nor those statements below
  405. use Zoo\Baz;
  406. use abc\Bar;
  407. <?php
  408. use Zoo\Baz;
  409. use abc\Bar;
  410. class Test
  411. {
  412. }
  413. EOF;
  414. $this->doTest($expected, $input);
  415. }
  416. public function testWithoutUses(): void
  417. {
  418. $expected = <<<'EOF'
  419. <?php
  420. $c = 1;
  421. EOF;
  422. $this->doTest($expected);
  423. }
  424. public function testOrderWithTrailingDigit(): void
  425. {
  426. $expected = <<<'EOF'
  427. <?php
  428. use abc\Bar;
  429. use abc2\Bar2;
  430. use xyz\abc\Bar6;
  431. use xyz\abc2\Bar7;
  432. use xyz\xyz\Bar4;
  433. use xyz\xyz\Bar5;
  434. class Test
  435. {
  436. }
  437. EOF;
  438. $input = <<<'EOF'
  439. <?php
  440. use abc2\Bar2;
  441. use abc\Bar;
  442. use xyz\abc2\Bar7;
  443. use xyz\abc\Bar6;
  444. use xyz\xyz\Bar4;
  445. use xyz\xyz\Bar5;
  446. class Test
  447. {
  448. }
  449. EOF;
  450. $this->doTest($expected, $input);
  451. }
  452. public function testCodeWithImportsOnly(): void
  453. {
  454. $expected = <<<'EOF'
  455. <?php
  456. use Aaa;
  457. use Bbb;
  458. EOF;
  459. $input = <<<'EOF'
  460. <?php
  461. use Bbb;
  462. use Aaa;
  463. EOF;
  464. $this->doTest($expected, $input);
  465. }
  466. public function testCodeWithCloseTag(): void
  467. {
  468. $this->doTest(
  469. '<?php
  470. use A\C1;
  471. use A\D?><?php use B\C2; use E\F ?>',
  472. '<?php
  473. use A\C1;
  474. use B\C2?><?php use A\D; use E\F ?>'
  475. );
  476. }
  477. public function testCodeWithComments(): void
  478. {
  479. $this->doTest(
  480. '<?php
  481. use A\C1 /* A */;
  482. use /* B */ B\C2;',
  483. '<?php
  484. use /* B */ B\C2;
  485. use A\C1 /* A */;'
  486. );
  487. }
  488. /**
  489. * @requires PHP <8.0
  490. */
  491. public function testCodeWithCommentsAndMultiLine(): void
  492. {
  493. $this->doTest(
  494. '<?php
  495. use#
  496. A\C1;
  497. use B#
  498. \C2#
  499. #
  500. ;',
  501. '<?php
  502. use#
  503. B#
  504. \C2#
  505. #
  506. ;
  507. use A\C1;'
  508. );
  509. }
  510. /**
  511. * @param array<string, mixed> $config
  512. *
  513. * @dataProvider provideFixCases
  514. */
  515. public function testFix(string $expected, ?string $input = null, array $config = []): void
  516. {
  517. $this->fixer->configure($config);
  518. $this->doTest($expected, $input);
  519. }
  520. public static function provideFixCases(): iterable
  521. {
  522. yield [
  523. <<<'EOF'
  524. The normal
  525. use of this fixer
  526. should not change this sentence nor those statements below
  527. use Zoo\Bar as ZooBar;
  528. use Foo\Bar;
  529. use Foo\Zar\Baz;
  530. <?php
  531. use Foo\Bar;
  532. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar as FooBaz;
  533. use Foo\Bir as FBB;
  534. use Foo\Zar\Baz;
  535. use SomeClass;
  536. use Symfony\Annotation\Template, Zoo\Bar as ZooBar;
  537. use Zoo\Tar;
  538. $a = new Bar();
  539. $a = new FooBaz();
  540. $a = new someclass();
  541. class AnnotatedClass
  542. {
  543. /**
  544. * @Template(foobar=21)
  545. * @param Entity $foo
  546. */
  547. public function doSomething($foo)
  548. {
  549. $bar = $foo->toArray();
  550. /** @var ArrayInterface $bar */
  551. return function () use ($bar, $foo) {};
  552. }
  553. }
  554. EOF
  555. ,
  556. <<<'EOF'
  557. The normal
  558. use of this fixer
  559. should not change this sentence nor those statements below
  560. use Zoo\Bar as ZooBar;
  561. use Foo\Bar;
  562. use Foo\Zar\Baz;
  563. <?php
  564. use Foo\Bar\FooBar as FooBaz;
  565. use Zoo\Bar as ZooBar, Zoo\Tar;
  566. use Foo\Bar;
  567. use Foo\Zar\Baz;
  568. use Symfony\Annotation\Template;
  569. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  570. use SomeClass;
  571. $a = new Bar();
  572. $a = new FooBaz();
  573. $a = new someclass();
  574. class AnnotatedClass
  575. {
  576. /**
  577. * @Template(foobar=21)
  578. * @param Entity $foo
  579. */
  580. public function doSomething($foo)
  581. {
  582. $bar = $foo->toArray();
  583. /** @var ArrayInterface $bar */
  584. return function () use ($bar, $foo) {};
  585. }
  586. }
  587. EOF
  588. ,
  589. ];
  590. yield [
  591. '<?php
  592. use A\B;
  593. use some\a\{ClassA, ClassB, ClassC as C};
  594. use some\b\{
  595. ClassF,
  596. ClassG
  597. };
  598. use const some\a\{ConstA, ConstB, ConstC};
  599. use const some\b\{
  600. ConstX,
  601. ConstY,
  602. ConstZ
  603. };
  604. use function some\a\{fn_a, fn_b, fn_c};
  605. use function some\b\{
  606. fn_x,
  607. fn_y,
  608. fn_z
  609. };
  610. ',
  611. '<?php
  612. use some\a\{ClassA, ClassB, ClassC as C};
  613. use function some\b\{
  614. fn_y,
  615. fn_z,
  616. fn_x
  617. };
  618. use function some\a\{fn_a, fn_b, fn_c};
  619. use A\B;
  620. use const some\b\{
  621. ConstZ,
  622. ConstX,
  623. ConstY
  624. };
  625. use const some\a\{ConstA, ConstB, ConstC};
  626. use some\b\{
  627. ClassG,
  628. ClassF
  629. };
  630. ',
  631. [
  632. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  633. 'imports_order' => ['class', 'const', 'function'],
  634. ],
  635. ];
  636. yield [
  637. '<?php
  638. use A\B;
  639. use some\a\{ClassA as A /*z*/, ClassB, ClassC};
  640. use const some\a\{
  641. ConstA,
  642. ConstB,
  643. ConstC
  644. };
  645. use function some\a\{fn_a, fn_b, fn_c};
  646. ',
  647. '<?php
  648. use some\a\{ ClassB,ClassC, /*z*/ ClassA as A};
  649. use function some\a\{fn_c, fn_a,fn_b };
  650. use A\B;
  651. use const some\a\{
  652. ConstA,
  653. ConstB,
  654. ConstC
  655. };
  656. ',
  657. [
  658. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  659. 'imports_order' => ['class', 'const', 'function'],
  660. ],
  661. ];
  662. yield [
  663. '<?php
  664. use A\B;
  665. use some\a\{ClassA, ClassB, ClassC as C};
  666. use const some\a\{ConstA, ConstB, ConstC};
  667. use function some\a\{fn_a, fn_b, fn_c};
  668. use some\b\{
  669. ClassF,
  670. ClassG
  671. };
  672. use const some\b\{
  673. ConstX,
  674. ConstY,
  675. ConstZ
  676. };
  677. use function some\b\{
  678. fn_x,
  679. fn_y,
  680. fn_z
  681. };
  682. ',
  683. '<?php
  684. use some\a\{ClassA, ClassB, ClassC as C};
  685. use function some\b\{
  686. fn_y,
  687. fn_z,
  688. fn_x
  689. };
  690. use function some\a\{fn_a, fn_b, fn_c};
  691. use A\B;
  692. use const some\b\{
  693. ConstZ,
  694. ConstX,
  695. ConstY
  696. };
  697. use const some\a\{ConstA, ConstB, ConstC};
  698. use some\b\{
  699. ClassG,
  700. ClassF
  701. };
  702. ',
  703. ];
  704. yield [
  705. '<?php
  706. use A\B;
  707. use const some\a\{
  708. ConstA,
  709. ConstB,
  710. ConstC
  711. };
  712. use some\a\{ClassA as A /*z2*/, ClassB, ClassC};
  713. use function some\a\{fn_a, fn_b, fn_c};
  714. ',
  715. '<?php
  716. use some\a\{ ClassB,ClassC, /*z2*/ ClassA as A};
  717. use function some\a\{fn_c, fn_a,fn_b };
  718. use A\B;
  719. use const some\a\{
  720. ConstA,
  721. ConstB,
  722. ConstC
  723. };
  724. ',
  725. ];
  726. yield [
  727. '<?php
  728. use C\B;
  729. use function B\fn_a;
  730. use const A\ConstA;
  731. ',
  732. '<?php
  733. use const A\ConstA;
  734. use function B\fn_a;
  735. use C\B;
  736. ',
  737. [
  738. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  739. 'imports_order' => ['class', 'function', 'const'],
  740. ],
  741. ];
  742. yield [
  743. '<?php
  744. use Foo\Bar\Baz;use Foo\Bar\{ClassA, ClassB, ClassC};
  745. use Foo\Bir;
  746. ',
  747. '<?php
  748. use Foo\Bar\Baz, Foo\Bir;
  749. use Foo\Bar\{ClassC, ClassB, ClassA};
  750. ',
  751. ];
  752. yield [
  753. '<?php
  754. use A\A;use Foo3\Bar\{ClassA};use G\G;use H\H;use Ioo2\Bar\{ClassB};use J\J;use K\K;use Loo1\Bar\{ClassC};use M\M;
  755. ',
  756. '<?php
  757. use A\A,G\G;use Foo3\Bar\{ClassA};use H\H,J\J;use Ioo2\Bar\{ClassB};use K\K,M\M;use Loo1\Bar\{ClassC};
  758. ',
  759. ];
  760. yield [
  761. '<?php
  762. use Foo\Bar\Baz;use Foo\Bar\{ClassA, ClassB, ClassC};
  763. use Foo\Bir;
  764. ',
  765. '<?php
  766. use Foo\Bar\Baz, Foo\Bir;
  767. use Foo\Bar\{ClassC, ClassB, ClassA};
  768. ',
  769. ];
  770. yield [
  771. '<?php
  772. use Foo\Bar\{ClassA, ClassB, ClassC};
  773. use Foo\Bir\{
  774. ClassD,
  775. ClassE,
  776. ClassF
  777. };
  778. use Foo\Bor\{
  779. ClassG,
  780. ClassH,
  781. ClassI,
  782. ClassJ
  783. };
  784. ',
  785. '<?php
  786. use Foo\Bar\{ClassC, ClassB, ClassA};
  787. use Foo\Bir\{ClassE, ClassF,
  788. ClassD};
  789. use Foo\Bor\{
  790. ClassJ,
  791. ClassI,
  792. ClassH,
  793. ClassG
  794. };
  795. ',
  796. ];
  797. yield 'alpha - [\'class\', \'function\', \'const\']' => [
  798. '<?php
  799. use Z\Z;
  800. use function X\X;
  801. use const Y\Y;
  802. ',
  803. '<?php
  804. use const Y\Y;
  805. use function X\X;
  806. use Z\Z;
  807. ',
  808. [
  809. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  810. 'imports_order' => ['class', 'function', 'const'],
  811. ],
  812. ];
  813. yield 'alpha - [\'class\', \'const\', \'function\']' => [
  814. '<?php
  815. use Z\Z;
  816. use const Y\Y;
  817. use function X\X;
  818. ',
  819. '<?php
  820. use function X\X;
  821. use const Y\Y;
  822. use Z\Z;
  823. ',
  824. [
  825. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  826. 'imports_order' => ['class', 'const', 'function'],
  827. ],
  828. ];
  829. yield 'alpha - [\'function\', \'class\', \'const\']' => [
  830. '<?php
  831. use function Z\Z;
  832. use Y\Y;
  833. use const X\X;
  834. ',
  835. '<?php
  836. use const X\X;
  837. use Y\Y;
  838. use function Z\Z;
  839. ',
  840. [
  841. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  842. 'imports_order' => ['function', 'class', 'const'],
  843. ],
  844. ];
  845. yield 'alpha - [\'function\', \'const\', \'class\']' => [
  846. '<?php
  847. use function Z\Z;
  848. use const Y\Y;
  849. use X\X;
  850. ',
  851. '<?php
  852. use X\X;
  853. use const Y\Y;
  854. use function Z\Z;
  855. ',
  856. [
  857. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  858. 'imports_order' => ['function', 'const', 'class'],
  859. ],
  860. ];
  861. yield 'alpha - [\'const\', \'function\', \'class\']' => [
  862. '<?php
  863. use const Z\Z;
  864. use function Y\Y;
  865. use X\X;
  866. ',
  867. '<?php
  868. use X\X;
  869. use function Y\Y;
  870. use const Z\Z;
  871. ',
  872. [
  873. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  874. 'imports_order' => ['const', 'function', 'class'],
  875. ],
  876. ];
  877. yield 'alpha - [\'const\', \'class\', \'function\']' => [
  878. '<?php
  879. use const Z\Z;
  880. use Y\Y;
  881. use function X\X;
  882. ',
  883. '<?php
  884. use function X\X;
  885. use Y\Y;
  886. use const Z\Z;
  887. ',
  888. [
  889. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  890. 'imports_order' => ['const', 'class', 'function'],
  891. ],
  892. ];
  893. yield '"strcasecmp" vs. "strnatcasecmp"' => [
  894. '<?php
  895. use A\A1;
  896. use A\A10;
  897. use A\A2;
  898. use A\A20;
  899. ',
  900. '<?php
  901. use A\A20;
  902. use A\A2;
  903. use A\A10;
  904. use A\A1;
  905. ',
  906. [
  907. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  908. ],
  909. ];
  910. yield [
  911. '<?php
  912. use A\{B,};
  913. use C\{D,E,};
  914. ',
  915. '<?php
  916. use C\{D,E,};
  917. use A\{B,};
  918. ',
  919. ];
  920. yield [
  921. '<?php
  922. use Foo\{
  923. Aaa,
  924. Bbb,
  925. };',
  926. '<?php
  927. use Foo\{
  928. Bbb,
  929. Aaa,
  930. };',
  931. ];
  932. yield [
  933. '<?php
  934. use Foo\{
  935. Aaa /* 3 *//* 4 *//* 5 */,
  936. Bbb /* 1 *//* 2 */,
  937. };',
  938. '<?php
  939. use Foo\{
  940. /* 1 */Bbb/* 2 */,/* 3 */
  941. /* 4 */Aaa/* 5 */,/* 6 */
  942. };',
  943. ];
  944. $input =
  945. '<?php use A\{B,};
  946. use some\y\{ClassA, ClassB, ClassC as C,};
  947. use function some\a\{fn_a, fn_b, fn_c,};
  948. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  949. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  950. use C\{D,E,};
  951. ';
  952. yield [
  953. '<?php use A\{B,};
  954. use C\{D,E,};
  955. use some\y\{ClassA, ClassB, ClassC as C,};
  956. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  957. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  958. use function some\a\{fn_a, fn_b, fn_c,};
  959. ',
  960. $input,
  961. [
  962. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  963. 'imports_order' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  964. ],
  965. ];
  966. yield [
  967. '<?php use A\{B,};
  968. use C\{D,E,};
  969. use some\y\{ClassA, ClassB, ClassC as C,};
  970. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  971. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  972. use function some\a\{fn_a, fn_b, fn_c,};
  973. ',
  974. $input,
  975. [
  976. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  977. 'imports_order' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  978. ],
  979. ];
  980. yield [
  981. '<?php use A\{B,};
  982. use some\y\{ClassA, ClassB, ClassC as C,};
  983. use C\{D,E,};
  984. use const some\Z\{ConstAA,ConstBB,ConstCC,};
  985. use const some\X\{ConstA,ConstB,ConstC,ConstF};
  986. use function some\a\{fn_a, fn_b, fn_c,};
  987. ',
  988. $input,
  989. [
  990. 'sort_algorithm' => OrderedImportsFixer::SORT_NONE,
  991. 'imports_order' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  992. ],
  993. ];
  994. }
  995. public function testUnknownOrderTypes(): void
  996. {
  997. $this->expectException(InvalidFixerConfigurationException::class);
  998. $this->expectExceptionMessage('[ordered_imports] Invalid configuration: Unknown sort types "foo" and "bar".');
  999. $this->fixer->configure([
  1000. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  1001. 'imports_order' => ['class', 'const', 'function', 'foo', 'bar'],
  1002. ]);
  1003. }
  1004. /*
  1005. |--------------------------------------------------------------------------
  1006. | Test sorting by length
  1007. |--------------------------------------------------------------------------
  1008. */
  1009. public function testInvalidOrderTypesSize(): void
  1010. {
  1011. $this->expectException(InvalidFixerConfigurationException::class);
  1012. $this->expectExceptionMessage('[ordered_imports] Invalid configuration: Missing sort type "function".');
  1013. $this->fixer->configure([
  1014. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  1015. 'imports_order' => ['class', 'const'],
  1016. ]);
  1017. }
  1018. public function testInvalidOrderType(): void
  1019. {
  1020. $this->expectException(InvalidFixerConfigurationException::class);
  1021. $this->expectExceptionMessage('[ordered_imports] Invalid configuration: Missing sort type "class".');
  1022. $this->fixer->configure([
  1023. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  1024. 'imports_order' => ['const', 'function', 'bar'],
  1025. ]);
  1026. }
  1027. /**
  1028. * @param array<string, mixed> $configuration
  1029. *
  1030. * @dataProvider provideInvalidSortAlgorithmCases
  1031. */
  1032. public function testInvalidSortAlgorithm(array $configuration, string $expectedValue): void
  1033. {
  1034. $this->expectException(InvalidFixerConfigurationException::class);
  1035. $this->expectExceptionMessage(sprintf(
  1036. '[ordered_imports] Invalid configuration: The option "sort_algorithm" with value %s is invalid. Accepted values are: "alpha", "length", "none".',
  1037. $expectedValue
  1038. ));
  1039. $this->fixer->configure($configuration);
  1040. }
  1041. public static function provideInvalidSortAlgorithmCases(): iterable
  1042. {
  1043. yield [
  1044. [
  1045. 'sort_algorithm' => 'dope',
  1046. 'imports_order' => null,
  1047. ],
  1048. '"dope"',
  1049. ];
  1050. yield [
  1051. [
  1052. 'sort_algorithm' => [OrderedImportsFixer::SORT_ALPHA, OrderedImportsFixer::SORT_LENGTH],
  1053. 'imports_order' => null,
  1054. ],
  1055. 'array',
  1056. ];
  1057. yield [
  1058. [
  1059. 'sort_algorithm' => new \stdClass(),
  1060. 'imports_order' => null,
  1061. ],
  1062. \stdClass::class,
  1063. ];
  1064. }
  1065. public function testByLengthFixWithSameLength(): void
  1066. {
  1067. $this->fixer->configure([
  1068. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1069. 'imports_order' => null,
  1070. ]);
  1071. $expected = <<<'EOF'
  1072. <?php
  1073. use Acme;
  1074. use Bar1;
  1075. use Barr;
  1076. use Fooo;
  1077. class AnnotatedClass
  1078. {
  1079. /**
  1080. * @Template(foobar=21)
  1081. * @param Entity $foo
  1082. */
  1083. public function doSomething($foo)
  1084. {
  1085. $bar = $foo->toArray();
  1086. /** @var ArrayInterface $bar */
  1087. return function () use ($bar, $foo) {};
  1088. }
  1089. }
  1090. EOF;
  1091. $input = <<<'EOF'
  1092. <?php
  1093. use Acme;
  1094. use Fooo;
  1095. use Barr;
  1096. use Bar1;
  1097. class AnnotatedClass
  1098. {
  1099. /**
  1100. * @Template(foobar=21)
  1101. * @param Entity $foo
  1102. */
  1103. public function doSomething($foo)
  1104. {
  1105. $bar = $foo->toArray();
  1106. /** @var ArrayInterface $bar */
  1107. return function () use ($bar, $foo) {};
  1108. }
  1109. }
  1110. EOF;
  1111. $this->doTest($expected, $input);
  1112. }
  1113. public function testByLengthFixWithSameLengthAndCaseSensitive(): void
  1114. {
  1115. $this->fixer->configure([
  1116. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1117. 'imports_order' => null,
  1118. 'case_sensitive' => true,
  1119. ]);
  1120. $expected = <<<'EOF'
  1121. <?php
  1122. use Acme;
  1123. use BaRr;
  1124. use Bar1;
  1125. use Fooo;
  1126. class AnnotatedClass { }
  1127. EOF;
  1128. $input = <<<'EOF'
  1129. <?php
  1130. use Acme;
  1131. use Fooo;
  1132. use Bar1;
  1133. use BaRr;
  1134. class AnnotatedClass { }
  1135. EOF;
  1136. $this->doTest($expected, $input);
  1137. }
  1138. public function testByLengthFixWithMultipleNamespace(): void
  1139. {
  1140. $this->fixer->configure([
  1141. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1142. 'imports_order' => null,
  1143. ]);
  1144. $expected = <<<'EOF'
  1145. <?php
  1146. namespace FooRoo {
  1147. use Foo\Bar;
  1148. use Zoo\Tar1, Zoo\Tar2;
  1149. use SomeClass;
  1150. use Foo\Zar\Baz;
  1151. use Foo\Bir as FBB;
  1152. use Zoo\Bar as ZooBar, Foo\Bar\Foo as Fooo;
  1153. use Foo\Bar\FooBar as FooBaz;
  1154. use Symfony\Annotation\Template;
  1155. $a = new Bar();
  1156. $a = new FooBaz();
  1157. $a = new someclass();
  1158. class AnnotatedClass
  1159. {
  1160. /**
  1161. * @Template(foobar=21)
  1162. * @param Entity $foo
  1163. */
  1164. public function doSomething($foo)
  1165. {
  1166. $bar = $foo->toArray();
  1167. /** @var ArrayInterface $bar */
  1168. return function () use ($bar, $foo) {};
  1169. }
  1170. }
  1171. }
  1172. namespace BlaRoo {
  1173. use Zoo\Bar;
  1174. use SomeClass;
  1175. use Foo\Zar\Baz;
  1176. use Symfony\Annotation\Template, Symfony\Doctrine\Entities\Entity;
  1177. class AnnotatedClass
  1178. {
  1179. /**
  1180. * @Template(foobar=21)
  1181. * @param Entity $foo
  1182. */
  1183. public function doSomething($foo)
  1184. {
  1185. $bar = $foo->toArray();
  1186. /** @var ArrayInterface $bar */
  1187. return function () use ($bar, $foo) {};
  1188. }
  1189. }
  1190. }
  1191. EOF;
  1192. $input = <<<'EOF'
  1193. <?php
  1194. namespace FooRoo {
  1195. use Foo\Bar\FooBar as FooBaz;
  1196. use Zoo\Bar as ZooBar, Zoo\Tar1;
  1197. use Foo\Bar;
  1198. use Foo\Zar\Baz;
  1199. use Symfony\Annotation\Template;
  1200. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1201. use SomeClass;
  1202. use Zoo\Tar2;
  1203. $a = new Bar();
  1204. $a = new FooBaz();
  1205. $a = new someclass();
  1206. class AnnotatedClass
  1207. {
  1208. /**
  1209. * @Template(foobar=21)
  1210. * @param Entity $foo
  1211. */
  1212. public function doSomething($foo)
  1213. {
  1214. $bar = $foo->toArray();
  1215. /** @var ArrayInterface $bar */
  1216. return function () use ($bar, $foo) {};
  1217. }
  1218. }
  1219. }
  1220. namespace BlaRoo {
  1221. use Foo\Zar\Baz;
  1222. use Zoo\Bar;
  1223. use SomeClass;
  1224. use Symfony\Annotation\Template, Symfony\Doctrine\Entities\Entity;
  1225. class AnnotatedClass
  1226. {
  1227. /**
  1228. * @Template(foobar=21)
  1229. * @param Entity $foo
  1230. */
  1231. public function doSomething($foo)
  1232. {
  1233. $bar = $foo->toArray();
  1234. /** @var ArrayInterface $bar */
  1235. return function () use ($bar, $foo) {};
  1236. }
  1237. }
  1238. }
  1239. EOF;
  1240. $this->doTest($expected, $input);
  1241. }
  1242. public function testByLengthFixWithComment(): void
  1243. {
  1244. $this->fixer->configure([
  1245. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1246. 'imports_order' => null,
  1247. ]);
  1248. $expected = <<<'EOF'
  1249. The normal
  1250. use of this fixer
  1251. should not change this sentence nor those statements below
  1252. use Zoo\Bar;
  1253. use Foo\Bar;
  1254. use Foo\Zar\Baz;
  1255. <?php
  1256. use Foo\Bar;
  1257. use Zoo\Tar, SomeClass;
  1258. use Foo\Zar\Baz;
  1259. use Foo\Bir as FBB;
  1260. use Zoo\Bar as ZooBar;
  1261. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar /* He there */ as FooBaz;
  1262. use /* FIXME */Symfony\Annotation\Template;
  1263. $a = new Bar();
  1264. $a = new FooBaz();
  1265. $a = new someclass();
  1266. use Symfony\Doctrine\Entities\Entity;
  1267. class AnnotatedClass
  1268. {
  1269. /**
  1270. * @Template(foobar=21)
  1271. * @param Entity $foo
  1272. */
  1273. public function doSomething($foo)
  1274. {
  1275. $bar = $foo->toArray();
  1276. /** @var ArrayInterface $bar */
  1277. return function () use ($bar, $foo) {};
  1278. }
  1279. }
  1280. EOF;
  1281. $input = <<<'EOF'
  1282. The normal
  1283. use of this fixer
  1284. should not change this sentence nor those statements below
  1285. use Zoo\Bar;
  1286. use Foo\Bar;
  1287. use Foo\Zar\Baz;
  1288. <?php
  1289. use Foo\Bar\FooBar /* He there */ as FooBaz;
  1290. use Zoo\Bar as ZooBar, Zoo\Tar;
  1291. use Foo\Bar;
  1292. use Foo\Zar\Baz;
  1293. use /* FIXME */Symfony\Annotation\Template;
  1294. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1295. use SomeClass;
  1296. $a = new Bar();
  1297. $a = new FooBaz();
  1298. $a = new someclass();
  1299. use Symfony\Doctrine\Entities\Entity;
  1300. class AnnotatedClass
  1301. {
  1302. /**
  1303. * @Template(foobar=21)
  1304. * @param Entity $foo
  1305. */
  1306. public function doSomething($foo)
  1307. {
  1308. $bar = $foo->toArray();
  1309. /** @var ArrayInterface $bar */
  1310. return function () use ($bar, $foo) {};
  1311. }
  1312. }
  1313. EOF;
  1314. $this->doTest($expected, $input);
  1315. }
  1316. public function testByLength(): void
  1317. {
  1318. $this->fixer->configure([
  1319. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1320. 'imports_order' => null,
  1321. ]);
  1322. $expected = <<<'EOF'
  1323. <?php
  1324. use Foo\Bar;
  1325. use Zoo\Tar, SomeClass;
  1326. use Foo\Zar\Baz;
  1327. use Foo\Bir as FBB;
  1328. use Zoo\Bar as ZooBar;
  1329. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar as FooBaz;
  1330. use Symfony\Annotation\Template;
  1331. use Symfony\Doctrine\Entities\Entity;
  1332. trait Foo {}
  1333. trait Zoo {}
  1334. class AnnotatedClass
  1335. {
  1336. use Foo, Bar;
  1337. /**
  1338. * @Template(foobar=21)
  1339. * @param Entity $foo
  1340. */
  1341. public function doSomething($foo)
  1342. {
  1343. $bar = $foo->toArray();
  1344. /** @var ArrayInterface $bar */
  1345. return function () use ($bar, $foo) {};
  1346. }
  1347. }
  1348. EOF;
  1349. $input = <<<'EOF'
  1350. <?php
  1351. use Foo\Bar\FooBar as FooBaz;
  1352. use Zoo\Bar as ZooBar, Zoo\Tar;
  1353. use Foo\Bar;
  1354. use Foo\Zar\Baz;
  1355. use Symfony\Annotation\Template;
  1356. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1357. use SomeClass;
  1358. use Symfony\Doctrine\Entities\Entity;
  1359. trait Foo {}
  1360. trait Zoo {}
  1361. class AnnotatedClass
  1362. {
  1363. use Foo, Bar;
  1364. /**
  1365. * @Template(foobar=21)
  1366. * @param Entity $foo
  1367. */
  1368. public function doSomething($foo)
  1369. {
  1370. $bar = $foo->toArray();
  1371. /** @var ArrayInterface $bar */
  1372. return function () use ($bar, $foo) {};
  1373. }
  1374. }
  1375. EOF;
  1376. $this->doTest($expected, $input);
  1377. }
  1378. public function testByLengthFixWithTraitImports(): void
  1379. {
  1380. $this->fixer->configure([
  1381. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1382. 'imports_order' => null,
  1383. ]);
  1384. $expected = <<<'EOF'
  1385. The normal
  1386. use of this fixer
  1387. should not change this sentence nor those statements below
  1388. use Zoo\Bar;
  1389. use Foo\Bar;
  1390. use Foo\Zar\Baz;
  1391. <?php
  1392. use Foo\Bar;
  1393. use Zoo\Tar, SomeClass;
  1394. use Foo\Zar\Baz;
  1395. use Foo\Bir as FBB;
  1396. use Zoo\Bar as ZooBar;
  1397. use Foo\Bar\Foo as Fooo;
  1398. use Acme\MyReusableTrait, Foo\Bar\FooBar as FooBaz;
  1399. use Symfony\Annotation\Template;
  1400. $a = new Bar();
  1401. $a = new FooBaz();
  1402. $a = new someclass();
  1403. use Symfony\Doctrine\Entities\Entity;
  1404. class AnnotatedClass
  1405. {
  1406. use MyReusableTrait;
  1407. /**
  1408. * @Template(foobar=21)
  1409. * @param Entity $foo
  1410. */
  1411. public function doSomething($foo)
  1412. {
  1413. $bar = $foo->toArray();
  1414. /** @var ArrayInterface $bar */
  1415. return function () use ($bar, $baz) {};
  1416. }
  1417. }
  1418. EOF;
  1419. $input = <<<'EOF'
  1420. The normal
  1421. use of this fixer
  1422. should not change this sentence nor those statements below
  1423. use Zoo\Bar;
  1424. use Foo\Bar;
  1425. use Foo\Zar\Baz;
  1426. <?php
  1427. use Foo\Bar\FooBar as FooBaz;
  1428. use Zoo\Bar as ZooBar, Zoo\Tar;
  1429. use Foo\Bar;
  1430. use Foo\Zar\Baz;
  1431. use Acme\MyReusableTrait;
  1432. use Symfony\Annotation\Template;
  1433. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1434. use SomeClass;
  1435. $a = new Bar();
  1436. $a = new FooBaz();
  1437. $a = new someclass();
  1438. use Symfony\Doctrine\Entities\Entity;
  1439. class AnnotatedClass
  1440. {
  1441. use MyReusableTrait;
  1442. /**
  1443. * @Template(foobar=21)
  1444. * @param Entity $foo
  1445. */
  1446. public function doSomething($foo)
  1447. {
  1448. $bar = $foo->toArray();
  1449. /** @var ArrayInterface $bar */
  1450. return function () use ($bar, $baz) {};
  1451. }
  1452. }
  1453. EOF;
  1454. $this->doTest($expected, $input);
  1455. }
  1456. public function testByLengthFixWithDifferentCases(): void
  1457. {
  1458. $this->fixer->configure([
  1459. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1460. 'imports_order' => null,
  1461. ]);
  1462. $expected = <<<'EOF'
  1463. The normal
  1464. use of this fixer
  1465. should not change this sentence nor those statements below
  1466. use Zoo\Baz;
  1467. use abc\Bar;
  1468. <?php
  1469. use abc\Bar;
  1470. use Zoo\Baz;
  1471. class Test
  1472. {
  1473. }
  1474. EOF;
  1475. $input = <<<'EOF'
  1476. The normal
  1477. use of this fixer
  1478. should not change this sentence nor those statements below
  1479. use Zoo\Baz;
  1480. use abc\Bar;
  1481. <?php
  1482. use Zoo\Baz;
  1483. use abc\Bar;
  1484. class Test
  1485. {
  1486. }
  1487. EOF;
  1488. $this->doTest($expected, $input);
  1489. }
  1490. public function testByLengthOrderWithTrailingDigit(): void
  1491. {
  1492. $this->fixer->configure([
  1493. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1494. 'imports_order' => null,
  1495. ]);
  1496. $expected = <<<'EOF'
  1497. <?php
  1498. use abc\Bar;
  1499. use abc2\Bar2;
  1500. use xyz\abc\Bar6;
  1501. use xyz\xyz\Bar4;
  1502. use xyz\xyz\Bar5;
  1503. use xyz\abc2\Bar7;
  1504. class Test
  1505. {
  1506. }
  1507. EOF;
  1508. $input = <<<'EOF'
  1509. <?php
  1510. use abc2\Bar2;
  1511. use abc\Bar;
  1512. use xyz\abc2\Bar7;
  1513. use xyz\abc\Bar6;
  1514. use xyz\xyz\Bar4;
  1515. use xyz\xyz\Bar5;
  1516. class Test
  1517. {
  1518. }
  1519. EOF;
  1520. $this->doTest($expected, $input);
  1521. }
  1522. public function testByLengthCodeWithImportsOnly(): void
  1523. {
  1524. $this->fixer->configure([
  1525. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1526. 'imports_order' => null,
  1527. ]);
  1528. $expected = <<<'EOF'
  1529. <?php
  1530. use Aaa;
  1531. use Bbb;
  1532. EOF;
  1533. $input = <<<'EOF'
  1534. <?php
  1535. use Bbb;
  1536. use Aaa;
  1537. EOF;
  1538. $this->doTest($expected, $input);
  1539. }
  1540. public function testByLengthWithoutUses(): void
  1541. {
  1542. $this->fixer->configure([
  1543. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1544. 'imports_order' => null,
  1545. ]);
  1546. $expected = <<<'EOF'
  1547. <?php
  1548. $c = 1;
  1549. EOF;
  1550. $this->doTest($expected);
  1551. }
  1552. /**
  1553. * @dataProvider provideFixByLengthCases
  1554. */
  1555. public function testFixByLength(string $expected, ?string $input = null): void
  1556. {
  1557. $this->fixer->configure([
  1558. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1559. 'imports_order' => null,
  1560. ]);
  1561. $this->doTest($expected, $input);
  1562. }
  1563. public static function provideFixByLengthCases(): iterable
  1564. {
  1565. yield [
  1566. <<<'EOF'
  1567. The normal
  1568. use of this fixer
  1569. should not change this sentence nor those statements below
  1570. use Zoo\Bar as ZooBar;
  1571. use Foo\Bar;
  1572. use Foo\Zar\Baz;
  1573. <?php
  1574. use Foo\Bar;
  1575. use Zoo\Tar, SomeClass;
  1576. use Foo\Zar\Baz;
  1577. use Foo\Bir as FBB;
  1578. use Zoo\Bar as ZooBar;
  1579. use Foo\Bar\Foo as Fooo, Foo\Bar\FooBar as FooBaz;
  1580. use Symfony\Annotation\Template;
  1581. $a = new Bar();
  1582. $a = new FooBaz();
  1583. $a = new someclass();
  1584. use Symfony\Doctrine\Entities\Entity;
  1585. class AnnotatedClass
  1586. {
  1587. /**
  1588. * @Template(foobar=21)
  1589. * @param Entity $foo
  1590. */
  1591. public function doSomething($foo)
  1592. {
  1593. $bar = $foo->toArray();
  1594. /** @var ArrayInterface $bar */
  1595. return function () use ($bar, $foo) {};
  1596. }
  1597. }
  1598. EOF
  1599. ,
  1600. <<<'EOF'
  1601. The normal
  1602. use of this fixer
  1603. should not change this sentence nor those statements below
  1604. use Zoo\Bar as ZooBar;
  1605. use Foo\Bar;
  1606. use Foo\Zar\Baz;
  1607. <?php
  1608. use Foo\Bar\FooBar as FooBaz;
  1609. use Zoo\Bar as ZooBar, Zoo\Tar;
  1610. use Foo\Bar;
  1611. use Foo\Zar\Baz;
  1612. use Symfony\Annotation\Template;
  1613. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1614. use SomeClass;
  1615. $a = new Bar();
  1616. $a = new FooBaz();
  1617. $a = new someclass();
  1618. use Symfony\Doctrine\Entities\Entity;
  1619. class AnnotatedClass
  1620. {
  1621. /**
  1622. * @Template(foobar=21)
  1623. * @param Entity $foo
  1624. */
  1625. public function doSomething($foo)
  1626. {
  1627. $bar = $foo->toArray();
  1628. /** @var ArrayInterface $bar */
  1629. return function () use ($bar, $foo) {};
  1630. }
  1631. }
  1632. EOF
  1633. ,
  1634. ];
  1635. yield [
  1636. '<?php
  1637. use A\B;
  1638. use Foo\Bar\Biz;
  1639. use some\b\{
  1640. ClassF,
  1641. ClassG
  1642. };
  1643. use function some\a\{fn_a, fn_b, fn_c};
  1644. use some\b\{ClassA, ClassB, ClassC as C};
  1645. use const some\a\{ConstA, ConstB, ConstC};
  1646. use some\a\{ClassX as X /*z*/, ClassY, ClassZ};
  1647. use Some\Biz\Barz\Boozz\Foz\Which\Is\Really\Long;
  1648. use const some\b\{ConstG, ConstX, ConstY, ConstZ};
  1649. use some\c\{ClassR, ClassT, ClassV as V, NiceClassName};
  1650. ',
  1651. '<?php
  1652. use function some\a\{fn_a, fn_b, fn_c};
  1653. use Foo\Bar\Biz;
  1654. use some\c\{ClassR, ClassT, ClassV as V, NiceClassName};
  1655. use A\B;
  1656. use Some\Biz\Barz\Boozz\Foz\Which\Is\Really\Long;
  1657. use some\b\{
  1658. ClassF,
  1659. ClassG
  1660. };
  1661. use const some\a\{ConstB, ConstA, ConstC};
  1662. use const some\b\{ConstX, ConstY, ConstZ, ConstG};
  1663. use some\b\{ClassA, ClassB, ClassC as C};
  1664. use some\a\{ ClassY,ClassZ, /*z*/ ClassX as X};
  1665. ',
  1666. ];
  1667. yield [
  1668. '<?php
  1669. use const ZZZ;
  1670. use function B;
  1671. use function A123;
  1672. ',
  1673. '<?php
  1674. use function B;
  1675. use function A123;
  1676. use const ZZZ;
  1677. ',
  1678. ];
  1679. }
  1680. /**
  1681. * @dataProvider provideFixTypesOrderAndLengthCases
  1682. */
  1683. public function testFixTypesOrderAndLength(string $expected, ?string $input = null): void
  1684. {
  1685. $this->fixer->configure([
  1686. 'sort_algorithm' => OrderedImportsFixer::SORT_LENGTH,
  1687. 'imports_order' => [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  1688. ]);
  1689. $this->doTest($expected, $input);
  1690. }
  1691. public static function provideFixTypesOrderAndLengthCases(): iterable
  1692. {
  1693. yield [
  1694. '<?php
  1695. use A\B;
  1696. use Some\Bar;
  1697. use Foo\Zar\Baz;
  1698. use some\b\{
  1699. ClassF,
  1700. ClassG
  1701. };
  1702. use some\a\{ClassA, ClassB, ClassC as C};
  1703. use some\b\{ClassK, ClassL, ClassM as M};
  1704. use some\a\{ClassX as X /*z*/, ClassY, ClassZ};
  1705. use const some\a\{ConstA, ConstB, ConstC};
  1706. use const some\b\{ConstD, ConstE, ConstF};
  1707. use function some\a\{fn_a, fn_b};
  1708. use function some\f\{fn_c, fn_d, fn_e};
  1709. use function some\b\{fn_k, fn_l, func_m};
  1710. ',
  1711. '<?php
  1712. use const some\a\{ConstA, ConstB, ConstC};
  1713. use some\a\{ClassA, ClassB, ClassC as C};
  1714. use Foo\Zar\Baz;
  1715. use some\b\{ClassK, ClassL, ClassM as M};
  1716. use some\a\{ClassX as X /*z*/, ClassY, ClassZ};
  1717. use A\B;
  1718. use some\b\{
  1719. ClassF,
  1720. ClassG
  1721. };
  1722. use function some\b\{fn_k, fn_l, func_m};
  1723. use Some\Bar;
  1724. use function some\a\{fn_a, fn_b};
  1725. use const some\b\{ConstD, ConstE, ConstF};
  1726. use function some\f\{fn_c, fn_d, fn_e};
  1727. ',
  1728. ];
  1729. }
  1730. /**
  1731. * @dataProvider provideFixTypesOrderAndAlphabetCases
  1732. *
  1733. * @param string[] $importOrder
  1734. */
  1735. public function testFixTypesOrderAndAlphabet(string $expected, ?string $input = null, array $importOrder = null): void
  1736. {
  1737. $this->fixer->configure([
  1738. 'sort_algorithm' => OrderedImportsFixer::SORT_ALPHA,
  1739. 'imports_order' => $importOrder,
  1740. ]);
  1741. $this->doTest($expected, $input);
  1742. }
  1743. public static function provideFixTypesOrderAndAlphabetCases(): iterable
  1744. {
  1745. yield [
  1746. '<?php
  1747. use Aaa\Bbb;
  1748. use Aaa\Ccc;
  1749. use Bar\Biz\Boooz\Bum;
  1750. use Foo\Zar\Baz;
  1751. use some\a\{ClassA};
  1752. use some\b\{
  1753. ClassF,
  1754. ClassG
  1755. };
  1756. use some\b\{ClassB, ClassC as C, ClassD};
  1757. use Some\Cloz;
  1758. use const some\a\{ConstA};
  1759. use const some\a\{ConstB, ConstC as CC};
  1760. use const some\a\{ConstD};
  1761. use const some\b\{ConstE};
  1762. use function some\a\{fn_a, fn_b};
  1763. use function some\a\{fn_bc};
  1764. use function some\b\{fn_c, fn_d, fn_e};
  1765. use function some\c\{fn_f};
  1766. use function some\f\{fn_g, fn_h, fn_i};
  1767. ',
  1768. '<?php
  1769. use Aaa\Ccc;
  1770. use Foo\Zar\Baz;
  1771. use function some\f\{fn_g, fn_h, fn_i};
  1772. use some\a\{ClassA};
  1773. use some\b\{ClassD, ClassB, ClassC as C};
  1774. use Bar\Biz\Boooz\Bum;
  1775. use function some\c\{fn_f};
  1776. use some\b\{
  1777. ClassF,
  1778. ClassG
  1779. };
  1780. use const some\a\{ConstD};
  1781. use Some\Cloz;
  1782. use function some\a\{fn_bc};
  1783. use const some\a\{ConstA};
  1784. use function some\b\{fn_c, fn_d, fn_e};
  1785. use const some\a\{ConstB, ConstC as CC};
  1786. use Aaa\Bbb;
  1787. use const some\b\{ConstE};
  1788. use function some\a\{fn_a, fn_b};
  1789. ',
  1790. [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  1791. ];
  1792. }
  1793. /**
  1794. * @dataProvider provideFixTypesOrderAndNoneCases
  1795. *
  1796. * @param null|string[] $importOrder
  1797. */
  1798. public function testFixTypesOrderAndNone(string $expected, ?string $input = null, array $importOrder = null): void
  1799. {
  1800. $this->fixer->configure([
  1801. 'sort_algorithm' => OrderedImportsFixer::SORT_NONE,
  1802. 'imports_order' => $importOrder,
  1803. ]);
  1804. $this->doTest($expected, $input);
  1805. }
  1806. public static function provideFixTypesOrderAndNoneCases(): iterable
  1807. {
  1808. yield [
  1809. '<?php
  1810. use Aaa\Ccc;
  1811. use Foo\Zar\Baz;
  1812. use some\a\{ClassA};
  1813. use some\b\{ClassD, ClassB, ClassC as C};
  1814. use Bar\Biz\Boooz\Bum;
  1815. use some\b\{
  1816. ClassF,
  1817. ClassG
  1818. };
  1819. use Some\Cloz;
  1820. use Aaa\Bbb;
  1821. use const some\a\{ConstD};
  1822. use const some\a\{ConstA};
  1823. use const some\a\{ConstB, ConstC as CC};
  1824. use const some\b\{ConstE};
  1825. use function some\f\{fn_g, fn_h, fn_i};
  1826. use function some\c\{fn_f};
  1827. use function some\a\{fn_x};
  1828. use function some\b\{fn_c, fn_d, fn_e};
  1829. use function some\a\{fn_a, fn_b};
  1830. ',
  1831. '<?php
  1832. use Aaa\Ccc;
  1833. use Foo\Zar\Baz;
  1834. use function some\f\{fn_g, fn_h, fn_i};
  1835. use some\a\{ClassA};
  1836. use some\b\{ClassD, ClassB, ClassC as C};
  1837. use Bar\Biz\Boooz\Bum;
  1838. use function some\c\{fn_f};
  1839. use some\b\{
  1840. ClassF,
  1841. ClassG
  1842. };
  1843. use const some\a\{ConstD};
  1844. use Some\Cloz;
  1845. use function some\a\{fn_x};
  1846. use const some\a\{ConstA};
  1847. use function some\b\{fn_c, fn_d, fn_e};
  1848. use const some\a\{ConstB, ConstC as CC};
  1849. use Aaa\Bbb;
  1850. use const some\b\{ConstE};
  1851. use function some\a\{fn_a, fn_b};
  1852. ',
  1853. [OrderedImportsFixer::IMPORT_TYPE_CLASS, OrderedImportsFixer::IMPORT_TYPE_CONST, OrderedImportsFixer::IMPORT_TYPE_FUNCTION],
  1854. ];
  1855. }
  1856. public function testFixByNone(): void
  1857. {
  1858. $this->fixer->configure([
  1859. 'sort_algorithm' => OrderedImportsFixer::SORT_NONE,
  1860. 'imports_order' => null,
  1861. ]);
  1862. $expected = <<<'EOF'
  1863. The normal
  1864. use of this fixer
  1865. should not change this sentence nor those statements below
  1866. use Zoo\Bar as ZooBar;
  1867. use Foo\Bar;
  1868. use Foo\Zar\Baz;
  1869. <?php
  1870. use Foo\Bar\FooBar as FooBaz;
  1871. use Zoo\Bar as ZooBar, Zoo\Tar;
  1872. use Foo\Bar;
  1873. use Foo\Zar\Baz;
  1874. use Symfony\Annotation\Template;
  1875. use Foo\Bar\Foo as Fooo, Foo\Bir as FBB;
  1876. use SomeClass;
  1877. $a = new Bar();
  1878. $a = new FooBaz();
  1879. $a = new someclass();
  1880. use Symfony\Doctrine\Entities\Entity;
  1881. class AnnotatedClass
  1882. {
  1883. /**
  1884. * @Template(foobar=21)
  1885. * @param Entity $foo
  1886. */
  1887. public function doSomething($foo)
  1888. {
  1889. $bar = $foo->toArray();
  1890. /** @var ArrayInterface $bar */
  1891. return function () use ($bar, $foo) {};
  1892. }
  1893. }
  1894. EOF;
  1895. $this->doTest($expected);
  1896. }
  1897. public function testFixWithCaseSensitive(): void
  1898. {
  1899. $this->fixer->configure([
  1900. 'case_sensitive' => true,
  1901. ]);
  1902. $expected = <<<'EOF'
  1903. <?php
  1904. use AA;
  1905. use Aaa;
  1906. class Foo { }
  1907. EOF;
  1908. $input = <<<'EOF'
  1909. <?php
  1910. use Aaa;
  1911. use AA;
  1912. class Foo { }
  1913. EOF;
  1914. $this->doTest($expected, $input);
  1915. }
  1916. }