BlankLineBeforeStatementFixerTest.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620
  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\ConfigurationException\InvalidFixerConfigurationException;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. use PhpCsFixer\WhitespacesFixerConfig;
  16. /**
  17. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  18. * @author Andreas Möller <am@localheinz.com>
  19. *
  20. * @internal
  21. *
  22. * @covers \PhpCsFixer\Fixer\Whitespace\BlankLineBeforeStatementFixer
  23. */
  24. final class BlankLineBeforeStatementFixerTest extends AbstractFixerTestCase
  25. {
  26. /**
  27. * @dataProvider provideConfigureRejectsInvalidControlStatementCases
  28. *
  29. * @param mixed $controlStatement
  30. */
  31. public function testConfigureRejectsInvalidControlStatement($controlStatement): void
  32. {
  33. $this->expectException(InvalidFixerConfigurationException::class);
  34. $this->fixer->configure([
  35. 'statements' => [$controlStatement],
  36. ]);
  37. }
  38. public static function provideConfigureRejectsInvalidControlStatementCases(): iterable
  39. {
  40. yield 'null' => [null];
  41. yield 'false' => [false];
  42. yield 'true' => [true];
  43. yield 'int' => [0];
  44. yield 'float' => [3.14];
  45. yield 'array' => [[]];
  46. yield 'object' => [new \stdClass()];
  47. yield 'unknown' => ['foo'];
  48. }
  49. /**
  50. * @dataProvider provideFixWithReturnCases
  51. */
  52. public function testFixWithDefaultConfiguration(string $expected, ?string $input = null): void
  53. {
  54. $this->doTest($expected, $input);
  55. }
  56. /**
  57. * @dataProvider provideFixWithBreakCases
  58. */
  59. public function testFixWithBreak(string $expected, ?string $input = null): void
  60. {
  61. $this->fixer->configure([
  62. 'statements' => ['break'],
  63. ]);
  64. $this->doTest($expected, $input);
  65. }
  66. public static function provideFixWithBreakCases(): iterable
  67. {
  68. yield [
  69. '<?php
  70. switch ($a) {
  71. case 42:
  72. break;
  73. }',
  74. ];
  75. yield [
  76. '<?php
  77. switch ($a) {
  78. case 42:
  79. $foo = $bar;
  80. break;
  81. }',
  82. '<?php
  83. switch ($a) {
  84. case 42:
  85. $foo = $bar;
  86. break;
  87. }',
  88. ];
  89. yield [
  90. '<?php
  91. while (true) {
  92. if ($foo === $bar) {
  93. break;
  94. }
  95. }',
  96. ];
  97. yield [
  98. '<?php
  99. while (true) {
  100. if ($foo === $bar) {
  101. break 1;
  102. }
  103. }',
  104. ];
  105. yield [
  106. '<?php
  107. while (true) {
  108. if ($foo === $bar) {
  109. echo $baz;
  110. break;
  111. }
  112. }',
  113. '<?php
  114. while (true) {
  115. if ($foo === $bar) {
  116. echo $baz;
  117. break;
  118. }
  119. }',
  120. ];
  121. yield [
  122. '<?php
  123. while (true) {
  124. if ($foo === $bar) {
  125. echo $baz;
  126. break 1;
  127. }
  128. }',
  129. '<?php
  130. while (true) {
  131. if ($foo === $bar) {
  132. echo $baz;
  133. break 1;
  134. }
  135. }',
  136. ];
  137. yield [
  138. '<?php
  139. while (true) {
  140. if ($foo === $bar) {
  141. /** X */
  142. break 1;
  143. }
  144. }',
  145. ];
  146. }
  147. /**
  148. * @dataProvider provideFixWithCaseCases
  149. */
  150. public function testFixWithCase(string $expected, ?string $input = null): void
  151. {
  152. $this->fixer->configure([
  153. 'statements' => ['case'],
  154. ]);
  155. $this->doTest($expected, $input);
  156. }
  157. public static function provideFixWithCaseCases(): iterable
  158. {
  159. yield [
  160. '<?php
  161. switch ($a) {
  162. case 1:
  163. return 1;
  164. case 2;
  165. return 2;
  166. case 3:
  167. return 3;
  168. }',
  169. '<?php
  170. switch ($a) {
  171. case 1:
  172. return 1;
  173. case 2;
  174. return 2;
  175. case 3:
  176. return 3;
  177. }',
  178. ];
  179. }
  180. /**
  181. * @dataProvider provideFixWithContinueCases
  182. */
  183. public function testFixWithContinue(string $expected, ?string $input = null): void
  184. {
  185. $this->fixer->configure([
  186. 'statements' => ['continue'],
  187. ]);
  188. $this->doTest($expected, $input);
  189. }
  190. public static function provideFixWithContinueCases(): iterable
  191. {
  192. yield [
  193. '<?php
  194. while (true) {
  195. continue;
  196. }',
  197. ];
  198. yield [
  199. '<?php
  200. while (true) {
  201. continue 1;
  202. }',
  203. ];
  204. yield [
  205. '<?php
  206. while (true) {
  207. while (true) {
  208. continue 2;
  209. }
  210. }',
  211. ];
  212. yield [
  213. '<?php
  214. while (true) {
  215. $foo = true;
  216. continue;
  217. }',
  218. '<?php
  219. while (true) {
  220. $foo = true;
  221. continue;
  222. }',
  223. ];
  224. yield [
  225. '<?php
  226. while (true) {
  227. $foo = true;
  228. continue 1;
  229. }',
  230. '<?php
  231. while (true) {
  232. $foo = true;
  233. continue 1;
  234. }',
  235. ];
  236. yield [
  237. '<?php
  238. while (true) {
  239. while (true) {
  240. switch($a) {
  241. case 1:
  242. echo 1;
  243. continue;
  244. }
  245. $foo = true;
  246. continue 2;
  247. }
  248. }',
  249. '<?php
  250. while (true) {
  251. while (true) {
  252. switch($a) {
  253. case 1:
  254. echo 1;
  255. continue;
  256. }
  257. $foo = true;
  258. continue 2;
  259. }
  260. }',
  261. ];
  262. }
  263. /**
  264. * @dataProvider provideFixWithDeclareCases
  265. */
  266. public function testFixWithDeclare(string $expected, ?string $input = null): void
  267. {
  268. $this->fixer->configure([
  269. 'statements' => ['declare'],
  270. ]);
  271. $this->doTest($expected, $input);
  272. }
  273. public static function provideFixWithDeclareCases(): iterable
  274. {
  275. yield [
  276. '<?php
  277. declare(ticks=1);',
  278. ];
  279. yield [
  280. '<?php
  281. $foo = "bar";
  282. do {
  283. } while (true);
  284. $foo = "bar";
  285. declare(ticks=1);',
  286. '<?php
  287. $foo = "bar";
  288. do {
  289. } while (true);
  290. $foo = "bar";
  291. declare(ticks=1);',
  292. ];
  293. }
  294. /**
  295. * @dataProvider provideFixWithDefaultCases
  296. */
  297. public function testFixWithDefault(string $expected, ?string $input = null): void
  298. {
  299. $this->fixer->configure([
  300. 'statements' => ['default'],
  301. ]);
  302. $this->doTest($expected, $input);
  303. }
  304. public static function provideFixWithDefaultCases(): iterable
  305. {
  306. yield [
  307. '<?php
  308. switch ($a) {
  309. case 1:
  310. return 1;
  311. default:
  312. return 2;
  313. }
  314. switch ($a1) {
  315. default:
  316. return 22;
  317. }',
  318. '<?php
  319. switch ($a) {
  320. case 1:
  321. return 1;
  322. default:
  323. return 2;
  324. }
  325. switch ($a1) {
  326. default:
  327. return 22;
  328. }',
  329. ];
  330. }
  331. /**
  332. * @dataProvider provideFixWithDoCases
  333. */
  334. public function testFixWithDo(string $expected, ?string $input = null): void
  335. {
  336. $this->fixer->configure([
  337. 'statements' => ['do'],
  338. ]);
  339. $this->doTest($expected, $input);
  340. }
  341. public static function provideFixWithDoCases(): iterable
  342. {
  343. yield [
  344. '<?php
  345. do {
  346. } while (true);',
  347. ];
  348. yield [
  349. '<?php
  350. $foo = "bar";
  351. do {
  352. } while (true);',
  353. '<?php
  354. $foo = "bar";
  355. do {
  356. } while (true);',
  357. ];
  358. }
  359. /**
  360. * @dataProvider provideFixWithExitCases
  361. */
  362. public function testFixWithExit(string $expected, ?string $input = null): void
  363. {
  364. $this->fixer->configure([
  365. 'statements' => ['exit'],
  366. ]);
  367. $this->doTest($expected, $input);
  368. }
  369. public static function provideFixWithExitCases(): iterable
  370. {
  371. yield [
  372. '<?php
  373. if ($foo === $bar) {
  374. exit();
  375. }',
  376. ];
  377. yield [
  378. '<?php
  379. if ($foo === $bar) {
  380. echo $baz;
  381. exit();
  382. }',
  383. '<?php
  384. if ($foo === $bar) {
  385. echo $baz;
  386. exit();
  387. }',
  388. ];
  389. yield [
  390. '<?php
  391. if ($foo === $bar) {
  392. echo $baz;
  393. exit();
  394. }',
  395. ];
  396. yield [
  397. '<?php
  398. mysqli_connect() or exit();',
  399. ];
  400. yield [
  401. '<?php
  402. if ($foo === $bar) {
  403. $bar = 9001;
  404. mysqli_connect() or exit();
  405. }',
  406. ];
  407. }
  408. /**
  409. * @dataProvider provideFixWithForCases
  410. */
  411. public function testFixWithFor(string $expected, ?string $input = null): void
  412. {
  413. $this->fixer->configure([
  414. 'statements' => ['for'],
  415. ]);
  416. $this->doTest($expected, $input);
  417. }
  418. public static function provideFixWithForCases(): iterable
  419. {
  420. yield [
  421. '<?php
  422. echo 1;
  423. for(;;){break;}
  424. ',
  425. '<?php
  426. echo 1;
  427. for(;;){break;}
  428. ',
  429. ];
  430. }
  431. /**
  432. * @dataProvider provideFixWithGotoCases
  433. */
  434. public function testFixWithGoto(string $expected, ?string $input = null): void
  435. {
  436. $this->fixer->configure([
  437. 'statements' => ['goto'],
  438. ]);
  439. $this->doTest($expected, $input);
  440. }
  441. public static function provideFixWithGotoCases(): iterable
  442. {
  443. yield [
  444. '<?php
  445. a:
  446. if ($foo === $bar) {
  447. goto a;
  448. }',
  449. ];
  450. yield [
  451. '<?php
  452. a:
  453. if ($foo === $bar) {
  454. echo $baz;
  455. goto a;
  456. }',
  457. '<?php
  458. a:
  459. if ($foo === $bar) {
  460. echo $baz;
  461. goto a;
  462. }',
  463. ];
  464. yield [
  465. '<?php
  466. a:
  467. if ($foo === $bar) {
  468. echo $baz;
  469. goto a;
  470. }',
  471. ];
  472. }
  473. /**
  474. * @dataProvider provideFixWithIfCases
  475. */
  476. public function testFixWithIf(string $expected, ?string $input = null): void
  477. {
  478. $this->fixer->configure([
  479. 'statements' => ['if'],
  480. ]);
  481. $this->doTest($expected, $input);
  482. }
  483. public static function provideFixWithIfCases(): iterable
  484. {
  485. yield [
  486. '<?php if (true) {
  487. echo $bar;
  488. }',
  489. ];
  490. yield [
  491. '<?php
  492. if (true) {
  493. echo $bar;
  494. }',
  495. ];
  496. yield [
  497. '<?php
  498. $foo = $bar;
  499. if (true) {
  500. echo $bar;
  501. }',
  502. '<?php
  503. $foo = $bar;
  504. if (true) {
  505. echo $bar;
  506. }',
  507. ];
  508. yield [
  509. '<?php
  510. // foo
  511. if ($foo) { }',
  512. ];
  513. }
  514. /**
  515. * @dataProvider provideFixWithForEachCases
  516. */
  517. public function testFixWithForEach(string $expected, ?string $input = null): void
  518. {
  519. $this->fixer->configure([
  520. 'statements' => ['foreach'],
  521. ]);
  522. $this->doTest($expected, $input);
  523. }
  524. public static function provideFixWithForEachCases(): iterable
  525. {
  526. yield [
  527. '<?php
  528. echo 1;
  529. foreach($a as $b){break;}
  530. ',
  531. '<?php
  532. echo 1;
  533. foreach($a as $b){break;}
  534. ',
  535. ];
  536. }
  537. /**
  538. * @dataProvider provideFixWithIncludeCases
  539. */
  540. public function testFixWithInclude(string $expected, ?string $input = null): void
  541. {
  542. $this->fixer->configure([
  543. 'statements' => ['include'],
  544. ]);
  545. $this->doTest($expected, $input);
  546. }
  547. public static function provideFixWithIncludeCases(): iterable
  548. {
  549. yield [
  550. '<?php
  551. include "foo.php";',
  552. ];
  553. yield [
  554. '<?php
  555. $foo = $bar;
  556. include "foo.php";',
  557. '<?php
  558. $foo = $bar;
  559. include "foo.php";',
  560. ];
  561. }
  562. /**
  563. * @dataProvider provideFixWithIncludeOnceCases
  564. */
  565. public function testFixWithIncludeOnce(string $expected, ?string $input = null): void
  566. {
  567. $this->fixer->configure([
  568. 'statements' => ['include_once'],
  569. ]);
  570. $this->doTest($expected, $input);
  571. }
  572. public static function provideFixWithIncludeOnceCases(): iterable
  573. {
  574. yield [
  575. '<?php
  576. include_once "foo.php";',
  577. ];
  578. yield [
  579. '<?php
  580. $foo = $bar;
  581. include_once "foo.php";',
  582. '<?php
  583. $foo = $bar;
  584. include_once "foo.php";',
  585. ];
  586. }
  587. /**
  588. * @dataProvider provideFixWithRequireCases
  589. */
  590. public function testFixWithRequire(string $expected, ?string $input = null): void
  591. {
  592. $this->fixer->configure([
  593. 'statements' => ['require'],
  594. ]);
  595. $this->doTest($expected, $input);
  596. }
  597. public static function provideFixWithRequireCases(): iterable
  598. {
  599. yield [
  600. '<?php
  601. require "foo.php";',
  602. ];
  603. yield [
  604. '<?php
  605. $foo = $bar;
  606. require "foo.php";',
  607. '<?php
  608. $foo = $bar;
  609. require "foo.php";',
  610. ];
  611. }
  612. /**
  613. * @dataProvider provideFixWithRequireOnceCases
  614. */
  615. public function testFixWithRequireOnce(string $expected, ?string $input = null): void
  616. {
  617. $this->fixer->configure([
  618. 'statements' => ['require_once'],
  619. ]);
  620. $this->doTest($expected, $input);
  621. }
  622. public static function provideFixWithRequireOnceCases(): iterable
  623. {
  624. yield [
  625. '<?php
  626. require_once "foo.php";',
  627. ];
  628. yield [
  629. '<?php
  630. $foo = $bar;
  631. require_once "foo.php";',
  632. '<?php
  633. $foo = $bar;
  634. require_once "foo.php";',
  635. ];
  636. }
  637. /**
  638. * @dataProvider provideFixWithReturnCases
  639. */
  640. public function testFixWithReturn(string $expected, ?string $input = null): void
  641. {
  642. $this->fixer->configure([
  643. 'statements' => ['return'],
  644. ]);
  645. $this->doTest($expected, $input);
  646. }
  647. public static function provideFixWithReturnCases(): iterable
  648. {
  649. yield [
  650. '<?php
  651. if ($a) { /* 1 */ /* 2 */ /* 3 */ // something about $a
  652. return $b;
  653. }
  654. ',
  655. ];
  656. yield [
  657. '<?php
  658. if ($a) { // something about $a
  659. return $b;
  660. }
  661. ',
  662. ];
  663. yield [
  664. '
  665. $a = $a;
  666. return $a;',
  667. ];
  668. yield [
  669. '<?php
  670. $a = $a;
  671. return $a;',
  672. '<?php
  673. $a = $a; return $a;',
  674. ];
  675. yield [
  676. '<?php
  677. $b = $b;
  678. return $b;',
  679. '<?php
  680. $b = $b;return $b;',
  681. ];
  682. yield [
  683. '<?php
  684. $c = $c;
  685. return $c;',
  686. '<?php
  687. $c = $c;
  688. return $c;',
  689. ];
  690. yield [
  691. '<?php
  692. $d = $d;
  693. return $d;',
  694. '<?php
  695. $d = $d;
  696. return $d;',
  697. ];
  698. yield [
  699. '<?php
  700. if (true) {
  701. return 1;
  702. }',
  703. ];
  704. yield [
  705. '<?php
  706. if (true)
  707. return 1;',
  708. ];
  709. yield [
  710. '<?php
  711. if (true) {
  712. return 1;
  713. } else {
  714. return 2;
  715. }',
  716. ];
  717. yield [
  718. '<?php
  719. if (true)
  720. return 1;
  721. else
  722. return 2;',
  723. ];
  724. yield [
  725. '<?php
  726. if (true) {
  727. return 1;
  728. } elseif (false) {
  729. return 2;
  730. }',
  731. ];
  732. yield [
  733. '<?php
  734. if (true)
  735. return 1;
  736. elseif (false)
  737. return 2;',
  738. ];
  739. yield [
  740. '<?php
  741. throw new Exception("return true; //.");',
  742. ];
  743. yield [
  744. '<?php
  745. function foo()
  746. {
  747. // comment
  748. return "foo";
  749. }',
  750. ];
  751. yield [
  752. '<?php
  753. function foo()
  754. {
  755. // comment
  756. return "bar";
  757. }',
  758. ];
  759. yield [
  760. '<?php
  761. function foo()
  762. {
  763. switch ($foo) {
  764. case 2: // comment
  765. return 1;
  766. }
  767. }',
  768. ];
  769. yield 'do not fix when there is empty line between statement and preceding comment' => [
  770. '<?php function foo()
  771. {
  772. bar();
  773. // comment
  774. return 42;
  775. }',
  776. ];
  777. yield 'do not fix when there is empty line between preceding comments' => [
  778. '<?php function foo()
  779. {
  780. bar();
  781. // comment1
  782. // comment2
  783. // comment3
  784. return 42;
  785. }',
  786. ];
  787. }
  788. /**
  789. * @dataProvider provideFixWithReturnAndMessyWhitespacesCases
  790. */
  791. public function testFixWithReturnAndMessyWhitespaces(string $expected, ?string $input = null): void
  792. {
  793. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  794. $this->doTest($expected, $input);
  795. }
  796. public static function provideFixWithReturnAndMessyWhitespacesCases(): iterable
  797. {
  798. yield [
  799. "<?php\r\n\$a = \$a;\r\n\r\nreturn \$a;",
  800. "<?php\r\n\$a = \$a; return \$a;",
  801. ];
  802. yield [
  803. "<?php\r\n\$b = \$b;\r\n\r\nreturn \$b;",
  804. "<?php\r\n\$b = \$b;return \$b;",
  805. ];
  806. yield [
  807. "<?php\r\n\$c = \$c;\r\n\r\nreturn \$c;",
  808. "<?php\r\n\$c = \$c;\r\nreturn \$c;",
  809. ];
  810. }
  811. /**
  812. * @dataProvider provideFixWithSwitchCases
  813. */
  814. public function testFixWithSwitch(string $expected, ?string $input = null): void
  815. {
  816. $this->fixer->configure([
  817. 'statements' => ['switch'],
  818. ]);
  819. $this->doTest($expected, $input);
  820. }
  821. public static function provideFixWithSwitchCases(): iterable
  822. {
  823. yield [
  824. '<?php
  825. switch ($a) {
  826. case 42:
  827. break;
  828. }',
  829. ];
  830. yield [
  831. '<?php
  832. $foo = $bar;
  833. switch ($foo) {
  834. case $bar:
  835. break;
  836. }',
  837. '<?php
  838. $foo = $bar;
  839. switch ($foo) {
  840. case $bar:
  841. break;
  842. }',
  843. ];
  844. }
  845. /**
  846. * @dataProvider provideFixWithThrowCases
  847. */
  848. public function testFixWithThrow(string $expected, ?string $input = null): void
  849. {
  850. $this->fixer->configure([
  851. 'statements' => ['throw'],
  852. ]);
  853. $this->doTest($expected, $input);
  854. }
  855. public static function provideFixWithThrowCases(): iterable
  856. {
  857. yield [
  858. '<?php
  859. if (false) {
  860. throw new \Exception("Something unexpected happened.");
  861. }',
  862. ];
  863. yield [
  864. '<?php
  865. if (false) {
  866. $log->error("No");
  867. throw new \Exception("Something unexpected happened.");
  868. }',
  869. '<?php
  870. if (false) {
  871. $log->error("No");
  872. throw new \Exception("Something unexpected happened.");
  873. }',
  874. ];
  875. }
  876. /**
  877. * @dataProvider provideFixWithTryCases
  878. */
  879. public function testFixWithTry(string $expected, ?string $input = null): void
  880. {
  881. $this->fixer->configure([
  882. 'statements' => ['try'],
  883. ]);
  884. $this->doTest($expected, $input);
  885. }
  886. public static function provideFixWithTryCases(): iterable
  887. {
  888. yield [
  889. '<?php
  890. try {
  891. $transaction->commit();
  892. } catch (\Exception $exception) {
  893. $transaction->rollback();
  894. }',
  895. ];
  896. yield [
  897. '<?php
  898. $foo = $bar;
  899. try {
  900. $transaction->commit();
  901. } catch (\Exception $exception) {
  902. $transaction->rollback();
  903. }',
  904. '<?php
  905. $foo = $bar;
  906. try {
  907. $transaction->commit();
  908. } catch (\Exception $exception) {
  909. $transaction->rollback();
  910. }',
  911. ];
  912. }
  913. /**
  914. * @dataProvider provideFixWithWhileCases
  915. */
  916. public function testFixWithWhile(string $expected, ?string $input = null): void
  917. {
  918. $this->fixer->configure([
  919. 'statements' => ['while'],
  920. ]);
  921. $this->doTest($expected, $input);
  922. }
  923. public static function provideFixWithWhileCases(): iterable
  924. {
  925. yield [
  926. '<?php
  927. while (true) {
  928. $worker->work();
  929. }',
  930. ];
  931. yield [
  932. '<?php
  933. $foo = $bar;
  934. while (true) {
  935. $worker->work();
  936. }',
  937. '<?php
  938. $foo = $bar;
  939. while (true) {
  940. $worker->work();
  941. }',
  942. ];
  943. yield [
  944. '<?php
  945. $foo = $bar;
  946. do {
  947. echo 1;
  948. while($a());
  949. $worker->work();
  950. } while (true);',
  951. '<?php
  952. $foo = $bar;
  953. do {
  954. echo 1;
  955. while($a());
  956. $worker->work();
  957. } while (true);',
  958. ];
  959. }
  960. /**
  961. * @dataProvider provideFixWithYieldCases
  962. */
  963. public function testFixWithYield(string $expected, ?string $input = null): void
  964. {
  965. $this->fixer->configure([
  966. 'statements' => ['yield'],
  967. ]);
  968. $this->doTest($expected, $input);
  969. }
  970. /**
  971. * @yield array
  972. */
  973. public static function provideFixWithYieldCases(): iterable
  974. {
  975. yield [
  976. '<?php
  977. function foo() {
  978. yield $a; /* a *//* b */ /* c */ /* d *//* e *//* etc */
  979. '.'
  980. yield $b;
  981. }',
  982. '<?php
  983. function foo() {
  984. yield $a; /* a *//* b */ /* c */ /* d *//* e *//* etc */ '.'
  985. yield $b;
  986. }',
  987. ];
  988. yield [
  989. '<?php
  990. function foo() {
  991. yield $a; // test
  992. yield $b; // test /* A */
  993. yield $c;
  994. yield $d;
  995. yield $e;#
  996. yield $f;
  997. /* @var int $g */
  998. yield $g;
  999. /* @var int $h */
  1000. yield $i;
  1001. yield $j;
  1002. }',
  1003. '<?php
  1004. function foo() {
  1005. yield $a; // test
  1006. yield $b; // test /* A */
  1007. yield $c;
  1008. yield $d;yield $e;#
  1009. yield $f;
  1010. /* @var int $g */
  1011. yield $g;
  1012. /* @var int $h */
  1013. yield $i;
  1014. yield $j;
  1015. }',
  1016. ];
  1017. yield [
  1018. '<?php
  1019. function foo() {
  1020. yield $a;
  1021. }',
  1022. ];
  1023. yield [
  1024. '<?php
  1025. function foo() {
  1026. yield $a;
  1027. yield $b;
  1028. }',
  1029. '<?php
  1030. function foo() {
  1031. yield $a;
  1032. yield $b;
  1033. }',
  1034. ];
  1035. yield [
  1036. '<?php
  1037. function foo() {
  1038. yield \'b\' => $a;
  1039. yield "a" => $b;
  1040. }',
  1041. '<?php
  1042. function foo() {
  1043. yield \'b\' => $a;
  1044. yield "a" => $b;
  1045. }',
  1046. ];
  1047. yield [
  1048. '<?php
  1049. function foo() {
  1050. $a = $a;
  1051. yield $a;
  1052. }',
  1053. ];
  1054. yield [
  1055. '<?php
  1056. function foo() {
  1057. $a = $a;
  1058. yield $a;
  1059. }',
  1060. '<?php
  1061. function foo() {
  1062. $a = $a;
  1063. yield $a;
  1064. }',
  1065. ];
  1066. yield [
  1067. '<?php function foo() {
  1068. // yield 1
  1069. yield 1;
  1070. // yield 2
  1071. yield 2;
  1072. }',
  1073. '<?php function foo() {
  1074. // yield 1
  1075. yield 1;
  1076. // yield 2
  1077. yield 2;
  1078. }',
  1079. ];
  1080. yield [
  1081. '<?php function foo() {
  1082. yield 1;
  1083. // yield 2
  1084. // or maybe yield 3
  1085. // better compromise
  1086. yield 2.5;
  1087. }',
  1088. '<?php function foo() {
  1089. yield 1;
  1090. // yield 2
  1091. // or maybe yield 3
  1092. // better compromise
  1093. yield 2.5;
  1094. }',
  1095. ];
  1096. }
  1097. /**
  1098. * @dataProvider provideFixWithYieldFromCases
  1099. */
  1100. public function testFixWithYieldFrom(string $expected, ?string $input = null): void
  1101. {
  1102. $this->fixer->configure([
  1103. 'statements' => ['yield_from'],
  1104. ]);
  1105. $this->doTest($expected, $input);
  1106. }
  1107. /**
  1108. * @yield array
  1109. */
  1110. public static function provideFixWithYieldFromCases(): iterable
  1111. {
  1112. yield [
  1113. '<?php
  1114. function foo() {
  1115. yield from $a;
  1116. }',
  1117. ];
  1118. yield [
  1119. '<?php
  1120. function foo() {
  1121. yield from $a;
  1122. yield from $b;
  1123. }',
  1124. '<?php
  1125. function foo() {
  1126. yield from $a;
  1127. yield from $b;
  1128. }',
  1129. ];
  1130. yield [
  1131. '<?php
  1132. function foo() {
  1133. $a = $a;
  1134. yield from $a;
  1135. yield $a;
  1136. yield $b;
  1137. }',
  1138. ];
  1139. yield [
  1140. '<?php
  1141. function foo() {
  1142. $a = $a;
  1143. yield from $a;
  1144. }',
  1145. '<?php
  1146. function foo() {
  1147. $a = $a;
  1148. yield from $a;
  1149. }',
  1150. ];
  1151. }
  1152. /**
  1153. * @dataProvider provideFixWithMultipleConfigStatementsCases
  1154. *
  1155. * @param string[] $statements
  1156. */
  1157. public function testFixWithMultipleConfigStatements(array $statements, string $expected, ?string $input = null): void
  1158. {
  1159. $this->fixer->configure(['statements' => $statements]);
  1160. $this->doTest($expected, $input);
  1161. }
  1162. public static function provideFixWithMultipleConfigStatementsCases(): iterable
  1163. {
  1164. $statementsWithoutCaseOrDefault = [
  1165. 'break',
  1166. 'continue',
  1167. 'declare',
  1168. 'do',
  1169. 'for',
  1170. 'foreach',
  1171. 'if',
  1172. 'include',
  1173. 'include_once',
  1174. 'require',
  1175. 'require_once',
  1176. 'return',
  1177. 'switch',
  1178. 'throw',
  1179. 'try',
  1180. 'while',
  1181. ];
  1182. $allStatements = [...$statementsWithoutCaseOrDefault, 'case', 'default'];
  1183. yield [
  1184. $statementsWithoutCaseOrDefault,
  1185. '<?php
  1186. while($a) {
  1187. if ($c) {
  1188. switch ($d) {
  1189. case $e:
  1190. continue 2;
  1191. case 4:
  1192. break;
  1193. case 5:
  1194. return 1;
  1195. default:
  1196. return 0;
  1197. }
  1198. }
  1199. }
  1200. ',
  1201. ];
  1202. yield [
  1203. $allStatements,
  1204. '<?php
  1205. while($a) {
  1206. if ($c) {
  1207. switch ($d) {
  1208. case $e:
  1209. continue 2;
  1210. case 4:
  1211. break;
  1212. case 5:
  1213. return 1;
  1214. default:
  1215. return 0;
  1216. }
  1217. }
  1218. }
  1219. ',
  1220. ];
  1221. yield [
  1222. ['break', 'throw'],
  1223. '<?php
  1224. do {
  1225. echo 0;
  1226. if ($a) {
  1227. echo 1;
  1228. break;
  1229. }
  1230. echo 2;
  1231. throw $f;
  1232. } while(true);',
  1233. '<?php
  1234. do {
  1235. echo 0;
  1236. if ($a) {
  1237. echo 1;
  1238. break;
  1239. }
  1240. echo 2;
  1241. throw $f;
  1242. } while(true);',
  1243. ];
  1244. }
  1245. /**
  1246. * @dataProvider provideFix80Cases
  1247. *
  1248. * @requires PHP 8.0
  1249. */
  1250. public function testFix80(string $expected, ?string $input = null): void
  1251. {
  1252. $this->fixer->configure([
  1253. 'statements' => ['default'],
  1254. ]);
  1255. $this->doTest($expected, $input);
  1256. }
  1257. public static function provideFix80Cases(): iterable
  1258. {
  1259. yield 'match' => [
  1260. '<?php
  1261. match ($foo) {
  1262. 1 => "a",
  1263. default => "b"
  1264. };
  1265. match ($foo) {
  1266. 1 => "a1",
  1267. default => "b2"
  1268. };
  1269. ',
  1270. ];
  1271. }
  1272. /**
  1273. * @dataProvider provideFix81Cases
  1274. *
  1275. * @requires PHP 8.1
  1276. */
  1277. public function testFix81(string $expected, ?string $input = null): void
  1278. {
  1279. $this->fixer->configure([
  1280. 'statements' => ['case'],
  1281. ]);
  1282. $this->doTest($expected, $input);
  1283. }
  1284. public static function provideFix81Cases(): iterable
  1285. {
  1286. yield 'enum' => [
  1287. '<?php
  1288. enum Suit {
  1289. case Hearts;
  1290. case Diamonds;
  1291. case Clubs;
  1292. case Spades;
  1293. }
  1294. enum UserStatus: string {
  1295. case Pending = "P";
  1296. case Active = "A";
  1297. public function label(): string {
  1298. switch ($a) {
  1299. case 1:
  1300. return 1;
  1301. case 2:
  1302. return 2; // do fix
  1303. }
  1304. return "label";
  1305. }
  1306. }
  1307. ',
  1308. '<?php
  1309. enum Suit {
  1310. case Hearts;
  1311. case Diamonds;
  1312. case Clubs;
  1313. case Spades;
  1314. }
  1315. enum UserStatus: string {
  1316. case Pending = "P";
  1317. case Active = "A";
  1318. public function label(): string {
  1319. switch ($a) {
  1320. case 1:
  1321. return 1;
  1322. case 2:
  1323. return 2; // do fix
  1324. }
  1325. return "label";
  1326. }
  1327. }
  1328. ',
  1329. ];
  1330. }
  1331. /**
  1332. * @dataProvider provideFixWithDocCommentCases
  1333. */
  1334. public function testFixWithDocComment(string $expected, string $input = null): void
  1335. {
  1336. $this->fixer->configure([
  1337. 'statements' => ['phpdoc'],
  1338. ]);
  1339. $this->doTest($expected, $input);
  1340. }
  1341. public static function provideFixWithDocCommentCases(): iterable
  1342. {
  1343. yield [
  1344. '<?php
  1345. /** @var int $foo */
  1346. $foo = 123;
  1347. /** @var float $bar */
  1348. $bar = 45.6;
  1349. /** @var string */
  1350. $baz = "789";
  1351. ',
  1352. '<?php
  1353. /** @var int $foo */
  1354. $foo = 123;
  1355. /** @var float $bar */
  1356. $bar = 45.6;
  1357. /** @var string */
  1358. $baz = "789";
  1359. ',
  1360. ];
  1361. yield [
  1362. '<?php
  1363. /* header */
  1364. /**
  1365. * Class description
  1366. */
  1367. class Foo {
  1368. /** test */
  1369. public function bar() {}
  1370. }
  1371. ',
  1372. ];
  1373. }
  1374. }