SingleClassElementPerStatementFixerTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  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\Tests\Test\AbstractFixerTestCase;
  13. use PhpCsFixer\WhitespacesFixerConfig;
  14. /**
  15. * @author Javier Spagnoletti <phansys@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer
  20. */
  21. final class SingleClassElementPerStatementFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @param string $expected
  25. * @param null|string $input
  26. *
  27. * @dataProvider provideFixCases
  28. */
  29. public function testFix($expected, $input = null)
  30. {
  31. $this->doTest($expected, $input);
  32. }
  33. public function provideFixCases()
  34. {
  35. return [
  36. [
  37. '<?php
  38. class Foo
  39. {
  40. private static $bar1 = array(1,2,3);
  41. private static $bar2 = [1,2,3];
  42. private static $baz1 = array(array(1,2), array(3, 4));
  43. private static $baz2 = array(1,2,3);
  44. private static $aaa1 = 1;
  45. private static $aaa2 = array(2, 2);
  46. private static $aaa3 = 3;
  47. }',
  48. '<?php
  49. class Foo
  50. {
  51. private static $bar1 = array(1,2,3), $bar2 = [1,2,3];
  52. private static $baz1 = array(array(1,2), array(3, 4)), $baz2 = array(1,2,3);
  53. private static $aaa1 = 1, $aaa2 = array(2, 2), $aaa3 = 3;
  54. }',
  55. ],
  56. [
  57. '<?php
  58. class Foo
  59. {
  60. const A = 1;
  61. const B = 2;
  62. }
  63. echo Foo::A, Foo::B;
  64. ',
  65. '<?php
  66. class Foo
  67. {
  68. const A = 1, B = 2;
  69. }
  70. echo Foo::A, Foo::B;
  71. ',
  72. ],
  73. [
  74. <<<'EOT'
  75. <?php
  76. class Foo { protected static $foo = 1; protected static $bar; protected static $baz=2 ; }
  77. EOT
  78. , <<<'EOT'
  79. <?php
  80. class Foo { protected static $foo = 1,$bar,$baz=2 ; }
  81. EOT
  82. ],
  83. [
  84. <<<'EOT'
  85. <?php
  86. class Foo {}
  87. class Bar
  88. {
  89. }
  90. EOT
  91. ],
  92. [
  93. <<<'EOT'
  94. <?php
  95. class Foo { protected static $foo = 1; protected static $bar; protected static $baz=2 ; }
  96. EOT
  97. , <<<'EOT'
  98. <?php
  99. class Foo { protected static $foo = 1, $bar, $baz=2 ; }
  100. EOT
  101. ],
  102. [
  103. <<<'EOT'
  104. <?php
  105. class Foo { const ONE = 1; const TWO = 2; protected static $foo = 1; protected static $bar; protected static $baz=2 ; const THREE = 3; }
  106. EOT
  107. , <<<'EOT'
  108. <?php
  109. class Foo { const ONE = 1, TWO = 2; protected static $foo = 1, $bar, $baz=2 ; const THREE = 3; }
  110. EOT
  111. ],
  112. [
  113. <<<'EOT'
  114. <?php
  115. class Foo {
  116. protected static $foo = 1;
  117. protected static $bar;
  118. protected static $baz=2;
  119. }
  120. EOT
  121. , <<<'EOT'
  122. <?php
  123. class Foo {
  124. protected static $foo = 1,
  125. $bar,
  126. $baz=2;
  127. }
  128. EOT
  129. ],
  130. [
  131. <<<'EOT'
  132. <?php
  133. class Foo {
  134. /**
  135. * Some great docblock
  136. */
  137. protected static $foo = 1;
  138. protected static $bar;
  139. protected static $baz=2;
  140. }
  141. EOT
  142. , <<<'EOT'
  143. <?php
  144. class Foo {
  145. /**
  146. * Some great docblock
  147. */
  148. protected static $foo = 1,
  149. $bar,
  150. $baz=2;
  151. }
  152. EOT
  153. ],
  154. [
  155. <<<'EOT'
  156. <?php
  157. class Foo {
  158. /**
  159. * @int
  160. */
  161. protected static $foo = 1;
  162. protected static $bar;
  163. protected static $baz=2;
  164. // this is an inline comment, not a docblock
  165. private $var = false;
  166. }
  167. EOT
  168. , <<<'EOT'
  169. <?php
  170. class Foo {
  171. /**
  172. * @int
  173. */
  174. protected static $foo = 1,
  175. $bar,
  176. $baz=2;
  177. // this is an inline comment, not a docblock
  178. private $var = false;
  179. }
  180. EOT
  181. ],
  182. [
  183. <<<'EOT'
  184. <?php
  185. class Foo {
  186. /**
  187. * @int
  188. */
  189. protected static $foo = 1;
  190. protected static $bar;
  191. protected static $baz=2;
  192. function doSomething()
  193. {
  194. }
  195. }
  196. EOT
  197. , <<<'EOT'
  198. <?php
  199. class Foo {
  200. /**
  201. * @int
  202. */
  203. protected static $foo = 1,
  204. $bar,
  205. $baz=2;
  206. function doSomething()
  207. {
  208. }
  209. }
  210. EOT
  211. ],
  212. 'line_breaks_1' => [
  213. <<<'EOT'
  214. <?php
  215. class Foo
  216. {
  217. public $bar = null;
  218. public $initialized = false;
  219. public $configured = false;
  220. public $called = false;
  221. public $arguments = array();
  222. public $baz = null;
  223. public $drop = false;
  224. function doSomething()
  225. {
  226. }
  227. }
  228. EOT
  229. , <<<'EOT'
  230. <?php
  231. class Foo
  232. {
  233. public $bar = null, $initialized = false, $configured = false, $called = false, $arguments = array();
  234. public $baz = null, $drop = false;
  235. function doSomething()
  236. {
  237. }
  238. }
  239. EOT
  240. ],
  241. 'line_breaks_2' => [
  242. <<<'EOT'
  243. <?php
  244. class Foo
  245. {
  246. const TWO = '2';
  247. public $bar = null;
  248. public $initialized = false;
  249. function doSomething()
  250. {
  251. }
  252. }
  253. EOT
  254. , <<<'EOT'
  255. <?php
  256. class Foo
  257. {
  258. const TWO = '2';
  259. public $bar = null, $initialized = false;
  260. function doSomething()
  261. {
  262. }
  263. }
  264. EOT
  265. ],
  266. 'line_breaks_3' => [
  267. <<<'EOT'
  268. <?php
  269. class Foo
  270. {
  271. const TWO = '2';
  272. public $bar = null;
  273. public $initialized = false;
  274. function doSomething()
  275. {
  276. }
  277. }
  278. EOT
  279. , <<<'EOT'
  280. <?php
  281. class Foo
  282. {
  283. const TWO = '2';
  284. public $bar = null, $initialized = false;
  285. function doSomething()
  286. {
  287. }
  288. }
  289. EOT
  290. ],
  291. 'line_breaks_4' => [
  292. <<<'EOT'
  293. <?php
  294. class Foo
  295. {
  296. public $one = 1;
  297. public $bar = null;
  298. public $initialized = false;
  299. public $configured = false;
  300. public $called = false;
  301. public $arguments = array();
  302. function doSomething()
  303. {
  304. }
  305. }
  306. EOT
  307. , <<<'EOT'
  308. <?php
  309. class Foo
  310. {
  311. public $one = 1;
  312. public $bar = null, $initialized = false, $configured = false, $called = false, $arguments = array();
  313. function doSomething()
  314. {
  315. }
  316. }
  317. EOT
  318. ],
  319. 'line_breaks_5' => [
  320. <<<'EOT'
  321. <?php
  322. class Foo
  323. {
  324. public $one = 1; public $bar = null; public $initialized = false; public $configured = false; public $called = false; public $arguments = array();
  325. function doSomething()
  326. {
  327. }
  328. }
  329. EOT
  330. , <<<'EOT'
  331. <?php
  332. class Foo
  333. {
  334. public $one = 1; public $bar = null, $initialized = false, $configured = false, $called = false, $arguments = array();
  335. function doSomething()
  336. {
  337. }
  338. }
  339. EOT
  340. ],
  341. 'line_breaks_6' => [
  342. <<<'EOT'
  343. <?php
  344. class Foo
  345. {
  346. public $one = 1;public $bar = null;public $initialized = false;public $configured = false;public $called = false;public $arguments = array();
  347. function doSomething()
  348. {
  349. }
  350. }
  351. EOT
  352. , <<<'EOT'
  353. <?php
  354. class Foo
  355. {
  356. public $one = 1;public $bar = null, $initialized = false, $configured = false, $called = false, $arguments = array();
  357. function doSomething()
  358. {
  359. }
  360. }
  361. EOT
  362. ],
  363. 'whitespace_1' => [
  364. <<<'EOT'
  365. <?php
  366. class Foo { public $one = 1; public $bar = null; public $initialized = false; public $configured = false; public $called = false; public $arguments = array();
  367. function doSomething()
  368. {
  369. }
  370. }
  371. EOT
  372. , <<<'EOT'
  373. <?php
  374. class Foo { public $one = 1; public $bar = null,$initialized = false,$configured = false,$called = false,$arguments = array();
  375. function doSomething()
  376. {
  377. }
  378. }
  379. EOT
  380. ],
  381. 'whitespace_2' => [
  382. <<<'EOT'
  383. <?php
  384. class Foo { public $one = 1; public $bar = null; public $initialized = false; public $configured = false; public $called=false; public $arguments = array();
  385. function doSomething()
  386. {
  387. }
  388. }
  389. EOT
  390. , <<<'EOT'
  391. <?php
  392. class Foo { public $one = 1; public $bar = null,$initialized = false,$configured = false,$called=false,$arguments = array();
  393. function doSomething()
  394. {
  395. }
  396. }
  397. EOT
  398. ],
  399. [
  400. <<<'EOT'
  401. <?php
  402. class Foo { protected static $foo = 1; protected static $bar; protected static $baz=1; }
  403. EOT
  404. , <<<'EOT'
  405. <?php
  406. class Foo { protected static $foo = 1, $bar, $baz=1; }
  407. EOT
  408. ],
  409. [
  410. <<<'EOT'
  411. <?php
  412. class Foo { protected static $foo = 1; protected static $bar; protected static $baz=1; }
  413. EOT
  414. , <<<'EOT'
  415. <?php
  416. class Foo { protected static $foo = 1, $bar, $baz=1; }
  417. EOT
  418. ],
  419. [
  420. <<<'EOT'
  421. <?php
  422. class Foo { protected $foo = 1; protected $bar; protected $baz=2; }
  423. EOT
  424. , <<<'EOT'
  425. <?php
  426. class Foo { protected $foo = 1, $bar, $baz=2; }
  427. EOT
  428. ],
  429. [
  430. <<<'EOT'
  431. <?php
  432. class Foo { var $foo = 1; var $bar; var $baz=2; }
  433. EOT
  434. , <<<'EOT'
  435. <?php
  436. class Foo { var $foo = 1, $bar, $baz=2; }
  437. EOT
  438. ],
  439. [
  440. <<<'EOT'
  441. <?php
  442. class Foo { var $foo = 1; var $bar; public function doSomething1() {} var $baz=2; }
  443. EOT
  444. , <<<'EOT'
  445. <?php
  446. class Foo { var $foo = 1, $bar; public function doSomething1() {} var $baz=2; }
  447. EOT
  448. ],
  449. [
  450. <<<'EOT'
  451. <?php
  452. class Foo { var $foo = 1; var $bar; public function doSomething2() { global $one, $two, $three; } var $baz=2; }
  453. EOT
  454. , <<<'EOT'
  455. <?php
  456. class Foo { var $foo = 1, $bar; public function doSomething2() { global $one, $two, $three; } var $baz=2; }
  457. EOT
  458. ],
  459. [
  460. <<<'EOT'
  461. <?php
  462. class Foo { public function doSomething3() {} protected $foo = 1; protected $bar; protected $baz=2; }
  463. EOT
  464. , <<<'EOT'
  465. <?php
  466. class Foo { public function doSomething3() {} protected $foo = 1, $bar, $baz=2; }
  467. EOT
  468. ],
  469. [
  470. <<<'EOT'
  471. <?php
  472. class Foo { public function doSomethingElse() {} protected $foo = 1; protected $bar; protected $baz=2; private $acme =array(); }
  473. EOT
  474. , <<<'EOT'
  475. <?php
  476. class Foo { public function doSomethingElse() {} protected $foo = 1, $bar, $baz=2; private $acme =array(); }
  477. EOT
  478. ],
  479. [
  480. <<<'EOT'
  481. <?php
  482. class Foo { public function doSomewhere() {} protected $foo = 1; protected $bar; protected $baz=2; private $acme1 =array(); }
  483. EOT
  484. , <<<'EOT'
  485. <?php
  486. class Foo { public function doSomewhere() {} protected $foo = 1, $bar, $baz=2; private $acme1 =array(); }
  487. EOT
  488. ],
  489. [
  490. <<<'EOT'
  491. <?php
  492. class Foo { public function doThis() { global $one1, $two2, $three3; } protected $foo = 1; protected $bar; protected $baz=2; private $acme2 =array(); }
  493. EOT
  494. , <<<'EOT'
  495. <?php
  496. class Foo { public function doThis() { global $one1, $two2, $three3; } protected $foo = 1, $bar, $baz=2; private $acme2 =array(); }
  497. EOT
  498. ],
  499. [
  500. '<?php
  501. class Foo
  502. {
  503. const A = 1;
  504. const #
  505. B#
  506. =#
  507. 2#
  508. ;#
  509. }
  510. echo Foo::A, Foo::B;
  511. ',
  512. '<?php
  513. class Foo
  514. {
  515. const A = 1,#
  516. B#
  517. =#
  518. 2#
  519. ;#
  520. }
  521. echo Foo::A, Foo::B;
  522. ',
  523. ],
  524. ];
  525. }
  526. /**
  527. * @param string $expected
  528. *
  529. * @group legacy
  530. * @dataProvider provideConfigurationCases
  531. * @expectedDeprecation Passing "elements" at the root of the configuration for rule "single_class_element_per_statement" is deprecated and will not be supported in 3.0, use "elements" => array(...) option instead.
  532. */
  533. public function testLegacyFixWithConfiguration(array $configuration, $expected)
  534. {
  535. static $input = <<<'EOT'
  536. <?php
  537. class Foo
  538. {
  539. const SOME_CONST = 'a', OTHER_CONST = 'b';
  540. protected static $foo = 1, $bar = 2;
  541. }
  542. EOT;
  543. $this->fixer->configure($configuration);
  544. $this->doTest($expected, $input);
  545. }
  546. /**
  547. * @param string $expected
  548. *
  549. * @dataProvider provideConfigurationCases
  550. */
  551. public function testFixWithConfiguration(array $configuration, $expected)
  552. {
  553. static $input = <<<'EOT'
  554. <?php
  555. class Foo
  556. {
  557. const SOME_CONST = 'a', OTHER_CONST = 'b';
  558. protected static $foo = 1, $bar = 2;
  559. }
  560. EOT;
  561. $this->fixer->configure(['elements' => $configuration]);
  562. $this->doTest($expected, $input);
  563. }
  564. public function provideConfigurationCases()
  565. {
  566. return [
  567. [
  568. ['const', 'property'],
  569. <<<'EOT'
  570. <?php
  571. class Foo
  572. {
  573. const SOME_CONST = 'a';
  574. const OTHER_CONST = 'b';
  575. protected static $foo = 1;
  576. protected static $bar = 2;
  577. }
  578. EOT
  579. ],
  580. [
  581. ['const'],
  582. <<<'EOT'
  583. <?php
  584. class Foo
  585. {
  586. const SOME_CONST = 'a';
  587. const OTHER_CONST = 'b';
  588. protected static $foo = 1, $bar = 2;
  589. }
  590. EOT
  591. ],
  592. [
  593. ['property'],
  594. <<<'EOT'
  595. <?php
  596. class Foo
  597. {
  598. const SOME_CONST = 'a', OTHER_CONST = 'b';
  599. protected static $foo = 1;
  600. protected static $bar = 2;
  601. }
  602. EOT
  603. ],
  604. ];
  605. }
  606. public function testWrongConfig()
  607. {
  608. $this->expectException(\PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class);
  609. $this->expectExceptionMessageMatches('/^\[single_class_element_per_statement\] Invalid configuration: The option "elements" .*\.$/');
  610. $this->fixer->configure(['elements' => ['foo']]);
  611. }
  612. /**
  613. * @param string $expected
  614. * @param string $input
  615. *
  616. * @dataProvider providePHP71Cases
  617. * @requires PHP 7.1
  618. */
  619. public function testPHP71($expected, $input)
  620. {
  621. $this->doTest($expected, $input);
  622. }
  623. public function providePHP71Cases()
  624. {
  625. return [
  626. [
  627. '<?php
  628. class Token {
  629. const PUBLIC_CONST = 0;
  630. private const PRIVATE_CONST = 0;
  631. protected const PROTECTED_CONST = 0;
  632. public const PUBLIC_CONST_TWO = 0;
  633. public const TEST_71 = 0;
  634. }
  635. ',
  636. '<?php
  637. class Token {
  638. const PUBLIC_CONST = 0;
  639. private const PRIVATE_CONST = 0;
  640. protected const PROTECTED_CONST = 0;
  641. public const PUBLIC_CONST_TWO = 0, TEST_71 = 0;
  642. }
  643. ',
  644. ],
  645. ];
  646. }
  647. /**
  648. * @param string $expected
  649. * @param null|string $input
  650. *
  651. * @dataProvider provideMessyWhitespacesCases
  652. */
  653. public function testMessyWhitespaces($expected, $input = null)
  654. {
  655. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  656. $this->doTest($expected, $input);
  657. }
  658. public function provideMessyWhitespacesCases()
  659. {
  660. return [
  661. [
  662. "<?php\r\n\tclass Foo {\r\n\t\tconst AAA=0;\r\n\t\tconst BBB=1;\r\n\t}",
  663. "<?php\r\n\tclass Foo {\r\n\t\tconst AAA=0, BBB=1;\r\n\t}",
  664. ],
  665. ];
  666. }
  667. /**
  668. * @requires PHP 7.0
  669. */
  670. public function testAnonymousClassFixing()
  671. {
  672. $this->doTest(
  673. '<?php
  674. $a = new class() {
  675. const PUBLIC_CONST_TWO = 0;
  676. const TEST_70 = 0;
  677. public function a() {
  678. }
  679. };
  680. class C
  681. {
  682. public function A()
  683. {
  684. $a = new class() {
  685. const PUBLIC_CONST_TWO = 0;
  686. const TEST_70 = 0;
  687. public function a() {}
  688. };
  689. }
  690. }
  691. ',
  692. '<?php
  693. $a = new class() {
  694. const PUBLIC_CONST_TWO = 0, TEST_70 = 0;
  695. public function a() {
  696. }
  697. };
  698. class C
  699. {
  700. public function A()
  701. {
  702. $a = new class() {
  703. const PUBLIC_CONST_TWO = 0, TEST_70 = 0;
  704. public function a() {}
  705. };
  706. }
  707. }
  708. '
  709. );
  710. }
  711. /**
  712. * @dataProvider provideTestFix74Cases
  713. * @requires PHP 7.4
  714. *
  715. * @param string $expected
  716. * @param null|string $input
  717. */
  718. public function testFix74($expected, $input = null)
  719. {
  720. $this->doTest($expected, $input);
  721. }
  722. public function provideTestFix74Cases()
  723. {
  724. yield [
  725. '<?php class Foo {
  726. private int $foo;
  727. private int $bar;
  728. }',
  729. '<?php class Foo {
  730. private int $foo, $bar;
  731. }',
  732. ];
  733. yield [
  734. '<?php class Foo {
  735. protected ?string $foo;
  736. protected ?string $bar;
  737. }',
  738. '<?php class Foo {
  739. protected ?string $foo, $bar;
  740. }',
  741. ];
  742. yield [
  743. '<?php class Foo {
  744. public ? string $foo;
  745. public ? string $bar;
  746. }',
  747. '<?php class Foo {
  748. public ? string $foo, $bar;
  749. }',
  750. ];
  751. yield [
  752. '<?php class Foo {
  753. var ? Foo\Bar $foo;
  754. var ? Foo\Bar $bar;
  755. }',
  756. '<?php class Foo {
  757. var ? Foo\Bar $foo, $bar;
  758. }',
  759. ];
  760. yield [
  761. '<?php class Foo {
  762. var array $foo;
  763. var array $bar;
  764. }',
  765. '<?php class Foo {
  766. var array $foo, $bar;
  767. }',
  768. ];
  769. }
  770. }