ClassAttributesSeparationFixerTest.php 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of PHP CS Fixer.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  12. namespace PhpCsFixer\Tests\Fixer\ClassNotation;
  13. use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. use PhpCsFixer\Tokenizer\Tokens;
  16. use PhpCsFixer\WhitespacesFixerConfig;
  17. /**
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer
  21. *
  22. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer>
  23. *
  24. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer
  25. */
  26. final class ClassAttributesSeparationFixerTest extends AbstractFixerTestCase
  27. {
  28. /**
  29. * @param _AutogeneratedInputConfiguration $configuration
  30. *
  31. * @dataProvider provideFixCases
  32. */
  33. public function testFix(string $expected, ?string $input = null, array $configuration = []): void
  34. {
  35. $this->fixer->configure($configuration);
  36. $this->doTest($expected, $input);
  37. }
  38. public static function provideFixCases(): iterable
  39. {
  40. yield [
  41. '<?php
  42. class Sample
  43. {
  44. private $a; // foo
  45. /** second in a hour */
  46. private $b;
  47. }
  48. ',
  49. '<?php
  50. class Sample
  51. {private $a; // foo
  52. /** second in a hour */
  53. private $b;
  54. }
  55. ',
  56. ];
  57. yield 'empty class' => [
  58. '<?php class Foo {}',
  59. ];
  60. yield 'simple top class' => [
  61. '<?php class A {
  62. public function Foo(){}
  63. }',
  64. '<?php class A {public function Foo(){}}',
  65. ];
  66. yield 'comment' => [
  67. '<?php class A {
  68. /* function comment */
  69. public function Bar(){}
  70. }',
  71. '<?php class A {/* function comment */public function Bar(){}
  72. }',
  73. ];
  74. yield 'comment, multiple lines' => [
  75. '<?php class A {
  76. /* some comment */
  77. public function Bar(){}
  78. }',
  79. '<?php class A {
  80. /* some comment */
  81. public function Bar(){}
  82. }',
  83. ];
  84. yield 'simple PHPDoc case' => [
  85. '<?php class Foo
  86. {
  87. /** Doc 1 */
  88. public function A(){}
  89. /** Doc 2 */
  90. public function B(){}
  91. }',
  92. '<?php class Foo
  93. {/** Doc 1 */public function A(){}
  94. /** Doc 2 */
  95. public function B(){}
  96. }',
  97. ];
  98. yield 'add a newline at the end of a class with trait group' => [
  99. '<?php class A
  100. {
  101. use Bar {
  102. __construct as barConstruct;
  103. baz as barBaz;
  104. }
  105. }',
  106. '<?php class A
  107. {
  108. use Bar {
  109. __construct as barConstruct;
  110. baz as barBaz;
  111. }}',
  112. ];
  113. yield 'add a newline at the end of a class with trait' => [
  114. '<?php class A
  115. {
  116. use A\B\C;
  117. }',
  118. '<?php class A
  119. {
  120. use A\B\C;}',
  121. ];
  122. yield 'removes extra lines at the end of an interface' => [
  123. '<?php interface F
  124. {
  125. public function A();
  126. }',
  127. '<?php interface F
  128. {
  129. public function A();
  130. }',
  131. ];
  132. yield 'removes extra lines at the end of an abstract class' => [
  133. '<?php abstract class F
  134. {
  135. public abstract function A();
  136. }',
  137. '<?php abstract class F
  138. {
  139. public abstract function A();
  140. }',
  141. ];
  142. yield 'add a newline at the end of a class' => [
  143. '<?php class A
  144. {
  145. public function A(){}
  146. }',
  147. '<?php class A
  148. {
  149. public function A(){}}',
  150. ];
  151. yield 'add a newline at the end of a class: with comments' => [
  152. '<?php class A
  153. {
  154. public const A = 1; /* foo */ /* bar */
  155. }',
  156. '<?php class A
  157. {
  158. public const A = 1; /* foo */ /* bar */}',
  159. ];
  160. yield 'add a newline at the end of a class: with comments with trailing space' => [
  161. '<?php class A
  162. {
  163. public const A = 1; /* foo */ /* bar */
  164. }',
  165. '<?php class A
  166. {
  167. public const A = 1; /* foo */ /* bar */ }',
  168. ];
  169. $to = $from = '<?php ';
  170. for ($i = 0; $i < 15; ++$i) {
  171. $from .= \sprintf('class A%d{public function GA%d(){return new class {public function B6B%d(){}};}public function otherFunction%d(){}}', $i, $i, $i, $i);
  172. $to .= \sprintf("class A%d{\npublic function GA%d(){return new class {\npublic function B6B%d(){}\n};}\n\npublic function otherFunction%d(){}\n}", $i, $i, $i, $i);
  173. }
  174. yield [$to, $from];
  175. yield [
  176. '<?php $a = new class {
  177. public function H(){}
  178. public function B7(){}
  179. private function C(){}
  180. };',
  181. '<?php $a = new class {
  182. public function H(){}
  183. public function B7(){}
  184. private function C(){}
  185. };',
  186. ];
  187. yield [
  188. '<?php
  189. class A
  190. {
  191. public function getFilter()
  192. {
  193. return new class () implements FilterInterface {
  194. private $d = 123;
  195. public function pass($a, $b) {
  196. echo $a;
  197. }
  198. public $e = 5;
  199. };}
  200. }
  201. ',
  202. '<?php
  203. class A
  204. {public function getFilter()
  205. {
  206. return new class () implements FilterInterface {private $d = 123;
  207. public function pass($a, $b) {
  208. echo $a;
  209. }
  210. public $e = 5;};}
  211. }
  212. ',
  213. ];
  214. yield ['<?php
  215. class SomeClass1
  216. {
  217. // This comment
  218. // is multiline.
  219. public function echoA()
  220. {
  221. echo "a";
  222. }
  223. }
  224. '];
  225. yield [
  226. '<?php
  227. class SomeClass2
  228. {
  229. // This comment
  230. /* is multiline. */
  231. public function echoA()
  232. {
  233. echo "a";
  234. }
  235. }
  236. ',
  237. '<?php
  238. class SomeClass2
  239. {
  240. // This comment
  241. /* is multiline. */public function echoA()
  242. {
  243. echo "a";
  244. }
  245. }
  246. ',
  247. ];
  248. yield [
  249. '<?php
  250. class SomeClass3
  251. {
  252. // This comment
  253. // is multiline.
  254. public function echoA()
  255. {
  256. echo "a";
  257. }
  258. }
  259. ', ];
  260. yield [
  261. '<?php
  262. class SomeClass1
  263. {
  264. private $a; //
  265. public function methodA()
  266. {
  267. }
  268. private $b;
  269. //
  270. public function methodB()
  271. {
  272. }
  273. // C
  274. public function methodC()
  275. {
  276. }
  277. // D
  278. public function methodD()
  279. {
  280. }
  281. /* E */
  282. public function methodE()
  283. {
  284. }
  285. /* F */
  286. public function methodF()
  287. {
  288. }
  289. }
  290. ',
  291. '<?php
  292. class SomeClass1
  293. {
  294. private $a; //
  295. public function methodA()
  296. {
  297. }
  298. private $b;
  299. //
  300. public function methodB()
  301. {
  302. }
  303. // C
  304. public function methodC()
  305. {
  306. }
  307. // D
  308. public function methodD()
  309. {
  310. }
  311. /* E */
  312. public function methodE()
  313. {
  314. }
  315. /* F */
  316. public function methodF()
  317. {
  318. }
  319. }
  320. ', ];
  321. yield ['<?php
  322. class SomeClass
  323. {
  324. // comment
  325. public function echoA()
  326. {
  327. echo "a";
  328. }
  329. }
  330. '];
  331. yield ['<?php
  332. class SomeClass
  333. {
  334. // This comment
  335. // is multiline.
  336. public function echoA()
  337. {
  338. echo "a";
  339. }
  340. }
  341. '];
  342. yield [
  343. '<?php
  344. class SomeClass
  345. {
  346. // comment
  347. public function echoA()
  348. {
  349. echo "a";
  350. }
  351. }
  352. ',
  353. '<?php
  354. class SomeClass
  355. {
  356. // comment
  357. public function echoA()
  358. {
  359. echo "a";
  360. }
  361. }
  362. ',
  363. ];
  364. yield [
  365. '<?php
  366. class SomeClass
  367. {
  368. /* comment */
  369. public function echoB()
  370. {
  371. echo "a";
  372. }
  373. }
  374. ',
  375. '<?php
  376. class SomeClass
  377. {
  378. /* comment */public function echoB()
  379. {
  380. echo "a";
  381. }
  382. }
  383. ',
  384. ];
  385. yield [
  386. '<?php
  387. class SomeClass
  388. {
  389. /* comment */
  390. public function echoC()
  391. {
  392. echo "a";
  393. }
  394. }
  395. ',
  396. '<?php
  397. class SomeClass
  398. {
  399. /* comment */ public function echoC()
  400. {
  401. echo "a";
  402. }
  403. }
  404. ',
  405. ];
  406. yield [
  407. '<?php
  408. abstract class MethodTest2
  409. {
  410. public function method045()
  411. {
  412. $files = null;
  413. if (!empty($files)) {
  414. $this->filter(
  415. function (\SplFileInfo $file) use ($files) {
  416. return !in_array($file->getRelativePathname(), $files, true);
  417. }
  418. );
  419. }
  420. }
  421. private $a;
  422. public static function method145()
  423. {
  424. }
  425. abstract protected function method245();
  426. // comment
  427. final private function method345()
  428. {
  429. }
  430. }
  431. function some1(){ echo 1;}
  432. function some2(){ echo 2;}',
  433. '<?php
  434. abstract class MethodTest2
  435. {
  436. public function method045()
  437. {
  438. $files = null;
  439. if (!empty($files)) {
  440. $this->filter(
  441. function (\SplFileInfo $file) use ($files) {
  442. return !in_array($file->getRelativePathname(), $files, true);
  443. }
  444. );
  445. }
  446. }
  447. private $a;
  448. public static function method145()
  449. {
  450. }
  451. abstract protected function method245();
  452. // comment
  453. final private function method345()
  454. {
  455. }
  456. }
  457. function some1(){ echo 1;}
  458. function some2(){ echo 2;}',
  459. ];
  460. yield [
  461. '<?php
  462. /*
  463. * This file is part of the PHP CS utility.
  464. *
  465. * (c) Fabien Potencier <fabien@symfony.com>
  466. *
  467. * This source file is subject to the MIT license that is bundled
  468. * with this source code in the file LICENSE.
  469. */
  470. namespace PhpCsFixer\Linter;
  471. /**
  472. * Dummy linter. No linting is performed. No error is raised.
  473. *
  474. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  475. *
  476. * @internal
  477. */
  478. final class NullLinter implements LinterInterface
  479. {
  480. /**
  481. * {@inheritdoc}
  482. */
  483. public function lintFile($path)
  484. {
  485. unset($path);
  486. }
  487. /**
  488. * {@inheritdoc}
  489. */
  490. public function lintSource($source)
  491. {
  492. unset($source);
  493. }
  494. }
  495. ',
  496. ];
  497. // do not touch anonymous functions (since PHP doesn't allow
  498. // for class attributes being functions :(, we only have to test
  499. // those used within methods)
  500. yield [
  501. '<?php
  502. class MethodTestAnonymous
  503. {
  504. public function method444a()
  505. {
  506. $text = "hello";
  507. $example = function ($arg) use ($message) {
  508. var_dump($arg . " " . $message);
  509. };
  510. $example($text);
  511. $example = function($arg) use ($message) {
  512. var_dump($arg . " " . $message);
  513. };
  514. $example = function /*test*/ ($arg) use ($message) {
  515. var_dump($arg . " " . $message);
  516. };
  517. }
  518. }',
  519. ];
  520. yield [
  521. '<?php
  522. class MethodTest1
  523. {
  524. private $c; //
  525. public function method444a()
  526. {
  527. }
  528. /**
  529. *
  530. */
  531. public function method444b()
  532. {
  533. }
  534. //
  535. public function method444c()
  536. {
  537. }
  538. private $a;
  539. public function method444d()
  540. {
  541. }
  542. private $b;
  543. //
  544. public function method444e()
  545. {
  546. }
  547. public function method444f()
  548. {
  549. }
  550. private $d; //
  551. public function method444f1()
  552. {
  553. }
  554. /**/
  555. public function method444g()
  556. {
  557. }
  558. }',
  559. '<?php
  560. class MethodTest1
  561. {
  562. private $c; //
  563. public function method444a()
  564. {
  565. }
  566. /**
  567. *
  568. */
  569. public function method444b()
  570. {
  571. }
  572. //
  573. public function method444c()
  574. {
  575. }
  576. private $a;
  577. public function method444d()
  578. {
  579. }
  580. private $b;
  581. //
  582. public function method444e()
  583. {
  584. }
  585. public function method444f()
  586. {
  587. }
  588. private $d; //
  589. public function method444f1()
  590. {
  591. }
  592. /**/
  593. public function method444g()
  594. {
  595. }
  596. }',
  597. ];
  598. // spaces between methods
  599. yield [
  600. '<?php
  601. abstract class MethodTest3
  602. {
  603. public function method021()
  604. {
  605. }
  606. public static function method121()
  607. {
  608. }
  609. abstract protected function method221(); '.'
  610. final private function method321a()
  611. {
  612. }
  613. }',
  614. '<?php
  615. abstract class MethodTest3
  616. {
  617. public function method021()
  618. {
  619. }
  620. public static function method121()
  621. {
  622. }
  623. abstract protected function method221();
  624. '.'
  625. final private function method321a()
  626. {
  627. }
  628. }', ];
  629. // don't change correct code
  630. yield [
  631. '<?php
  632. class SmallHelperException extends \Exception
  633. {
  634. public function getId111()
  635. {
  636. return 1;
  637. }
  638. public function getMessage111()
  639. {
  640. return \'message\';
  641. }
  642. }
  643. class MethodTest123124124
  644. {
  645. public function method111a(){}
  646. public function method211a(){}
  647. }',
  648. ];
  649. // do not touch function out of class scope
  650. yield [
  651. '<?php
  652. function some0() {
  653. }
  654. class MethodTest4
  655. {
  656. public function method122b()
  657. {
  658. }
  659. public function method222b()
  660. {
  661. }
  662. }
  663. function some() {
  664. }
  665. function some2() {
  666. }
  667. ',
  668. ];
  669. yield [
  670. '<?php interface A {
  671. public function B1(); // allowed comment
  672. public function C(); // allowed comment
  673. }',
  674. '<?php interface A {public function B1(); // allowed comment
  675. public function C(); // allowed comment
  676. }',
  677. ];
  678. yield [
  679. '<?php class Foo {
  680. var $a;
  681. var $b;
  682. }',
  683. '<?php class Foo {
  684. var $a;
  685. var $b;
  686. }',
  687. ];
  688. yield [
  689. '<?php
  690. class A
  691. {
  692. /** 1 */
  693. function A2() {}
  694. /** 2 */
  695. function B2() {}
  696. }
  697. ',
  698. '<?php
  699. class A
  700. {
  701. /** 1 */
  702. function A2() {}
  703. /** 2 */
  704. function B2() {}
  705. }
  706. ',
  707. ];
  708. // do not touch well formatted traits
  709. yield [
  710. '<?php
  711. trait OkTrait
  712. {
  713. function getReturnTypeOk()
  714. {
  715. }
  716. /**
  717. *
  718. */
  719. function getReturnDescriptionOk()
  720. {
  721. }
  722. }',
  723. ];
  724. yield [
  725. '<?php
  726. trait ezcReflectionReturnInfo {
  727. public $x = 1;
  728. protected function getA(){echo 1;}
  729. function getB(){echo 2;}
  730. protected function getC(){echo 3;}
  731. /** Description */
  732. function getD(){echo 4;}
  733. protected function getE(){echo 3;}
  734. private $a;
  735. function getF(){echo 4;}
  736. }',
  737. '<?php
  738. trait ezcReflectionReturnInfo {
  739. public $x = 1;
  740. protected function getA(){echo 1;}function getB(){echo 2;}
  741. protected function getC(){echo 3;}/** Description */function getD(){echo 4;}
  742. protected function getE(){echo 3;}private $a;function getF(){echo 4;}
  743. }',
  744. ];
  745. yield [
  746. '<?php
  747. trait SomeReturnInfo {
  748. function getReturnType()
  749. {
  750. }
  751. function getReturnDescription()
  752. {
  753. }
  754. function getReturnDescription2()
  755. {
  756. }
  757. abstract public function getWorld();
  758. }',
  759. '<?php
  760. trait SomeReturnInfo {
  761. function getReturnType()
  762. {
  763. }
  764. function getReturnDescription()
  765. {
  766. } function getReturnDescription2()
  767. {
  768. }
  769. abstract public function getWorld();
  770. }',
  771. ];
  772. yield [
  773. '<?php
  774. interface TestInterface
  775. {
  776. public function someInterfaceMethod4();
  777. public function someInterfaceMethod5();
  778. /**
  779. * {@link}
  780. */ '.'
  781. public function someInterfaceMethod6();
  782. public function someInterfaceMethod7();
  783. public function someInterfaceMethod8();
  784. }',
  785. '<?php
  786. interface TestInterface
  787. { public function someInterfaceMethod4();
  788. public function someInterfaceMethod5();
  789. /**
  790. * {@link}
  791. */ '.'
  792. public function someInterfaceMethod6();
  793. public function someInterfaceMethod7(); public function someInterfaceMethod8();
  794. }',
  795. ];
  796. // do not touch well formatted interfaces
  797. yield [
  798. '<?php
  799. interface TestInterfaceOK
  800. {
  801. public function someMethod1();
  802. public function someMethod2();
  803. }',
  804. ];
  805. // method after trait use
  806. yield [
  807. '<?php
  808. trait ezcReflectionReturnInfo {
  809. function getReturnDescription() {}
  810. }
  811. class ezcReflectionMethod extends ReflectionMethod {
  812. use ezcReflectionReturnInfo;
  813. function afterUseTrait(){}
  814. function afterUseTrait2(){}
  815. }',
  816. '<?php
  817. trait ezcReflectionReturnInfo {
  818. function getReturnDescription() {}
  819. }
  820. class ezcReflectionMethod extends ReflectionMethod {
  821. use ezcReflectionReturnInfo;function afterUseTrait(){}function afterUseTrait2(){}
  822. }',
  823. ];
  824. yield 'multi line property' => [
  825. '<?php class Foo
  826. {
  827. private $prop = [
  828. 1 => true,
  829. 2 => false,
  830. ];
  831. // comment2
  832. private $bar = 1;
  833. }',
  834. '<?php class Foo
  835. {
  836. private $prop = [
  837. 1 => true,
  838. 2 => false,
  839. ]; // comment2
  840. private $bar = 1;
  841. }',
  842. ['elements' => ['property' => 'one']],
  843. ];
  844. yield 'trait group import none' => [
  845. '<?php class Foo
  846. {
  847. use Ao;
  848. use B0 { X0 as Y0;} // test
  849. use A;
  850. use B { X as Y;} // test
  851. use Char;
  852. use Bar {
  853. __construct as barConstruct;
  854. baz as barBaz;
  855. }
  856. use Dua;
  857. }',
  858. '<?php class Foo
  859. {
  860. use Ao;
  861. use B0 { X0 as Y0;} // test
  862. use A;
  863. use B { X as Y;} // test
  864. use Char;
  865. use Bar {
  866. __construct as barConstruct;
  867. baz as barBaz;
  868. }
  869. use Dua;
  870. }',
  871. ['elements' => ['trait_import' => 'none']],
  872. ];
  873. yield [
  874. '<?php
  875. class Foo
  876. {
  877. /** A */
  878. private $email;
  879. private $foo0; #0 /* test */
  880. private $foo1; #1
  881. private $foo2; /* @2 */
  882. }',
  883. '<?php
  884. class Foo
  885. {
  886. /** A */
  887. private $email;
  888. private $foo0; #0 /* test */
  889. private $foo1; #1
  890. private $foo2; /* @2 */
  891. }',
  892. ['elements' => ['property' => 'none']],
  893. ];
  894. yield [
  895. '<?php
  896. class Sample
  897. {
  898. /** @var int */
  899. const FOO = 1;
  900. /** @var int */
  901. const BAR = 2;
  902. const BAZ = 3;
  903. const OTHER = 4;
  904. const OTHER2 = 5;
  905. }',
  906. '<?php
  907. class Sample
  908. {
  909. /** @var int */
  910. const FOO = 1;
  911. /** @var int */
  912. const BAR = 2;
  913. const BAZ = 3;
  914. const OTHER = 4;
  915. const OTHER2 = 5;
  916. }',
  917. ['elements' => ['const' => 'none']],
  918. ];
  919. yield 'multiple trait import 5954' => [
  920. '<?php
  921. class Foo
  922. {
  923. use Bar, Baz;
  924. }',
  925. null,
  926. ['elements' => ['method' => 'one']],
  927. ];
  928. yield 'multiple trait import with method 5954' => [
  929. '<?php
  930. class Foo
  931. {
  932. use Bar, Baz;
  933. public function f() {}
  934. }',
  935. '<?php
  936. class Foo
  937. {
  938. use Bar, Baz;
  939. public function f() {}
  940. }',
  941. ['elements' => ['method' => 'one']],
  942. ];
  943. yield 'trait group import 5843' => [
  944. '<?php
  945. class Foo
  946. {
  947. use Ao;
  948. use B0 { X0 as Y0;} // test
  949. use A;
  950. use B { X as Y;} // test
  951. use Char;
  952. use Bar {
  953. __construct as barConstruct;
  954. baz as barBaz;
  955. }
  956. use Dua;
  957. public function aaa()
  958. {
  959. }
  960. }',
  961. '<?php
  962. class Foo
  963. {
  964. use Ao;
  965. use B0 { X0 as Y0;} // test
  966. use A;
  967. use B { X as Y;} // test
  968. use Char;
  969. use Bar {
  970. __construct as barConstruct;
  971. baz as barBaz;
  972. }
  973. use Dua;
  974. public function aaa()
  975. {
  976. }
  977. }',
  978. ['elements' => ['method' => 'one', 'trait_import' => 'one']],
  979. ];
  980. yield [
  981. '<?php
  982. class Foo
  983. {
  984. use SomeTrait1;
  985. use SomeTrait2;
  986. public function Bar(){}
  987. }
  988. ',
  989. '<?php
  990. class Foo
  991. {
  992. use SomeTrait1;
  993. use SomeTrait2;
  994. public function Bar(){}
  995. }
  996. ',
  997. ['elements' => ['method' => 'one', 'trait_import' => 'one']],
  998. ];
  999. yield 'trait group import 5852' => [
  1000. '<?php
  1001. class Foo
  1002. {
  1003. use A;
  1004. use B;
  1005. /**
  1006. *
  1007. */
  1008. public function A(){}
  1009. }',
  1010. '<?php
  1011. class Foo
  1012. {
  1013. use A;
  1014. use B;
  1015. /**
  1016. *
  1017. */
  1018. public function A(){}
  1019. }',
  1020. ['elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one', 'trait_import' => 'none']],
  1021. ];
  1022. yield [
  1023. '<?php
  1024. abstract class Example
  1025. {
  1026. use SomeTrait;
  1027. use AnotherTrait;
  1028. public $property;
  1029. abstract public function method(): void;
  1030. }',
  1031. '<?php
  1032. abstract class Example
  1033. {
  1034. use SomeTrait;
  1035. use AnotherTrait;
  1036. public $property;
  1037. abstract public function method(): void;
  1038. }',
  1039. ['elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one']],
  1040. ];
  1041. yield [
  1042. '<?php
  1043. class A
  1044. {
  1045. private $a = null;
  1046. public $b = 1;
  1047. function A() {}
  1048. }
  1049. ',
  1050. '<?php
  1051. class A
  1052. {
  1053. private $a = null;
  1054. public $b = 1;
  1055. function A() {}
  1056. }
  1057. ',
  1058. ['elements' => ['property' => 'one']],
  1059. ];
  1060. yield [
  1061. '<?php
  1062. class A
  1063. {
  1064. private $a = null;
  1065. public $b = 1;
  1066. function A() {}
  1067. }
  1068. ',
  1069. '<?php
  1070. class A
  1071. {
  1072. private $a = null;
  1073. public $b = 1;
  1074. function A() {}
  1075. }
  1076. ',
  1077. ['elements' => ['property' => 'none']],
  1078. ];
  1079. yield [
  1080. '<?php
  1081. class A
  1082. {
  1083. const A = 1;
  1084. const THREE = ONE + self::TWO; /* test */ # test
  1085. const B = 2;
  1086. }
  1087. ',
  1088. '<?php
  1089. class A
  1090. {
  1091. const A = 1;
  1092. const THREE = ONE + self::TWO; /* test */ # test
  1093. const B = 2;
  1094. }
  1095. ',
  1096. ['elements' => ['const' => 'one']],
  1097. ];
  1098. yield [
  1099. '<?php
  1100. class A
  1101. {
  1102. const A = 1;
  1103. const THREE = ONE + self::TWO;
  1104. const B = 2;
  1105. }
  1106. ',
  1107. '<?php
  1108. class A
  1109. {
  1110. const A = 1;
  1111. const THREE = ONE + self::TWO;
  1112. const B = 2;
  1113. }
  1114. ',
  1115. ['elements' => ['const' => 'none']],
  1116. ];
  1117. yield [
  1118. '<?php
  1119. class A
  1120. {
  1121. function D() {}
  1122. function B4() {}
  1123. }
  1124. ',
  1125. '<?php
  1126. class A
  1127. {
  1128. function D() {}
  1129. function B4() {}
  1130. }
  1131. ',
  1132. ['elements' => ['method' => 'one']],
  1133. ];
  1134. yield [
  1135. '<?php
  1136. class A
  1137. {
  1138. function A() {}
  1139. function B() {}
  1140. }
  1141. ',
  1142. '<?php
  1143. class A
  1144. {
  1145. function A() {}
  1146. function B() {}
  1147. }
  1148. ',
  1149. ['elements' => ['method' => 'none']],
  1150. ];
  1151. yield [
  1152. '<?php
  1153. class A
  1154. {
  1155. private $x;
  1156. private $y;
  1157. final function f1() {}
  1158. final function f2() {}
  1159. }
  1160. ',
  1161. '<?php
  1162. class A
  1163. {
  1164. private $x;
  1165. private $y;
  1166. final function f1() {}
  1167. final function f2() {}
  1168. }
  1169. ',
  1170. ['elements' => ['property' => 'none', 'method' => 'one']],
  1171. ];
  1172. yield [
  1173. '<?php
  1174. class A
  1175. {
  1176. const FOO = 1;
  1177. const BAR = 2;
  1178. function f1() {}
  1179. function f2() {}
  1180. }
  1181. ',
  1182. '<?php
  1183. class A
  1184. {
  1185. const FOO = 1;
  1186. const BAR = 2;
  1187. function f1() {}
  1188. function f2() {}
  1189. }
  1190. ',
  1191. ['elements' => ['const' => 'none', 'method' => 'one']],
  1192. ];
  1193. yield [
  1194. '<?php
  1195. class A
  1196. {
  1197. const FOO = 1;
  1198. const BAR = 2;
  1199. public function f1() {}
  1200. public function f2() {}
  1201. }
  1202. ',
  1203. '<?php
  1204. class A
  1205. {
  1206. const FOO = 1;
  1207. const BAR = 2;
  1208. public function f1() {}
  1209. public function f2() {}
  1210. }
  1211. ',
  1212. ['elements' => ['const' => 'none', 'method' => 'one']],
  1213. ];
  1214. yield [
  1215. '<?php
  1216. class A
  1217. {
  1218. const B = 2;
  1219. const FOO = 1;
  1220. const BAR = 2;
  1221. /** @var int */
  1222. const BAZ = 3;
  1223. /** @var int */
  1224. const NEW = 4;
  1225. /** @var int */
  1226. const A = 5;
  1227. }
  1228. ',
  1229. '<?php
  1230. class A
  1231. {
  1232. const B = 2;
  1233. const FOO = 1;
  1234. const BAR = 2;
  1235. /** @var int */
  1236. const BAZ = 3;
  1237. /** @var int */
  1238. const NEW = 4;
  1239. /** @var int */
  1240. const A = 5;
  1241. }
  1242. ',
  1243. ['elements' => ['const' => 'only_if_meta']],
  1244. ];
  1245. yield [
  1246. '<?php
  1247. class B
  1248. {
  1249. public $foo;
  1250. /** @var string */
  1251. public $bar;
  1252. public $baz;
  1253. }
  1254. ',
  1255. '<?php
  1256. class B
  1257. {
  1258. public $foo;
  1259. /** @var string */
  1260. public $bar;
  1261. public $baz;
  1262. }
  1263. ',
  1264. ['elements' => ['property' => 'only_if_meta']],
  1265. ];
  1266. yield [
  1267. '<?php
  1268. class C
  1269. {
  1270. public function f1() {}
  1271. public function f2() {}
  1272. public function f3() {}
  1273. /** @return string */
  1274. public function f4() {}
  1275. }
  1276. ',
  1277. '<?php
  1278. class C
  1279. {
  1280. public function f1() {}
  1281. public function f2() {}
  1282. public function f3() {}
  1283. /** @return string */
  1284. public function f4() {}
  1285. }
  1286. ',
  1287. ['elements' => ['method' => 'only_if_meta']],
  1288. ];
  1289. yield [
  1290. '<?php
  1291. class Sample
  1292. {
  1293. /** @var int */
  1294. const ART = 1;
  1295. const SCIENCE = 2;
  1296. /** @var string */
  1297. public $a;
  1298. /** @var int */
  1299. public $b;
  1300. public $c;
  1301. /**
  1302. * @param string $a
  1303. * @param int $b
  1304. * @param int $c
  1305. */
  1306. public function __construct($a, $b, $c) {}
  1307. public function __destruct() {}
  1308. }
  1309. ',
  1310. '<?php
  1311. class Sample
  1312. {
  1313. /** @var int */
  1314. const ART = 1;
  1315. const SCIENCE = 2;
  1316. /** @var string */
  1317. public $a;
  1318. /** @var int */
  1319. public $b;
  1320. public $c;
  1321. /**
  1322. * @param string $a
  1323. * @param int $b
  1324. * @param int $c
  1325. */
  1326. public function __construct($a, $b, $c) {}
  1327. public function __destruct() {}
  1328. }
  1329. ',
  1330. ['elements' => ['const' => 'only_if_meta', 'property' => 'only_if_meta', 'method' => 'only_if_meta']],
  1331. ];
  1332. yield [
  1333. '<?php
  1334. class A
  1335. {
  1336. use A;
  1337. use B;
  1338. private $a = null;
  1339. public $b = 1;
  1340. }
  1341. ',
  1342. '<?php
  1343. class A
  1344. {
  1345. use A;
  1346. use B;
  1347. private $a = null;
  1348. public $b = 1;
  1349. }
  1350. ',
  1351. ['elements' => ['property' => 'none', 'trait_import' => 'none']],
  1352. ];
  1353. yield [
  1354. '<?php
  1355. class Foo {
  1356. public function H1(){}
  1357. /** */
  1358. public const BAR = 123;
  1359. /** */
  1360. private const BAZ = "a";
  1361. }',
  1362. '<?php
  1363. class Foo {
  1364. public function H1(){}
  1365. /** */
  1366. public const BAR = 123;
  1367. /** */
  1368. private const BAZ = "a";
  1369. }',
  1370. ];
  1371. yield [
  1372. '<?php
  1373. class Foo {
  1374. private ?int $foo;
  1375. protected string $bar;
  1376. public iterable $baz;
  1377. var ? Foo\Bar $qux;
  1378. }',
  1379. '<?php
  1380. class Foo {
  1381. private ?int $foo;
  1382. protected string $bar;
  1383. public iterable $baz;
  1384. var ? Foo\Bar $qux;
  1385. }',
  1386. ];
  1387. yield [
  1388. '<?php
  1389. class Foo {
  1390. private array $foo;
  1391. private array $bar;
  1392. }',
  1393. '<?php
  1394. class Foo {
  1395. private array $foo;
  1396. private array $bar;
  1397. }',
  1398. ];
  1399. yield [
  1400. '<?php
  1401. class Entity
  1402. {
  1403. /**
  1404. * @ORM\Column(name="one", type="text")
  1405. */
  1406. private string $one;
  1407. /**
  1408. * @ORM\Column(name="two", type="text")
  1409. */
  1410. private string $two;
  1411. private string $three;
  1412. private string $four;
  1413. private string $five;
  1414. }',
  1415. '<?php
  1416. class Entity
  1417. {
  1418. /**
  1419. * @ORM\Column(name="one", type="text")
  1420. */
  1421. private string $one;
  1422. /**
  1423. * @ORM\Column(name="two", type="text")
  1424. */
  1425. private string $two;
  1426. private string $three;
  1427. private string $four;
  1428. private string $five;
  1429. }',
  1430. ['elements' => ['property' => 'only_if_meta']],
  1431. ];
  1432. yield [
  1433. '<?php
  1434. class Foo
  1435. {
  1436. use SomeTrait1;
  1437. use SomeTrait2;
  1438. public function Bar(){}
  1439. }
  1440. ',
  1441. '<?php
  1442. class Foo
  1443. {
  1444. use SomeTrait1;
  1445. use SomeTrait2;
  1446. public function Bar(){}
  1447. }
  1448. ',
  1449. ];
  1450. }
  1451. /**
  1452. * @param _AutogeneratedInputConfiguration $config
  1453. *
  1454. * @dataProvider provideFix80Cases
  1455. *
  1456. * @requires PHP 8.0
  1457. */
  1458. public function testFix80(string $expected, ?string $input, array $config = []): void
  1459. {
  1460. $this->fixer->configure($config);
  1461. $this->doTest($expected, $input);
  1462. }
  1463. public static function provideFix80Cases(): iterable
  1464. {
  1465. yield 'attributes' => [
  1466. '<?php
  1467. class User1
  1468. {
  1469. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1470. private $id;
  1471. #[ORM\Column("string", ORM\Column::UNIQUE)]
  1472. #[Assert\String()]
  1473. #[Assert\Email(["message" => "The email {{ value }} is not a valid email."])]
  1474. private $email;
  1475. #[Assert\String()]
  1476. private $name;
  1477. }',
  1478. '<?php
  1479. class User1
  1480. {
  1481. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1482. private $id;
  1483. #[ORM\Column("string", ORM\Column::UNIQUE)]
  1484. #[Assert\String()]
  1485. #[Assert\Email(["message" => "The email {{ value }} is not a valid email."])]
  1486. private $email;
  1487. #[Assert\String()]
  1488. private $name;
  1489. }',
  1490. ];
  1491. yield 'attributes minimal' => [
  1492. '<?php
  1493. class User2{
  1494. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1495. private $id;
  1496. }',
  1497. '<?php
  1498. class User2{#[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue] private $id;}',
  1499. ];
  1500. yield 'attribute block' => [
  1501. '<?php
  1502. class User3
  1503. {
  1504. private $id;
  1505. #[ORM\Column("string")]
  1506. #[Assert\Email(["message" => "Foo"])]
  1507. private $email;
  1508. }',
  1509. '<?php
  1510. class User3
  1511. {
  1512. private $id;
  1513. #[ORM\Column("string")]
  1514. #[Assert\Email(["message" => "Foo"])] private $email;
  1515. }',
  1516. ];
  1517. yield 'constructor property promotion' => [
  1518. '<?php
  1519. class Foo {
  1520. private array $foo;
  1521. private array $bar;
  1522. public function __construct(
  1523. public float $x = 0.0,
  1524. protected float $y = 0.0,
  1525. private float $z = 0.0,
  1526. ) {}
  1527. }',
  1528. '<?php
  1529. class Foo {
  1530. private array $foo;
  1531. private array $bar;
  1532. public function __construct(
  1533. public float $x = 0.0,
  1534. protected float $y = 0.0,
  1535. private float $z = 0.0,
  1536. ) {}
  1537. }',
  1538. ];
  1539. yield 'typed properties' => [
  1540. '<?php
  1541. class Foo {
  1542. private static int | float | null $a;
  1543. private static int | float | null $b;
  1544. private int | float | null $c;
  1545. private int | float | null $d;
  1546. }',
  1547. '<?php
  1548. class Foo {
  1549. private static int | float | null $a;
  1550. private static int | float | null $b;
  1551. private int | float | null $c;
  1552. private int | float | null $d;
  1553. }',
  1554. ];
  1555. yield 'attributes with conditional spacing' => [
  1556. '<?php
  1557. class User
  1558. {
  1559. private $id;
  1560. #[Assert\String()]
  1561. private $name;
  1562. private $email;
  1563. }
  1564. ',
  1565. '<?php
  1566. class User
  1567. {
  1568. private $id;
  1569. #[Assert\String()]
  1570. private $name;
  1571. private $email;
  1572. }
  1573. ',
  1574. ['elements' => ['property' => 'only_if_meta']],
  1575. ];
  1576. yield 'mixed attributes and phpdoc with conditional spacing' => [
  1577. '<?php
  1578. class User
  1579. {
  1580. private $id;
  1581. /** @var string */
  1582. #[Assert\Email(["message" => "Foo"])]
  1583. private $email;
  1584. #[Assert\String()]
  1585. #[ORM\Column()]
  1586. private $place;
  1587. #[ORM\Column()]
  1588. /** @var string */
  1589. private $hash;
  1590. /** @var string **/
  1591. #[ORM\Column()]
  1592. /** @internal */
  1593. private $updatedAt;
  1594. }
  1595. ',
  1596. '<?php
  1597. class User
  1598. {
  1599. private $id;
  1600. /** @var string */
  1601. #[Assert\Email(["message" => "Foo"])]
  1602. private $email;
  1603. #[Assert\String()]
  1604. #[ORM\Column()]
  1605. private $place;
  1606. #[ORM\Column()]
  1607. /** @var string */
  1608. private $hash;
  1609. /** @var string **/
  1610. #[ORM\Column()]
  1611. /** @internal */
  1612. private $updatedAt;
  1613. }
  1614. ',
  1615. ['elements' => ['property' => 'only_if_meta']],
  1616. ];
  1617. yield [
  1618. '<?php
  1619. class Foo
  1620. {
  1621. #[Assert\Email(["message" => "Foo"])]
  1622. private $email;
  1623. private $foo1; #1
  1624. private $foo2; /* @2 */
  1625. }',
  1626. '<?php
  1627. class Foo
  1628. {
  1629. #[Assert\Email(["message" => "Foo"])]
  1630. private $email;
  1631. private $foo1; #1
  1632. private $foo2; /* @2 */
  1633. }',
  1634. ['elements' => ['property' => 'none']],
  1635. ];
  1636. }
  1637. /**
  1638. * @param _AutogeneratedInputConfiguration $config
  1639. *
  1640. * @dataProvider provideFix81Cases
  1641. *
  1642. * @requires PHP 8.1
  1643. */
  1644. public function testFix81(string $expected, ?string $input, array $config = []): void
  1645. {
  1646. $this->fixer->configure($config);
  1647. $this->doTest($expected, $input);
  1648. }
  1649. public static function provideFix81Cases(): iterable
  1650. {
  1651. yield [
  1652. '<?php class A {
  1653. public int $a0;
  1654. public readonly int $a1;
  1655. readonly public int $a2;
  1656. readonly int $a3;
  1657. public int $a4;
  1658. }',
  1659. '<?php class A {
  1660. public int $a0;
  1661. public readonly int $a1;
  1662. readonly public int $a2;
  1663. readonly int $a3;
  1664. public int $a4;
  1665. }',
  1666. ];
  1667. yield [
  1668. '<?php
  1669. class Foo
  1670. {
  1671. final public const B1 = "1";
  1672. public final const B2 = "2";
  1673. final const B3 = "3";
  1674. }
  1675. ',
  1676. '<?php
  1677. class Foo
  1678. {
  1679. final public const B1 = "1";
  1680. public final const B2 = "2";
  1681. final const B3 = "3";
  1682. }
  1683. ',
  1684. ];
  1685. yield 'intersection properties' => [
  1686. '<?php
  1687. class Foo {
  1688. private static Bar & Something & Baz $a;
  1689. private static Bar & Something & Baz $b;
  1690. private Bar & Something & Baz $c;
  1691. private Bar & Something & Baz $d;
  1692. }',
  1693. '<?php
  1694. class Foo {
  1695. private static Bar & Something & Baz $a;
  1696. private static Bar & Something & Baz $b;
  1697. private Bar & Something & Baz $c;
  1698. private Bar & Something & Baz $d;
  1699. }',
  1700. ];
  1701. $input = '<?php
  1702. enum Cards: string
  1703. {
  1704. protected const Deck = "d.d";
  1705. protected const Pack = "p.p";
  1706. case Hearts = "H";
  1707. case Spades = "S";
  1708. case Diamonds = "D";
  1709. case Clubs = "C";
  1710. protected function test() {
  1711. echo 1;
  1712. }
  1713. protected function test2() {
  1714. echo 2;
  1715. }
  1716. }
  1717. ';
  1718. yield [
  1719. '<?php
  1720. enum Cards: string
  1721. {
  1722. protected const Deck = "d.d";
  1723. protected const Pack = "p.p";
  1724. case Hearts = "H";
  1725. case Spades = "S";
  1726. case Diamonds = "D";
  1727. case Clubs = "C";
  1728. protected function test() {
  1729. echo 1;
  1730. }
  1731. protected function test2() {
  1732. echo 2;
  1733. }
  1734. }
  1735. ',
  1736. $input,
  1737. ['elements' => [
  1738. 'const' => 'one',
  1739. 'method' => 'one',
  1740. 'case' => 'one',
  1741. ]],
  1742. ];
  1743. yield [
  1744. '<?php
  1745. enum Cards: string
  1746. {
  1747. protected const Deck = "d.d";
  1748. protected const Pack = "p.p";
  1749. case Hearts = "H";
  1750. case Spades = "S";
  1751. case Diamonds = "D";
  1752. case Clubs = "C";
  1753. protected function test() {
  1754. echo 1;
  1755. }
  1756. protected function test2() {
  1757. echo 2;
  1758. }
  1759. }
  1760. ',
  1761. $input,
  1762. ['elements' => [
  1763. 'const' => 'none',
  1764. 'method' => 'one',
  1765. 'case' => 'none',
  1766. ]],
  1767. ];
  1768. }
  1769. /**
  1770. * @dataProvider provideFix82Cases
  1771. *
  1772. * @requires PHP 8.2
  1773. */
  1774. public function testFix82(string $expected, ?string $input = null): void
  1775. {
  1776. $this->doTest($expected, $input);
  1777. }
  1778. /**
  1779. * @return iterable<array{0: string, 1?: string}>
  1780. */
  1781. public static function provideFix82Cases(): iterable
  1782. {
  1783. yield [
  1784. '<?php
  1785. trait Foo {
  1786. const Bar = 1;
  1787. const Baz = 2;
  1788. }',
  1789. '<?php
  1790. trait Foo {
  1791. const Bar = 1;
  1792. const Baz = 2;
  1793. }',
  1794. ];
  1795. yield [
  1796. '<?php
  1797. class X
  1798. {
  1799. private A|(B&C) $propertyName;
  1800. }',
  1801. ];
  1802. }
  1803. /**
  1804. * @dataProvider provideWithWhitespacesConfigCases
  1805. */
  1806. public function testWithWhitespacesConfig(string $expected, ?string $input = null): void
  1807. {
  1808. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  1809. $this->doTest($expected, $input);
  1810. }
  1811. /**
  1812. * @return iterable<array{string, string}>
  1813. */
  1814. public static function provideWithWhitespacesConfigCases(): iterable
  1815. {
  1816. yield [
  1817. "<?php\r\nclass SomeClass\r\n{\r\n // comment\n\n public function echoA()\r\n {\r\n echo 'a';\r\n }\r\n}\r\n",
  1818. "<?php\r\nclass SomeClass\r\n{\r\n // comment\n\n\n public function echoA()\r\n {\r\n echo 'a';\r\n }\r\n}\r\n",
  1819. ];
  1820. yield [
  1821. "<?php\r\nclass SomeClass\r\n{\r\n // comment\r\n\r\n public function echoA()\r\n {\r\n echo 'a';\r\n }\r\n}\r\n",
  1822. "<?php\r\nclass SomeClass\r\n{\r\n // comment\r\n\r\n\r\n public function echoA()\r\n {\r\n echo 'a';\r\n }\r\n}\r\n",
  1823. ];
  1824. }
  1825. /**
  1826. * @param array<array-key, mixed> $elements
  1827. *
  1828. * @dataProvider provideInvalidConfigurationCases
  1829. */
  1830. public function testInvalidConfiguration(array $elements): void
  1831. {
  1832. $this->expectException(InvalidFixerConfigurationException::class);
  1833. $this->fixer->configure(['elements' => $elements]);
  1834. }
  1835. public static function provideInvalidConfigurationCases(): iterable
  1836. {
  1837. yield 'numeric keys' => [['method', 'property']];
  1838. yield 'wrong key name' => [['methods' => 'one']];
  1839. yield 'wrong key value' => [['method' => 'two']];
  1840. }
  1841. /**
  1842. * @dataProvider provideCommentBlockStartDetectionCases
  1843. */
  1844. public function testCommentBlockStartDetection(int $expected, string $code, int $index): void
  1845. {
  1846. Tokens::clearCache();
  1847. $tokens = Tokens::fromCode($code);
  1848. $method = new \ReflectionMethod($this->fixer, 'findCommentBlockStart');
  1849. $method->setAccessible(true);
  1850. $result = $method->invoke($this->fixer, $tokens, $index, 0);
  1851. self::assertSame(
  1852. $expected,
  1853. $result,
  1854. \sprintf('Expected index %d (%s) got index %d (%s).', $expected, $tokens[$expected]->toJson(), $result, $tokens[$result]->toJson())
  1855. );
  1856. }
  1857. /**
  1858. * @return iterable<array{int, string, int}>
  1859. */
  1860. public static function provideCommentBlockStartDetectionCases(): iterable
  1861. {
  1862. yield [
  1863. 4,
  1864. '<?php
  1865. //ui
  1866. //j1
  1867. //k2
  1868. ',
  1869. 6,
  1870. ];
  1871. yield [
  1872. 4,
  1873. '<?php
  1874. //ui
  1875. //j1
  1876. //k2
  1877. ',
  1878. 5,
  1879. ];
  1880. yield [
  1881. 4,
  1882. '<?php
  1883. /**/
  1884. //j1
  1885. //k2
  1886. ',
  1887. 6,
  1888. ];
  1889. yield [
  1890. 4,
  1891. '<?php
  1892. $a;//j
  1893. //k
  1894. ',
  1895. 6,
  1896. ];
  1897. yield [
  1898. 2,
  1899. '<?php
  1900. //a
  1901. ',
  1902. 2,
  1903. ];
  1904. yield [
  1905. 2,
  1906. '<?php
  1907. //b
  1908. //c
  1909. ',
  1910. 2,
  1911. ];
  1912. yield [
  1913. 2,
  1914. '<?php
  1915. //d
  1916. //e
  1917. ',
  1918. 4,
  1919. ];
  1920. yield [
  1921. 2,
  1922. '<?php
  1923. /**/
  1924. //f
  1925. //g
  1926. //h
  1927. ',
  1928. 8,
  1929. ];
  1930. }
  1931. }