StatementIndentationFixerTest.php 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  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\Whitespace;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @internal
  17. *
  18. * @covers \PhpCsFixer\Fixer\Whitespace\StatementIndentationFixer
  19. */
  20. final class StatementIndentationFixerTest extends AbstractFixerTestCase
  21. {
  22. /**
  23. * @dataProvider provideFixCases
  24. */
  25. public function testFix(string $expected, ?string $input = null): void
  26. {
  27. $this->doTest($expected, $input);
  28. }
  29. public static function provideFixCases(): iterable
  30. {
  31. yield 'no brace block' => [
  32. '<?php
  33. foo();
  34. bar();',
  35. '<?php
  36. foo();
  37. bar();',
  38. ];
  39. yield 'simple' => [
  40. '<?php
  41. if ($foo) {
  42. foo();
  43. bar();
  44. }',
  45. '<?php
  46. if ($foo) {
  47. foo();
  48. bar();
  49. }',
  50. ];
  51. yield 'braces on same line as code' => [
  52. '<?php
  53. if ($foo) {
  54. foo();
  55. if ($bar) { bar(); }
  56. }',
  57. '<?php
  58. if ($foo) {
  59. foo();
  60. if ($bar) { bar(); }
  61. }',
  62. ];
  63. yield 'with several closing braces on same line' => [
  64. '<?php
  65. if ($foo) { foo();
  66. if ($bar) { bar();
  67. if ($baz) { baz(); }}
  68. foo();
  69. }
  70. foo();',
  71. '<?php
  72. if ($foo) { foo();
  73. if ($bar) { bar();
  74. if ($baz) { baz(); }}
  75. foo();
  76. }
  77. foo();',
  78. ];
  79. yield 'with meaningful content on closing line' => [
  80. '<?php
  81. if ($foo) {
  82. foo(); }
  83. foo();',
  84. '<?php
  85. if ($foo) {
  86. foo(); }
  87. foo();',
  88. ];
  89. // @TODO brace at line 6 should have one level of indentation
  90. yield 'with several opening braces on same line' => [
  91. '<?php
  92. if ($foo) { if ($foo) { foo();
  93. if ($bar) { if ($bar) { bar(); }
  94. baz();
  95. }
  96. }
  97. baz();
  98. }
  99. baz();',
  100. '<?php
  101. if ($foo) { if ($foo) { foo();
  102. if ($bar) { if ($bar) { bar(); }
  103. baz();
  104. }
  105. }
  106. baz();
  107. }
  108. baz();',
  109. ];
  110. yield 'function definition arguments' => [
  111. '<?php
  112. function foo(
  113. $bar,
  114. $baz
  115. ) {
  116. }',
  117. '<?php
  118. function foo(
  119. $bar,
  120. $baz
  121. ) {
  122. }',
  123. ];
  124. yield 'anonymous function definition arguments' => [
  125. '<?php
  126. $foo = function(
  127. $bar,
  128. $baz
  129. ) {
  130. };',
  131. '<?php
  132. $foo = function(
  133. $bar,
  134. $baz
  135. ) {
  136. };',
  137. ];
  138. yield 'interface method definition arguments' => [
  139. '<?php
  140. interface Foo {
  141. public function foo(
  142. $bar,
  143. $baz
  144. );
  145. }',
  146. '<?php
  147. interface Foo {
  148. public function foo(
  149. $bar,
  150. $baz
  151. );
  152. }',
  153. ];
  154. yield 'class method definition arguments' => [
  155. '<?php
  156. class Foo {
  157. public function foo(
  158. $bar,
  159. $baz
  160. ) {
  161. }
  162. }',
  163. '<?php
  164. class Foo {
  165. public function foo(
  166. $bar,
  167. $baz
  168. ) {
  169. }
  170. }',
  171. ];
  172. yield 'multiple class methods with many permutations of visibility modifiers' => [
  173. '<?php
  174. abstract class Test {
  175. final protected function test_final_protected() {}
  176. static private function test_static_private() {}
  177. private function test_private() {}
  178. private static function test_private_static() {}
  179. abstract public static function test_abstract_public_static();
  180. abstract static public function test_abstract_static_public();
  181. abstract public function test_abstract_public();
  182. protected abstract function test_protected_abstract();
  183. public abstract function test_public_abstract();
  184. final static protected function test_final_static_protected() {}
  185. final private static function test_final_private_static() {}
  186. public final function test_public_final() {}
  187. final private function test_final_private() {}
  188. static final public function test_static_final_public() {}
  189. protected abstract static function test_protected_abstract_static();
  190. public static abstract function test_public_static_abstract();
  191. protected static abstract function test_protected_static_abstract();
  192. static final function test_static_final() {}
  193. final static private function test_final_static_private() {}
  194. static protected abstract function test_static_protected_abstract();
  195. public abstract static function test_public_abstract_static();
  196. static final protected function test_static_final_protected() {}
  197. final public static function test_final_public_static() {}
  198. static final private function test_static_final_private() {}
  199. abstract protected function test_abstract_protected();
  200. abstract static protected function test_abstract_static_protected();
  201. private static final function test_private_static_final() {}
  202. final static function test_final_static() {}
  203. protected static function test_protected_static() {}
  204. protected function test_protected() {}
  205. public static function test_public_static() {}
  206. final function test_final() {}
  207. abstract protected static function test_abstract_protected_static();
  208. static protected function test_static_protected() {}
  209. static abstract function test_static_abstract();
  210. static abstract protected function test_static_abstract_protected();
  211. protected final static function test_protected_final_static() {}
  212. static public final function test_static_public_final() {}
  213. public final static function test_public_final_static() {}
  214. abstract static function test_abstract_static();
  215. public static final function test_public_static_final() {}
  216. static function test_static() {}
  217. abstract function test_abstract();
  218. static protected final function test_static_protected_final() {}
  219. static private final function test_static_private_final() {}
  220. private final function test_private_final() {}
  221. static public abstract function test_static_public_abstract();
  222. protected static final function test_protected_static_final() {}
  223. final protected static function test_final_protected_static() {}
  224. final static public function test_final_static_public() {}
  225. static public function test_static_public() {}
  226. function test_() {}
  227. static abstract public function test_static_abstract_public();
  228. final public function test_final_public() {}
  229. private final static function test_private_final_static() {}
  230. protected final function test_protected_final() {}
  231. public function test_public() {}
  232. }',
  233. '<?php
  234. abstract class Test {
  235. final protected function test_final_protected() {}
  236. static private function test_static_private() {}
  237. private function test_private() {}
  238. private static function test_private_static() {}
  239. abstract public static function test_abstract_public_static();
  240. abstract static public function test_abstract_static_public();
  241. abstract public function test_abstract_public();
  242. protected abstract function test_protected_abstract();
  243. public abstract function test_public_abstract();
  244. final static protected function test_final_static_protected() {}
  245. final private static function test_final_private_static() {}
  246. public final function test_public_final() {}
  247. final private function test_final_private() {}
  248. static final public function test_static_final_public() {}
  249. protected abstract static function test_protected_abstract_static();
  250. public static abstract function test_public_static_abstract();
  251. protected static abstract function test_protected_static_abstract();
  252. static final function test_static_final() {}
  253. final static private function test_final_static_private() {}
  254. static protected abstract function test_static_protected_abstract();
  255. public abstract static function test_public_abstract_static();
  256. static final protected function test_static_final_protected() {}
  257. final public static function test_final_public_static() {}
  258. static final private function test_static_final_private() {}
  259. abstract protected function test_abstract_protected();
  260. abstract static protected function test_abstract_static_protected();
  261. private static final function test_private_static_final() {}
  262. final static function test_final_static() {}
  263. protected static function test_protected_static() {}
  264. protected function test_protected() {}
  265. public static function test_public_static() {}
  266. final function test_final() {}
  267. abstract protected static function test_abstract_protected_static();
  268. static protected function test_static_protected() {}
  269. static abstract function test_static_abstract();
  270. static abstract protected function test_static_abstract_protected();
  271. protected final static function test_protected_final_static() {}
  272. static public final function test_static_public_final() {}
  273. public final static function test_public_final_static() {}
  274. abstract static function test_abstract_static();
  275. public static final function test_public_static_final() {}
  276. static function test_static() {}
  277. abstract function test_abstract();
  278. static protected final function test_static_protected_final() {}
  279. static private final function test_static_private_final() {}
  280. private final function test_private_final() {}
  281. static public abstract function test_static_public_abstract();
  282. protected static final function test_protected_static_final() {}
  283. final protected static function test_final_protected_static() {}
  284. final static public function test_final_static_public() {}
  285. static public function test_static_public() {}
  286. function test_() {}
  287. static abstract public function test_static_abstract_public();
  288. final public function test_final_public() {}
  289. private final static function test_private_final_static() {}
  290. protected final function test_protected_final() {}
  291. public function test_public() {}
  292. }',
  293. ];
  294. yield 'trait method definition arguments' => [
  295. '<?php
  296. trait Foo {
  297. public function foo(
  298. $bar,
  299. $baz
  300. ) {
  301. }
  302. }',
  303. '<?php
  304. trait Foo {
  305. public function foo(
  306. $bar,
  307. $baz
  308. ) {
  309. }
  310. }',
  311. ];
  312. yield 'function call arguments' => [
  313. '<?php
  314. foo(
  315. $bar,
  316. $baz
  317. );',
  318. '<?php
  319. foo(
  320. $bar,
  321. $baz
  322. );',
  323. ];
  324. yield 'variable function call arguments' => [
  325. '<?php
  326. $foo(
  327. $bar,
  328. $baz
  329. );',
  330. '<?php
  331. $foo(
  332. $bar,
  333. $baz
  334. );',
  335. ];
  336. yield 'chained method calls' => [
  337. '<?php
  338. if ($foo) {
  339. $foo
  340. ->bar()
  341. ->baz()
  342. ;
  343. }',
  344. '<?php
  345. if ($foo) {
  346. $foo
  347. ->bar()
  348. ->baz()
  349. ;
  350. }',
  351. ];
  352. yield 'nested arrays (long syntax)' => [
  353. '<?php
  354. if ($foo) {
  355. $foo = array(
  356. $foo,
  357. $bar
  358. ->bar()
  359. ,
  360. array($baz)
  361. )
  362. ;
  363. }',
  364. '<?php
  365. if ($foo) {
  366. $foo = array(
  367. $foo,
  368. $bar
  369. ->bar()
  370. ,
  371. array($baz)
  372. )
  373. ;
  374. }',
  375. ];
  376. yield 'nested arrays (short syntax)' => [
  377. '<?php
  378. if ($foo) {
  379. $foo = [
  380. $foo,
  381. $bar
  382. ->bar()
  383. ,
  384. [$baz]
  385. ]
  386. ;
  387. }',
  388. '<?php
  389. if ($foo) {
  390. $foo = [
  391. $foo,
  392. $bar
  393. ->bar()
  394. ,
  395. [$baz]
  396. ]
  397. ;
  398. }',
  399. ];
  400. yield 'array (long syntax) with function call' => [
  401. '<?php
  402. if ($foo) {
  403. $foo = array(
  404. foo(
  405. $bar,
  406. $baz
  407. )
  408. )
  409. ;
  410. }',
  411. '<?php
  412. if ($foo) {
  413. $foo = array(
  414. foo(
  415. $bar,
  416. $baz
  417. )
  418. )
  419. ;
  420. }',
  421. ];
  422. yield 'array (short syntax) with function call' => [
  423. '<?php
  424. if ($foo) {
  425. $foo = [
  426. foo(
  427. $bar,
  428. $baz
  429. )
  430. ]
  431. ;
  432. }',
  433. '<?php
  434. if ($foo) {
  435. $foo = [
  436. foo(
  437. $bar,
  438. $baz
  439. )
  440. ]
  441. ;
  442. }',
  443. ];
  444. yield 'array (long syntax) with class instantiation' => [
  445. '<?php
  446. if ($foo) {
  447. $foo = array(
  448. new Foo(
  449. $bar,
  450. $baz
  451. )
  452. )
  453. ;
  454. }',
  455. '<?php
  456. if ($foo) {
  457. $foo = array(
  458. new Foo(
  459. $bar,
  460. $baz
  461. )
  462. )
  463. ;
  464. }',
  465. ];
  466. yield 'array (short syntax) with class instantiation' => [
  467. '<?php
  468. if ($foo) {
  469. $foo = [
  470. new Foo(
  471. $bar,
  472. $baz
  473. )
  474. ]
  475. ;
  476. }',
  477. '<?php
  478. if ($foo) {
  479. $foo = [
  480. new Foo(
  481. $bar,
  482. $baz
  483. )
  484. ]
  485. ;
  486. }',
  487. ];
  488. yield 'implements list' => [
  489. '<?php
  490. class Foo implements
  491. Bar,
  492. Baz
  493. {}',
  494. '<?php
  495. class Foo implements
  496. Bar,
  497. Baz
  498. {}',
  499. ];
  500. yield 'extends list' => [
  501. '<?php
  502. interface Foo extends
  503. Bar,
  504. Baz
  505. {}',
  506. '<?php
  507. interface Foo extends
  508. Bar,
  509. Baz
  510. {}',
  511. ];
  512. yield 'use list' => [
  513. '<?php
  514. class Foo {
  515. use Bar,
  516. Baz;
  517. }',
  518. '<?php
  519. class Foo {
  520. use Bar,
  521. Baz;
  522. }',
  523. ];
  524. yield 'chained method call with argument' => [
  525. '<?php
  526. $foo
  527. ->bar(
  528. $baz
  529. );',
  530. '<?php
  531. $foo
  532. ->bar(
  533. $baz
  534. );',
  535. ];
  536. yield 'argument separator on its own line' => [
  537. '<?php
  538. foo(
  539. 1
  540. ,
  541. 2
  542. );',
  543. '<?php
  544. foo(
  545. 1
  546. ,
  547. 2
  548. );',
  549. ];
  550. yield 'statement end on its own line' => [
  551. '<?php
  552. if (true) {
  553. $foo =
  554. $a
  555. && $b
  556. ;
  557. }',
  558. '<?php
  559. if (true) {
  560. $foo =
  561. $a
  562. && $b
  563. ;
  564. }',
  565. ];
  566. yield 'multiline control structure conditions' => [
  567. '<?php
  568. if ($a
  569. && $b) {
  570. foo();
  571. }',
  572. '<?php
  573. if ($a
  574. && $b) {
  575. foo();
  576. }',
  577. ];
  578. yield 'switch' => [
  579. '<?php
  580. switch ($foo) {
  581. case 1:
  582. echo "foo";
  583. break;
  584. case 2:
  585. echo "bar";
  586. break;
  587. case 3:
  588. default:
  589. echo "baz";
  590. }',
  591. '<?php
  592. switch ($foo) {
  593. case 1:
  594. echo "foo";
  595. break;
  596. case 2:
  597. echo "bar";
  598. break;
  599. case 3:
  600. default:
  601. echo "baz";
  602. }',
  603. ];
  604. yield 'array (long syntax) with anonymous class' => [
  605. '<?php
  606. if ($foo) {
  607. $foo = array(
  608. new class (
  609. $bar,
  610. $baz
  611. ) {
  612. private $foo;
  613. public function foo(
  614. $foo
  615. ) {
  616. return $foo;
  617. }
  618. }
  619. )
  620. ;
  621. }',
  622. '<?php
  623. if ($foo) {
  624. $foo = array(
  625. new class (
  626. $bar,
  627. $baz
  628. ) {
  629. private $foo;
  630. public function foo(
  631. $foo
  632. ) {
  633. return $foo;
  634. }
  635. }
  636. )
  637. ;
  638. }',
  639. ];
  640. yield 'array (short syntax) with anonymous class' => [
  641. '<?php
  642. if ($foo) {
  643. $foo = [
  644. new class (
  645. $bar,
  646. $baz
  647. ) {
  648. private $foo;
  649. public function foo(
  650. $foo
  651. ) {
  652. return $foo;
  653. }
  654. }
  655. ]
  656. ;
  657. }',
  658. '<?php
  659. if ($foo) {
  660. $foo = [
  661. new class (
  662. $bar,
  663. $baz
  664. ) {
  665. private $foo;
  666. public function foo(
  667. $foo
  668. ) {
  669. return $foo;
  670. }
  671. }
  672. ]
  673. ;
  674. }',
  675. ];
  676. yield 'expression function call arguments' => [
  677. '<?php
  678. (\'foo\')(
  679. $bar,
  680. $baz
  681. );',
  682. '<?php
  683. (\'foo\')(
  684. $bar,
  685. $baz
  686. );',
  687. ];
  688. yield 'arrow function definition arguments' => [
  689. '<?php
  690. $foo = fn(
  691. $bar,
  692. $baz
  693. ) => null;',
  694. '<?php
  695. $foo = fn(
  696. $bar,
  697. $baz
  698. ) => null;',
  699. ];
  700. yield 'multiline list in foreach' => [
  701. '<?php
  702. foreach ($array as [
  703. "foo" => $foo,
  704. "bar" => $bar,
  705. ]) {
  706. }',
  707. ];
  708. yield 'switch case with control structure' => [
  709. '<?php
  710. switch ($foo) {
  711. case true:
  712. if ($bar) {
  713. bar();
  714. }
  715. return true;
  716. }',
  717. '<?php
  718. switch ($foo) {
  719. case true:
  720. if ($bar) {
  721. bar();
  722. }
  723. return true;
  724. }',
  725. ];
  726. yield 'comment in method calls chain' => [
  727. '<?php
  728. $foo
  729. ->baz()
  730. /* ->baz() */
  731. ;',
  732. ];
  733. yield 'if with only a comment and followed by else' => [
  734. '<?php
  735. if (true) {
  736. // foo
  737. } else {
  738. // bar
  739. }',
  740. ];
  741. yield 'multiple anonymous functions as function arguments' => [
  742. '<?php
  743. foo(function () {
  744. bar();
  745. }, function () {
  746. baz();
  747. });',
  748. ];
  749. yield 'multiple anonymous functions as method arguments' => [
  750. '<?php
  751. $this
  752. ->bar(function ($a) {
  753. echo $a;
  754. }, function ($b) {
  755. echo $b;
  756. })
  757. ;',
  758. ];
  759. yield 'semicolon on a newline inside a switch case without break statement' => [
  760. '<?php
  761. switch (true) {
  762. case $foo:
  763. $foo
  764. ->baz()
  765. ;
  766. }',
  767. ];
  768. yield 'alternative syntax' => [
  769. '<?php if (1): ?>
  770. <div></div>
  771. <?php else: ?>
  772. <?php if (2): ?>
  773. <div></div>
  774. <?php else: ?>
  775. <div></div>
  776. <?php endif; ?>
  777. <?php endif; ?>
  778. ',
  779. ];
  780. yield 'trait import with conflict resolution' => [
  781. '<?php
  782. class Foo {
  783. use Bar,
  784. Baz {
  785. Baz::baz insteadof Bar;
  786. }
  787. }',
  788. '<?php
  789. class Foo {
  790. use Bar,
  791. Baz {
  792. Baz::baz insteadof Bar;
  793. }
  794. }',
  795. ];
  796. yield 'multiline class definition' => [
  797. '<?php
  798. class Foo
  799. extends
  800. BaseFoo
  801. implements Bar,
  802. Baz {
  803. public function foo() {
  804. }
  805. }',
  806. '<?php
  807. class Foo
  808. extends
  809. BaseFoo
  810. implements Bar,
  811. Baz {
  812. public function foo() {
  813. }
  814. }',
  815. ];
  816. yield 'comment at end of switch case' => [
  817. '<?php
  818. switch ($foo) {
  819. case 1:
  820. // Nothing to do
  821. }',
  822. ];
  823. yield 'comment at end of switch default' => [
  824. '<?php
  825. switch ($foo) {
  826. case 1:
  827. break;
  828. case 2:
  829. break;
  830. default:
  831. // Nothing to do
  832. }',
  833. ];
  834. yield 'switch ending with empty case' => [
  835. '<?php
  836. switch ($foo) {
  837. case 1:
  838. }',
  839. ];
  840. yield 'switch ending with empty default' => [
  841. '<?php
  842. switch ($foo) {
  843. default:
  844. }',
  845. ];
  846. yield 'function ending with a comment and followed by a comma' => [
  847. '<?php
  848. foo(function () {
  849. bar();
  850. // comment
  851. }, );',
  852. ];
  853. yield 'multiline arguments starting with "new" keyword' => [
  854. '<?php
  855. $result1 = foo(
  856. new Bar1(),
  857. 1
  858. );
  859. $result2 = ($function)(
  860. new Bar2(),
  861. 2
  862. );
  863. $result3 = (new Argument())(
  864. new Bar3(),
  865. 3
  866. );',
  867. ];
  868. yield 'comments at the end of if/elseif/else blocks' => [
  869. '<?php
  870. if ($foo) {
  871. echo "foo";
  872. // foo
  873. } elseif ($bar) {
  874. echo "bar";
  875. // bar
  876. } else {
  877. echo "baz";
  878. // baz
  879. }',
  880. ];
  881. }
  882. /**
  883. * @dataProvider provideFixWithTabsCases
  884. */
  885. public function testFixWithTabs(string $expected, ?string $input = null): void
  886. {
  887. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t"));
  888. $this->doTest($expected, $input);
  889. }
  890. public static function provideFixWithTabsCases(): iterable
  891. {
  892. yield 'simple' => [
  893. "<?php
  894. if (\$foo) {
  895. \tfoo();
  896. \tbar();
  897. }",
  898. '<?php
  899. if ($foo) {
  900. foo();
  901. bar();
  902. }',
  903. ];
  904. }
  905. /**
  906. * @dataProvider provideFixPhp80Cases
  907. *
  908. * @requires PHP 8.0
  909. */
  910. public function testFixPhp80(string $expected, ?string $input = null): void
  911. {
  912. $this->doTest($expected, $input);
  913. }
  914. public static function provideFixPhp80Cases(): iterable
  915. {
  916. yield 'match expression' => [
  917. '<?php
  918. return match ($bool) {
  919. 0 => false,
  920. 1 => true,
  921. default => throw new Exception(),
  922. };',
  923. '<?php
  924. return match ($bool) {
  925. 0 => false,
  926. 1 => true,
  927. default => throw new Exception(),
  928. };',
  929. ];
  930. yield 'attribute' => [
  931. '<?php
  932. class Foo {
  933. #[SimpleAttribute]
  934. #[
  935. MultilineAttribute
  936. ]
  937. #[ComplexAttribute(
  938. foo: true,
  939. bar: [
  940. 1,
  941. 2,
  942. 3,
  943. ]
  944. )]
  945. public function bar()
  946. {
  947. }
  948. }',
  949. '<?php
  950. class Foo {
  951. #[SimpleAttribute]
  952. #[
  953. MultilineAttribute
  954. ]
  955. #[ComplexAttribute(
  956. foo: true,
  957. bar: [
  958. 1,
  959. 2,
  960. 3,
  961. ]
  962. )]
  963. public function bar()
  964. {
  965. }
  966. }',
  967. ];
  968. }
  969. /**
  970. * @dataProvider provideFixPhp81Cases
  971. *
  972. * @requires PHP 8.1
  973. */
  974. public function testFixPhp81(string $expected, ?string $input = null): void
  975. {
  976. $this->doTest($expected, $input);
  977. }
  978. public static function provideFixPhp81Cases(): iterable
  979. {
  980. yield 'simple enum' => [
  981. '<?php
  982. enum Color {
  983. case Red;
  984. case Green;
  985. case Blue;
  986. }',
  987. '<?php
  988. enum Color {
  989. case Red;
  990. case Green;
  991. case Blue;
  992. }',
  993. ];
  994. yield 'backend enum' => [
  995. '<?php
  996. enum Color: string {
  997. case Red = "R";
  998. case Green = "G";
  999. case Blue = "B";
  1000. }',
  1001. '<?php
  1002. enum Color: string {
  1003. case Red = "R";
  1004. case Green = "G";
  1005. case Blue = "B";
  1006. }',
  1007. ];
  1008. yield 'enum with method' => [
  1009. '<?php
  1010. enum Color {
  1011. case Red;
  1012. case Green;
  1013. case Blue;
  1014. public function foo() {
  1015. return true;
  1016. }
  1017. }',
  1018. '<?php
  1019. enum Color {
  1020. case Red;
  1021. case Green;
  1022. case Blue;
  1023. public function foo() {
  1024. return true;
  1025. }
  1026. }',
  1027. ];
  1028. }
  1029. }