OrderedImportsFixerTest.php 56 KB

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