ClassAttributesSeparationFixerTest.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace PhpCsFixer\Tests\Fixer\ClassNotation;
  12. use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\Tokenizer\Tokens;
  15. use PhpCsFixer\WhitespacesFixerConfig;
  16. /**
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer
  20. */
  21. final class ClassAttributesSeparationFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @param int $expected
  25. * @param string $code
  26. * @param int $index
  27. *
  28. * @dataProvider provideCommentBlockStartDetectionCases
  29. */
  30. public function testCommentBlockStartDetection($expected, $code, $index)
  31. {
  32. Tokens::clearCache();
  33. $tokens = Tokens::fromCode($code);
  34. $method = new \ReflectionMethod($this->fixer, 'findCommentBlockStart');
  35. $method->setAccessible(true);
  36. $result = $method->invoke($this->fixer, $tokens, $index);
  37. static::assertSame(
  38. $expected,
  39. $result,
  40. sprintf('Expected index %d (%s) got index %d (%s).', $expected, $tokens[$expected]->toJson(), $result, $tokens[$result]->toJson())
  41. );
  42. }
  43. public function provideCommentBlockStartDetectionCases()
  44. {
  45. return [
  46. [
  47. 4,
  48. '<?php
  49. //ui
  50. //j1
  51. //k2
  52. ',
  53. 6,
  54. ],
  55. [
  56. 4,
  57. '<?php
  58. //ui
  59. //j1
  60. //k2
  61. ',
  62. 5,
  63. ],
  64. [
  65. 4,
  66. '<?php
  67. /**/
  68. //j1
  69. //k2
  70. ',
  71. 6,
  72. ],
  73. [
  74. 4,
  75. '<?php
  76. $a;//j
  77. //k
  78. ',
  79. 6,
  80. ],
  81. [
  82. 2,
  83. '<?php
  84. //a
  85. ',
  86. 2,
  87. ],
  88. [
  89. 2,
  90. '<?php
  91. //b
  92. //c
  93. ',
  94. 2,
  95. ],
  96. [
  97. 2,
  98. '<?php
  99. //d
  100. //e
  101. ',
  102. 4,
  103. ],
  104. [
  105. 2,
  106. '<?php
  107. /**/
  108. //f
  109. //g
  110. //h
  111. ',
  112. 8,
  113. ],
  114. ];
  115. }
  116. /**
  117. * @param string $expected
  118. * @param null|string $input
  119. *
  120. * @dataProvider provideFixClassesCases
  121. */
  122. public function testFixClasses($expected, $input = null)
  123. {
  124. $this->doTest($expected, $input);
  125. }
  126. public function provideFixClassesCases()
  127. {
  128. $cases = [];
  129. $cases[] = ['<?php
  130. class SomeClass1
  131. {
  132. // This comment
  133. // is multiline.
  134. public function echoA()
  135. {
  136. echo "a";
  137. }
  138. }
  139. '];
  140. $cases[] = [
  141. '<?php
  142. class SomeClass2
  143. {
  144. // This comment
  145. /* is multiline. */
  146. public function echoA()
  147. {
  148. echo "a";
  149. }
  150. }
  151. ',
  152. '<?php
  153. class SomeClass2
  154. {
  155. // This comment
  156. /* is multiline. */public function echoA()
  157. {
  158. echo "a";
  159. }
  160. }
  161. ',
  162. ];
  163. $cases[] = [
  164. '<?php
  165. class SomeClass3
  166. {
  167. // This comment
  168. // is multiline.
  169. public function echoA()
  170. {
  171. echo "a";
  172. }
  173. }
  174. ', ];
  175. $cases[] = [
  176. '<?php
  177. class SomeClass1
  178. {
  179. private $a; //
  180. public function methodA()
  181. {
  182. }
  183. private $b;
  184. //
  185. public function methodB()
  186. {
  187. }
  188. // C
  189. public function methodC()
  190. {
  191. }
  192. // D
  193. public function methodD()
  194. {
  195. }
  196. /* E */
  197. public function methodE()
  198. {
  199. }
  200. /* F */
  201. public function methodF()
  202. {
  203. }
  204. }
  205. ',
  206. '<?php
  207. class SomeClass1
  208. {
  209. private $a; //
  210. public function methodA()
  211. {
  212. }
  213. private $b;
  214. //
  215. public function methodB()
  216. {
  217. }
  218. // C
  219. public function methodC()
  220. {
  221. }
  222. // D
  223. public function methodD()
  224. {
  225. }
  226. /* E */
  227. public function methodE()
  228. {
  229. }
  230. /* F */
  231. public function methodF()
  232. {
  233. }
  234. }
  235. ', ];
  236. $cases[] = ['<?php
  237. class SomeClass
  238. {
  239. // comment
  240. public function echoA()
  241. {
  242. echo "a";
  243. }
  244. }
  245. '];
  246. $cases[] = ['<?php
  247. class SomeClass
  248. {
  249. // This comment
  250. // is multiline.
  251. public function echoA()
  252. {
  253. echo "a";
  254. }
  255. }
  256. '];
  257. $cases[] = [
  258. '<?php
  259. class SomeClass
  260. {
  261. // comment
  262. public function echoA()
  263. {
  264. echo "a";
  265. }
  266. }
  267. ',
  268. '<?php
  269. class SomeClass
  270. {
  271. // comment
  272. public function echoA()
  273. {
  274. echo "a";
  275. }
  276. }
  277. ',
  278. ];
  279. $cases[] = [
  280. '<?php
  281. class SomeClass
  282. {
  283. /* comment */
  284. public function echoB()
  285. {
  286. echo "a";
  287. }
  288. }
  289. ',
  290. '<?php
  291. class SomeClass
  292. {
  293. /* comment */public function echoB()
  294. {
  295. echo "a";
  296. }
  297. }
  298. ',
  299. ];
  300. $cases[] = [
  301. '<?php
  302. class SomeClass
  303. {
  304. /* comment */
  305. public function echoC()
  306. {
  307. echo "a";
  308. }
  309. }
  310. ',
  311. '<?php
  312. class SomeClass
  313. {
  314. /* comment */ public function echoC()
  315. {
  316. echo "a";
  317. }
  318. }
  319. ',
  320. ];
  321. $cases[] = [
  322. '<?php
  323. abstract class MethodTest2
  324. {
  325. public function method045()
  326. {
  327. $files = null;
  328. if (!empty($files)) {
  329. $this->filter(
  330. function (\SplFileInfo $file) use ($files) {
  331. return !in_array($file->getRelativePathname(), $files, true);
  332. }
  333. );
  334. }
  335. }
  336. private $a;
  337. public static function method145()
  338. {
  339. }
  340. abstract protected function method245();
  341. // comment
  342. final private function method345()
  343. {
  344. }
  345. }
  346. function some1(){ echo 1;}
  347. function some2(){ echo 2;}',
  348. '<?php
  349. abstract class MethodTest2
  350. {
  351. public function method045()
  352. {
  353. $files = null;
  354. if (!empty($files)) {
  355. $this->filter(
  356. function (\SplFileInfo $file) use ($files) {
  357. return !in_array($file->getRelativePathname(), $files, true);
  358. }
  359. );
  360. }
  361. }
  362. private $a;
  363. public static function method145()
  364. {
  365. }
  366. abstract protected function method245();
  367. // comment
  368. final private function method345()
  369. {
  370. }
  371. }
  372. function some1(){ echo 1;}
  373. function some2(){ echo 2;}',
  374. ];
  375. $cases[] = [
  376. '<?php
  377. /*
  378. * This file is part of the PHP CS utility.
  379. *
  380. * (c) Fabien Potencier <fabien@symfony.com>
  381. *
  382. * This source file is subject to the MIT license that is bundled
  383. * with this source code in the file LICENSE.
  384. */
  385. namespace PhpCsFixer\Linter;
  386. /**
  387. * Dummy linter. No linting is performed. No error is raised.
  388. *
  389. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  390. *
  391. * @internal
  392. */
  393. final class NullLinter implements LinterInterface
  394. {
  395. /**
  396. * {@inheritdoc}
  397. */
  398. public function lintFile($path)
  399. {
  400. unset($path);
  401. }
  402. /**
  403. * {@inheritdoc}
  404. */
  405. public function lintSource($source)
  406. {
  407. unset($source);
  408. }
  409. }
  410. ',
  411. ];
  412. // do not touch anonymous functions (since PHP doesn't allow
  413. // for class attributes being functions :(, we only have to test
  414. // those used within methods)
  415. $cases[] = [
  416. '<?php
  417. class MethodTestAnonymous
  418. {
  419. public function method444a()
  420. {
  421. $text = "hello";
  422. $example = function ($arg) use ($message) {
  423. var_dump($arg . " " . $message);
  424. };
  425. $example($text);
  426. $example = function($arg) use ($message) {
  427. var_dump($arg . " " . $message);
  428. };
  429. $example = function /*test*/ ($arg) use ($message) {
  430. var_dump($arg . " " . $message);
  431. };
  432. }
  433. }',
  434. ];
  435. $cases[] = [
  436. '<?php
  437. class MethodTest1
  438. {
  439. private $c; //
  440. public function method444a()
  441. {
  442. }
  443. /**
  444. *
  445. */
  446. public function method444b()
  447. {
  448. }
  449. //
  450. public function method444c()
  451. {
  452. }
  453. private $a;
  454. public function method444d()
  455. {
  456. }
  457. private $b;
  458. //
  459. public function method444e()
  460. {
  461. }
  462. public function method444f()
  463. {
  464. }
  465. private $d; //
  466. public function method444f1()
  467. {
  468. }
  469. /**/
  470. public function method444g()
  471. {
  472. }
  473. }',
  474. '<?php
  475. class MethodTest1
  476. {
  477. private $c; //
  478. public function method444a()
  479. {
  480. }
  481. /**
  482. *
  483. */
  484. public function method444b()
  485. {
  486. }
  487. //
  488. public function method444c()
  489. {
  490. }
  491. private $a;
  492. public function method444d()
  493. {
  494. }
  495. private $b;
  496. //
  497. public function method444e()
  498. {
  499. }
  500. public function method444f()
  501. {
  502. }
  503. private $d; //
  504. public function method444f1()
  505. {
  506. }
  507. /**/
  508. public function method444g()
  509. {
  510. }
  511. }',
  512. ];
  513. // spaces between methods
  514. $cases[] = [
  515. '<?php
  516. abstract class MethodTest3
  517. {
  518. public function method021()
  519. {
  520. }
  521. public static function method121()
  522. {
  523. }
  524. abstract protected function method221(); '.'
  525. final private function method321a()
  526. {
  527. }
  528. }',
  529. '<?php
  530. abstract class MethodTest3
  531. {
  532. public function method021()
  533. {
  534. }
  535. public static function method121()
  536. {
  537. }
  538. abstract protected function method221();
  539. '.'
  540. final private function method321a()
  541. {
  542. }
  543. }', ];
  544. // don't change correct code
  545. $cases[] = [
  546. '<?php
  547. class SmallHelperException extends \Exception
  548. {
  549. public function getId111()
  550. {
  551. return 1;
  552. }
  553. public function getMessage111()
  554. {
  555. return \'message\';
  556. }
  557. }
  558. class MethodTest123124124
  559. {
  560. public function method111a(){}
  561. public function method211a(){}
  562. }',
  563. ];
  564. // do not touch function out of class scope
  565. $cases[] = [
  566. '<?php
  567. function some0() {
  568. }
  569. class MethodTest4
  570. {
  571. public function method122b()
  572. {
  573. }
  574. public function method222b()
  575. {
  576. }
  577. }
  578. function some() {
  579. }
  580. function some2() {
  581. }
  582. ',
  583. ];
  584. $cases[] = [
  585. '<?php interface A {
  586. public function B1(); // allowed comment
  587. public function C(); // allowed comment
  588. }',
  589. '<?php interface A {public function B1(); // allowed comment
  590. public function C(); // allowed comment
  591. }',
  592. ];
  593. $cases[] = [
  594. '<?php class Foo {
  595. var $a;
  596. var $b;
  597. }',
  598. '<?php class Foo {
  599. var $a;
  600. var $b;
  601. }',
  602. ];
  603. $cases[] = [
  604. '<?php
  605. class A
  606. {
  607. /** 1 */
  608. function A2() {}
  609. /** 2 */
  610. function B2() {}
  611. }
  612. ',
  613. '<?php
  614. class A
  615. {
  616. /** 1 */
  617. function A2() {}
  618. /** 2 */
  619. function B2() {}
  620. }
  621. ',
  622. ];
  623. return $cases;
  624. }
  625. /**
  626. * @param string $expected
  627. * @param null|string $input
  628. *
  629. * @dataProvider provideFixTraitsCases
  630. */
  631. public function testFixTraits($expected, $input = null)
  632. {
  633. $this->doTest($expected, $input);
  634. }
  635. public function provideFixTraitsCases()
  636. {
  637. $cases = [];
  638. // do not touch well formatted traits
  639. $cases[] = [
  640. '<?php
  641. trait OkTrait
  642. {
  643. function getReturnTypeOk()
  644. {
  645. }
  646. /**
  647. *
  648. */
  649. function getReturnDescriptionOk()
  650. {
  651. }
  652. }',
  653. ];
  654. $cases[] = [
  655. '<?php
  656. trait ezcReflectionReturnInfo {
  657. public $x = 1;
  658. protected function getA(){echo 1;}
  659. function getB(){echo 2;}
  660. protected function getC(){echo 3;}
  661. /** Description */
  662. function getD(){echo 4;}
  663. protected function getE(){echo 3;}
  664. private $a;
  665. function getF(){echo 4;}
  666. }',
  667. '<?php
  668. trait ezcReflectionReturnInfo {
  669. public $x = 1;
  670. protected function getA(){echo 1;}function getB(){echo 2;}
  671. protected function getC(){echo 3;}/** Description */function getD(){echo 4;}
  672. protected function getE(){echo 3;}private $a;function getF(){echo 4;}
  673. }',
  674. ];
  675. $cases[] = [
  676. '<?php
  677. trait SomeReturnInfo {
  678. function getReturnType()
  679. {
  680. }
  681. function getReturnDescription()
  682. {
  683. }
  684. function getReturnDescription2()
  685. {
  686. }
  687. abstract public function getWorld();
  688. }',
  689. '<?php
  690. trait SomeReturnInfo {
  691. function getReturnType()
  692. {
  693. }
  694. function getReturnDescription()
  695. {
  696. } function getReturnDescription2()
  697. {
  698. }
  699. abstract public function getWorld();
  700. }',
  701. ];
  702. return $cases;
  703. }
  704. /**
  705. * @param string $expected
  706. * @param null|string $input
  707. *
  708. * @dataProvider provideFixInterfaceCases
  709. */
  710. public function testFixInterface($expected, $input = null)
  711. {
  712. $this->doTest($expected, $input);
  713. }
  714. public function provideFixInterfaceCases()
  715. {
  716. $cases = [];
  717. $cases[] = [
  718. '<?php
  719. interface TestInterface
  720. {
  721. public function someInterfaceMethod4();
  722. public function someInterfaceMethod5();
  723. /**
  724. * {@link}
  725. */ '.'
  726. public function someInterfaceMethod6();
  727. public function someInterfaceMethod7();
  728. public function someInterfaceMethod8();
  729. }',
  730. '<?php
  731. interface TestInterface
  732. { public function someInterfaceMethod4();
  733. public function someInterfaceMethod5();
  734. /**
  735. * {@link}
  736. */ '.'
  737. public function someInterfaceMethod6();
  738. public function someInterfaceMethod7(); public function someInterfaceMethod8();
  739. }',
  740. ];
  741. // do not touch well formatted interfaces
  742. $cases[] = [
  743. '<?php
  744. interface TestInterfaceOK
  745. {
  746. public function someMethod1();
  747. public function someMethod2();
  748. }',
  749. ];
  750. // method after trait use
  751. $cases[] = [
  752. '<?php
  753. trait ezcReflectionReturnInfo {
  754. function getReturnDescription() {}
  755. }
  756. class ezcReflectionMethod extends ReflectionMethod {
  757. use ezcReflectionReturnInfo;
  758. function afterUseTrait(){}
  759. function afterUseTrait2(){}
  760. }',
  761. '<?php
  762. trait ezcReflectionReturnInfo {
  763. function getReturnDescription() {}
  764. }
  765. class ezcReflectionMethod extends ReflectionMethod {
  766. use ezcReflectionReturnInfo;function afterUseTrait(){}function afterUseTrait2(){}
  767. }',
  768. ];
  769. return $cases;
  770. }
  771. /**
  772. * @param string $expected
  773. * @param null|string $input
  774. *
  775. * @dataProvider provideMessyWhitespacesCases
  776. */
  777. public function testMessyWhitespaces($expected, $input = null)
  778. {
  779. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  780. $this->doTest($expected, $input);
  781. }
  782. public function provideMessyWhitespacesCases()
  783. {
  784. return [
  785. [
  786. "<?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",
  787. "<?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",
  788. ],
  789. [
  790. "<?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",
  791. "<?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",
  792. ],
  793. ];
  794. }
  795. /**
  796. * @param string $expected
  797. * @param null|string $input
  798. *
  799. * @dataProvider provideConfigCases
  800. */
  801. public function testWithConfig($expected, $input = null, array $config = [])
  802. {
  803. $this->fixer->configure($config);
  804. $this->doTest($expected, $input);
  805. }
  806. public function provideConfigCases()
  807. {
  808. return [
  809. [
  810. '<?php
  811. class A
  812. {
  813. private $a = null;
  814. public $b = 1;
  815. function A() {}
  816. }
  817. ',
  818. '<?php
  819. class A
  820. {
  821. private $a = null;
  822. public $b = 1;
  823. function A() {}
  824. }
  825. ',
  826. ['elements' => ['property' => ClassAttributesSeparationFixer::SPACING_ONE]],
  827. ],
  828. [
  829. '<?php
  830. class A
  831. {
  832. private $a = null;
  833. public $b = 1;
  834. function A() {}
  835. }
  836. ',
  837. '<?php
  838. class A
  839. {
  840. private $a = null;
  841. public $b = 1;
  842. function A() {}
  843. }
  844. ',
  845. ['elements' => ['property' => ClassAttributesSeparationFixer::SPACING_NONE]],
  846. ],
  847. [
  848. '<?php
  849. class A
  850. {
  851. const A = 1;
  852. const THREE = ONE + self::TWO; /* test */ # test
  853. const B = 2;
  854. }
  855. ',
  856. '<?php
  857. class A
  858. {
  859. const A = 1;
  860. const THREE = ONE + self::TWO; /* test */ # test
  861. const B = 2;
  862. }
  863. ',
  864. ['elements' => ['const' => ClassAttributesSeparationFixer::SPACING_ONE]],
  865. ],
  866. [
  867. '<?php
  868. class A
  869. {
  870. const A = 1;
  871. const THREE = ONE + self::TWO;
  872. const B = 2;
  873. }
  874. ',
  875. '<?php
  876. class A
  877. {
  878. const A = 1;
  879. const THREE = ONE + self::TWO;
  880. const B = 2;
  881. }
  882. ',
  883. ['elements' => ['const' => ClassAttributesSeparationFixer::SPACING_NONE]],
  884. ],
  885. [
  886. '<?php
  887. class A
  888. {
  889. function D() {}
  890. function B4() {}
  891. }
  892. ',
  893. '<?php
  894. class A
  895. {
  896. function D() {}
  897. function B4() {}
  898. }
  899. ',
  900. ['elements' => ['method' => ClassAttributesSeparationFixer::SPACING_ONE]],
  901. ],
  902. [
  903. '<?php
  904. class A
  905. {
  906. function A() {}
  907. function B() {}
  908. }
  909. ',
  910. '<?php
  911. class A
  912. {
  913. function A() {}
  914. function B() {}
  915. }
  916. ',
  917. ['elements' => ['method' => ClassAttributesSeparationFixer::SPACING_NONE]],
  918. ],
  919. ];
  920. }
  921. /**
  922. * @param string $expected
  923. * @param null|string $input
  924. *
  925. * @dataProvider provideDeprecatedConfigCases
  926. * @group legacy
  927. * @expectedDeprecation A list of elements is deprecated, use a dictionary of `const|method|property` => `none|one` instead.
  928. */
  929. public function testWithDeprecatedConfig($expected, $input = null, array $config = [])
  930. {
  931. $this->fixer->configure($config);
  932. $this->doTest($expected, $input);
  933. }
  934. public function provideDeprecatedConfigCases()
  935. {
  936. return [
  937. [
  938. '<?php
  939. class A
  940. {
  941. private $a = null;
  942. public $b = 1;
  943. function E() {}
  944. }
  945. ',
  946. '<?php
  947. class A
  948. {
  949. private $a = null;
  950. public $b = 1;
  951. function E() {}
  952. }
  953. ',
  954. ['elements' => ['property']],
  955. ],
  956. [
  957. '<?php
  958. class A
  959. {
  960. function F() {}
  961. function B5() {}
  962. }
  963. ',
  964. '<?php
  965. class A
  966. {
  967. function F() {}
  968. function B5() {}
  969. }
  970. ',
  971. ['elements' => ['method']],
  972. ],
  973. [
  974. '<?php
  975. class A
  976. {
  977. const A = 1;
  978. const THREE = ONE + self::TWO; /* test */ # test
  979. const B = 2;
  980. }
  981. ',
  982. '<?php
  983. class A
  984. {
  985. const A = 1;
  986. const THREE = ONE + self::TWO; /* test */ # test
  987. const B = 2;
  988. }
  989. ',
  990. ['elements' => ['const']],
  991. ],
  992. ];
  993. }
  994. /**
  995. * @param string $expected
  996. * @param null|string $input
  997. *
  998. * @dataProvider provideFix70Cases
  999. * @requires PHP 7.0
  1000. */
  1001. public function testFix70($expected, $input = null)
  1002. {
  1003. $this->doTest($expected, $input);
  1004. }
  1005. public function provideFix70Cases()
  1006. {
  1007. $to = $from = '<?php ';
  1008. for ($i = 0; $i < 15; ++$i) {
  1009. $from .= sprintf('class A%d{public function GA%d(){return new class {public function B6B%d(){}};}public function otherFunction%d(){}}', $i, $i, $i, $i);
  1010. $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);
  1011. }
  1012. return [
  1013. [$to, $from],
  1014. [
  1015. '<?php $a = new class {
  1016. public function H(){}
  1017. public function B7(){}
  1018. private function C(){}
  1019. };',
  1020. '<?php $a = new class {
  1021. public function H(){}
  1022. public function B7(){}
  1023. private function C(){}
  1024. };',
  1025. ],
  1026. [
  1027. '<?php
  1028. class A
  1029. {
  1030. public function getFilter()
  1031. {
  1032. return new class () implements FilterInterface {
  1033. private $d = 123;
  1034. public function pass($a, $b) {
  1035. echo $a;
  1036. }
  1037. public $e = 5;
  1038. };}
  1039. }
  1040. ',
  1041. '<?php
  1042. class A
  1043. {public function getFilter()
  1044. {
  1045. return new class () implements FilterInterface {private $d = 123;
  1046. public function pass($a, $b) {
  1047. echo $a;
  1048. }
  1049. public $e = 5;};}
  1050. }
  1051. ',
  1052. ],
  1053. ];
  1054. }
  1055. /**
  1056. * @param string $expected
  1057. * @param null|string $input
  1058. *
  1059. * @dataProvider provideFix71Cases
  1060. * @requires PHP 7.1
  1061. */
  1062. public function testFix71($expected, $input = null)
  1063. {
  1064. $this->fixer->configure([
  1065. 'elements' => ['method' => ClassAttributesSeparationFixer::SPACING_ONE, 'const' => ClassAttributesSeparationFixer::SPACING_ONE],
  1066. ]);
  1067. $this->doTest($expected, $input);
  1068. }
  1069. public function provideFix71Cases()
  1070. {
  1071. return [
  1072. [
  1073. '<?php
  1074. class Foo {
  1075. public function H1(){}
  1076. /** */
  1077. public const BAR = 123;
  1078. /** */
  1079. private const BAZ = "a";
  1080. }',
  1081. '<?php
  1082. class Foo {
  1083. public function H1(){}
  1084. /** */
  1085. public const BAR = 123;
  1086. /** */
  1087. private const BAZ = "a";
  1088. }',
  1089. ],
  1090. ];
  1091. }
  1092. /**
  1093. * @param string $expected
  1094. * @param null|string $input
  1095. *
  1096. * @dataProvider provideFix74Cases
  1097. * @requires PHP 7.4
  1098. */
  1099. public function testFix74($expected, $input = null)
  1100. {
  1101. $this->doTest($expected, $input);
  1102. }
  1103. public function provideFix74Cases()
  1104. {
  1105. yield [
  1106. '<?php
  1107. class Foo {
  1108. private ?int $foo;
  1109. protected string $bar;
  1110. public iterable $baz;
  1111. var ? Foo\Bar $qux;
  1112. }',
  1113. '<?php
  1114. class Foo {
  1115. private ?int $foo;
  1116. protected string $bar;
  1117. public iterable $baz;
  1118. var ? Foo\Bar $qux;
  1119. }',
  1120. ];
  1121. yield [
  1122. '<?php
  1123. class Foo {
  1124. private array $foo;
  1125. private array $bar;
  1126. }',
  1127. '<?php
  1128. class Foo {
  1129. private array $foo;
  1130. private array $bar;
  1131. }',
  1132. ];
  1133. }
  1134. /**
  1135. * @param string $expected
  1136. * @param null|string $input
  1137. *
  1138. * @dataProvider provideFixPhp80Cases
  1139. * @requires PHP 8.0
  1140. */
  1141. public function testFixPhp80($expected, $input = null)
  1142. {
  1143. $this->doTest($expected, $input);
  1144. }
  1145. public function provideFixPhp80Cases()
  1146. {
  1147. yield 'attributes' => [
  1148. '<?php
  1149. class User1
  1150. {
  1151. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1152. private $id;
  1153. #[ORM\Column("string", ORM\Column::UNIQUE)]
  1154. #[Assert\String()]
  1155. #[Assert\Email(["message" => "The email {{ value }} is not a valid email."])]
  1156. private $email;
  1157. #[Assert\String()]
  1158. private $name;
  1159. }',
  1160. '<?php
  1161. class User1
  1162. {
  1163. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1164. private $id;
  1165. #[ORM\Column("string", ORM\Column::UNIQUE)]
  1166. #[Assert\String()]
  1167. #[Assert\Email(["message" => "The email {{ value }} is not a valid email."])]
  1168. private $email;
  1169. #[Assert\String()]
  1170. private $name;
  1171. }',
  1172. ];
  1173. yield 'attributes minimal' => [
  1174. '<?php
  1175. class User2{
  1176. #[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue]
  1177. private $id;
  1178. }',
  1179. '<?php
  1180. class User2{#[ORM\Id, ORM\Column("integer"), ORM\GeneratedValue] private $id;}',
  1181. ];
  1182. yield 'attributes not blocks' => [
  1183. '<?php
  1184. class User3
  1185. {
  1186. private $id;
  1187. #[ORM\Column("string")]
  1188. #[Assert\Email(["message" => "Foo"])]
  1189. private $email;
  1190. }',
  1191. '<?php
  1192. class User3
  1193. {
  1194. private $id;
  1195. #[ORM\Column("string")]
  1196. #[Assert\Email(["message" => "Foo"])] private $email;
  1197. }',
  1198. ];
  1199. yield 'constructor property promotion' => [
  1200. '<?php
  1201. class Foo {
  1202. private array $foo;
  1203. private array $bar;
  1204. public function __construct(
  1205. public float $x = 0.0,
  1206. protected float $y = 0.0,
  1207. private float $z = 0.0,
  1208. ) {}
  1209. }',
  1210. '<?php
  1211. class Foo {
  1212. private array $foo;
  1213. private array $bar;
  1214. public function __construct(
  1215. public float $x = 0.0,
  1216. protected float $y = 0.0,
  1217. private float $z = 0.0,
  1218. ) {}
  1219. }',
  1220. ];
  1221. yield 'typed properties' => [
  1222. '<?php
  1223. class Foo {
  1224. private static int | float | null $a;
  1225. private static int | float | null $b;
  1226. private int | float | null $c;
  1227. private int | float | null $d;
  1228. }',
  1229. '<?php
  1230. class Foo {
  1231. private static int | float | null $a;
  1232. private static int | float | null $b;
  1233. private int | float | null $c;
  1234. private int | float | null $d;
  1235. }',
  1236. ];
  1237. }
  1238. }