NoEmptyStatementFixerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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\Semicolon;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer
  20. */
  21. final class NoEmptyStatementFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideNoEmptyStatementsCases
  25. */
  26. public function testNoEmptyStatements(string $expected, ?string $input = null): void
  27. {
  28. $this->doTest($expected, $input);
  29. }
  30. public static function provideNoEmptyStatementsCases(): iterable
  31. {
  32. yield [
  33. '<?php
  34. abstract class TestClass0 extends Test IMPLEMENTS TestInterface, TestInterface2
  35. {
  36. }
  37. ',
  38. '<?php
  39. abstract class TestClass0 extends Test IMPLEMENTS TestInterface, TestInterface2
  40. {
  41. };
  42. ',
  43. ];
  44. yield [
  45. '<?php
  46. abstract class TestClass1 EXTENDS Test implements TestInterface
  47. {
  48. }
  49. ',
  50. '<?php
  51. abstract class TestClass1 EXTENDS Test implements TestInterface
  52. {
  53. };
  54. ',
  55. ];
  56. yield [
  57. '<?php
  58. CLASS TestClass2 extends Test
  59. {
  60. }
  61. ',
  62. '<?php
  63. CLASS TestClass2 extends Test
  64. {
  65. };
  66. ',
  67. ];
  68. yield [
  69. '<?php
  70. class TestClass3 implements TestInterface1
  71. {
  72. }
  73. ',
  74. '<?php
  75. class TestClass3 implements TestInterface1
  76. {
  77. };
  78. ',
  79. ];
  80. yield [
  81. '<?php
  82. class TestClass4
  83. {
  84. }
  85. ',
  86. '<?php
  87. class TestClass4
  88. {
  89. };
  90. ',
  91. ];
  92. yield [
  93. '<?php
  94. interface TestInterface1
  95. {
  96. }
  97. ',
  98. '<?php
  99. interface TestInterface1
  100. {
  101. };
  102. ',
  103. ];
  104. yield [
  105. '<?php
  106. interface TestExtendingInterface extends TestInterface2, TestInterface3 {
  107. }
  108. ',
  109. '<?php
  110. interface TestExtendingInterface extends TestInterface2, TestInterface3 {
  111. };
  112. ',
  113. ];
  114. yield [
  115. '<?php
  116. namespace Two {
  117. $a = 1; {
  118. }
  119. }
  120. ',
  121. '<?php
  122. namespace Two {;;
  123. $a = 1; {
  124. };
  125. }
  126. ',
  127. ];
  128. yield [
  129. '<?php
  130. {
  131. '.'
  132. }
  133. echo 1;
  134. ',
  135. '<?php
  136. {
  137. ;
  138. };
  139. echo 1;
  140. ',
  141. ];
  142. yield [
  143. '<?php
  144. while($time < $a)
  145. ;
  146. echo "done waiting.";
  147. $b = \Test;
  148. ',
  149. ];
  150. yield [
  151. '<?php
  152. if($a>1){
  153. }
  154. ',
  155. '<?php
  156. if($a>1){
  157. };
  158. ',
  159. ];
  160. yield [
  161. '<?php
  162. if($a>1) {
  163. } else {
  164. }
  165. ',
  166. '<?php
  167. if($a>1) {
  168. } else {
  169. };
  170. ',
  171. ];
  172. yield [
  173. '<?php
  174. try{
  175. }catch (\Exception $e) {
  176. }
  177. ',
  178. '<?php
  179. try{
  180. }catch (\Exception $e) {
  181. };
  182. ',
  183. ];
  184. yield [
  185. '<?php ',
  186. '<?php ;',
  187. ];
  188. yield [
  189. '<?php
  190. function foo()
  191. {
  192. // a
  193. }
  194. ',
  195. '<?php
  196. function foo()
  197. {
  198. ; // a
  199. }
  200. ',
  201. ];
  202. yield [
  203. '<?php function foo(){}',
  204. '<?php function foo(){;;}',
  205. ];
  206. yield [
  207. '<?php class Test{}',
  208. '<?php class Test{};',
  209. ];
  210. yield [
  211. '<?php
  212. for(;;) {
  213. }
  214. ',
  215. '<?php
  216. for(;;) {
  217. };
  218. ',
  219. ];
  220. yield [
  221. '<?php
  222. foreach($a as $b) {
  223. }
  224. foreach($a as $b => $c) {
  225. }
  226. ',
  227. '<?php
  228. foreach($a as $b) {
  229. };
  230. foreach($a as $b => $c) {
  231. };
  232. ',
  233. ];
  234. yield [
  235. '<?php
  236. while($a > 1){
  237. }
  238. do {
  239. } while($a>1); // 1
  240. ',
  241. '<?php
  242. while($a > 1){
  243. };
  244. do {
  245. } while($a>1); 1; // 1
  246. ',
  247. ];
  248. yield [
  249. '<?php
  250. switch($a) {
  251. default : {echo 1;}
  252. }
  253. ',
  254. '<?php
  255. switch($a) {
  256. default : {echo 1;}
  257. };
  258. ',
  259. ];
  260. yield [
  261. '<?php
  262. function test($a, $b) {
  263. }
  264. ',
  265. '<?php
  266. function test($a, $b) {
  267. };
  268. ',
  269. ];
  270. yield [
  271. '<?php
  272. function foo($n)
  273. {
  274. '.'
  275. $a = function(){};
  276. $b = function() use ($a) {};
  277. ++${"a"};
  278. switch(fooBar()) {
  279. case 5;{
  280. }
  281. }
  282. return $n->{$o};
  283. }
  284. ',
  285. '<?php
  286. function foo($n)
  287. {
  288. ;
  289. $a = function(){};
  290. $b = function() use ($a) {};
  291. ++${"a"};
  292. switch(fooBar()) {
  293. case 5;{
  294. }
  295. };
  296. return $n->{$o};
  297. };
  298. ',
  299. ];
  300. yield [
  301. '<?php
  302. declare(ticks=1) {
  303. // entire script here
  304. }
  305. declare(ticks=1);
  306. ',
  307. '<?php
  308. declare(ticks=1) {
  309. // entire script here
  310. };
  311. declare(ticks=1);
  312. ',
  313. ];
  314. yield [
  315. '<?php
  316. namespace A\B\C;
  317. use D;
  318. ',
  319. '<?php
  320. namespace A\B\C;;;;
  321. use D;;;;
  322. ',
  323. ];
  324. yield [
  325. '<?php
  326. namespace A\B\C;
  327. use D;
  328. ',
  329. '<?php
  330. namespace A\B\C;
  331. use D;;;;
  332. ',
  333. ];
  334. yield [
  335. '<?php
  336. namespace A\B\C;use D;
  337. ',
  338. '<?php
  339. namespace A\B\C;;use D;
  340. ',
  341. ];
  342. yield [
  343. '<?php
  344. trait TestTrait
  345. {
  346. }
  347. ',
  348. '<?php
  349. trait TestTrait
  350. {
  351. };
  352. ',
  353. ];
  354. yield [
  355. '<?php
  356. try {
  357. throw new \Exception("Foo.");
  358. } catch (\Exception $e){
  359. //
  360. } finally {
  361. } '.'
  362. ',
  363. '<?php
  364. try {
  365. throw new \Exception("Foo.");
  366. } catch (\Exception $e){
  367. //
  368. } finally {
  369. } ;
  370. ',
  371. ];
  372. foreach (['break', 'continue'] as $ops) {
  373. yield [
  374. sprintf('<?php while(true) {%s ;}', $ops),
  375. sprintf('<?php while(true) {%s 1;}', $ops),
  376. ];
  377. }
  378. foreach (['1', '1.0', '"foo"', '$foo'] as $noop) {
  379. yield [
  380. '<?php echo "foo"; ',
  381. sprintf('<?php echo "foo"; %s ;', $noop),
  382. ];
  383. }
  384. yield [
  385. '<?php /* 1 */ /* 2 */ /* 3 */ ',
  386. '<?php /* 1 */ ; /* 2 */ 1 /* 3 */ ;',
  387. ];
  388. yield [
  389. '<?php
  390. while(true) {while(true) {break 2;}}
  391. while(true) {continue;}
  392. ',
  393. ];
  394. yield [
  395. '<?php if ($foo1) {} ',
  396. '<?php if ($foo1) {} 1;',
  397. ];
  398. yield [
  399. '<?php if ($foo2) {}',
  400. '<?php if ($foo2) {1;}',
  401. ];
  402. }
  403. /**
  404. * @dataProvider provideFixCases
  405. */
  406. public function testFix(string $expected, ?string $input = null): void
  407. {
  408. $this->doTest($expected, $input);
  409. }
  410. public static function provideFixCases(): iterable
  411. {
  412. yield [
  413. '<?php
  414. use function Functional\map;
  415. $a = new class {
  416. public function log($msg)
  417. {
  418. }
  419. };
  420. ',
  421. ];
  422. yield [
  423. '<?php
  424. use function Functional\map;
  425. $a = new class extends A {
  426. };
  427. ',
  428. ];
  429. yield [
  430. '<?php
  431. use function Functional\map;
  432. $a = new class implements B {
  433. };
  434. ',
  435. ];
  436. yield [
  437. '<?php
  438. use function Functional\map;
  439. $a = new class extends A implements B {
  440. };
  441. ',
  442. ];
  443. yield [
  444. '<?php
  445. $a = new class extends \A implements B\C {
  446. };
  447. ',
  448. ];
  449. yield [
  450. '<?php {{}}',
  451. '<?php {{}};',
  452. ];
  453. yield [
  454. '<?php
  455. namespace A\B\C {
  456. }
  457. ',
  458. '<?php
  459. namespace A\B\C {
  460. };
  461. ',
  462. ];
  463. yield [
  464. '<?php
  465. namespace A{
  466. }
  467. ',
  468. '<?php
  469. namespace A{
  470. };
  471. ',
  472. ];
  473. yield [
  474. '<?php
  475. namespace{
  476. }
  477. ',
  478. '<?php
  479. namespace{
  480. };
  481. ',
  482. ];
  483. }
  484. /**
  485. * @dataProvider provideCasesWithShortOpenTagCases
  486. */
  487. public function testCasesWithShortOpenTag(string $expected, ?string $input = null): void
  488. {
  489. if (!\ini_get('short_open_tag')) {
  490. self::markTestSkipped('No short tag tests possible.');
  491. }
  492. $this->doTest($expected, $input);
  493. }
  494. public static function provideCasesWithShortOpenTagCases(): iterable
  495. {
  496. yield [
  497. '<? ',
  498. '<? ;',
  499. ];
  500. }
  501. /**
  502. * @dataProvider provideFixMultipleSemicolonsCases
  503. */
  504. public function testFixMultipleSemicolons(string $expected, ?string $input = null): void
  505. {
  506. $this->doTest($expected, $input);
  507. }
  508. public static function provideFixMultipleSemicolonsCases(): iterable
  509. {
  510. yield [
  511. '<?php $foo = 2 ; //
  512. '.'
  513. ',
  514. '<?php $foo = 2 ; //
  515. ;
  516. ',
  517. ];
  518. yield [
  519. '<?php $foo = 3; /**/ ',
  520. '<?php $foo = 3; /**/; ;',
  521. ];
  522. yield [
  523. '<?php $foo = 1;',
  524. '<?php $foo = 1;;;',
  525. ];
  526. yield [
  527. '<?php $foo = 4; ',
  528. '<?php $foo = 4;; ;;',
  529. ];
  530. yield [
  531. '<?php $foo = 5;
  532. ',
  533. '<?php $foo = 5;;
  534. ;
  535. ;',
  536. ];
  537. yield [
  538. '<?php $foo = 6; ',
  539. '<?php $foo = 6;; ',
  540. ];
  541. yield [
  542. '<?php for ($i = 7; ; ++$i) {}',
  543. ];
  544. yield [
  545. '<?php
  546. switch($a){
  547. case 8;
  548. echo 9;
  549. }
  550. ',
  551. '<?php
  552. switch($a){
  553. case 8;;
  554. echo 9;
  555. }
  556. ',
  557. ];
  558. }
  559. /**
  560. * @dataProvider provideFix81Cases
  561. *
  562. * @requires PHP 8.1
  563. */
  564. public function testFix81(string $expected, string $input): void
  565. {
  566. $this->doTest($expected, $input);
  567. }
  568. public static function provideFix81Cases(): iterable
  569. {
  570. yield [
  571. '<?php enum Foo{}',
  572. '<?php enum Foo{};',
  573. ];
  574. }
  575. }