MultilineWhitespaceBeforeSemicolonsFixerTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  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\Semicolon;
  12. use PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @author John Kelly <wablam@gmail.com>
  17. * @author Graham Campbell <graham@alt-three.com>
  18. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  19. * @author Egidijus Girčys <e.gircys@gmail.com>
  20. *
  21. * @internal
  22. *
  23. * @covers \PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer
  24. */
  25. final class MultilineWhitespaceBeforeSemicolonsFixerTest extends AbstractFixerTestCase
  26. {
  27. /**
  28. * @param string $expected
  29. * @param null|string $input
  30. *
  31. * @dataProvider provideMultiLineWhitespaceFixCases
  32. */
  33. public function testFixMultiLineWhitespace($expected, $input = null)
  34. {
  35. $this->fixer->configure(['strategy' => MultilineWhitespaceBeforeSemicolonsFixer::STRATEGY_NO_MULTI_LINE]);
  36. $this->doTest($expected, $input);
  37. }
  38. public function provideMultiLineWhitespaceFixCases()
  39. {
  40. return [
  41. [
  42. '<?php
  43. $foo->bar() // test
  44. ;',
  45. '<?php
  46. $foo->bar() // test
  47. ;',
  48. ],
  49. [
  50. "<?php echo(1) // test\n;",
  51. ],
  52. [
  53. '<?php
  54. $foo->bar() # test
  55. ;',
  56. '<?php
  57. $foo->bar() # test
  58. ;',
  59. ],
  60. [
  61. "<?php\n;",
  62. ],
  63. [
  64. '<?php
  65. $this
  66. ->setName(\'readme1\')
  67. ->setDescription(\'Generates the README\');
  68. ',
  69. '<?php
  70. $this
  71. ->setName(\'readme1\')
  72. ->setDescription(\'Generates the README\')
  73. ;
  74. ',
  75. ],
  76. [
  77. '<?php
  78. $this
  79. ->setName(\'readme2\')
  80. ->setDescription(\'Generates the README\');
  81. ',
  82. '<?php
  83. $this
  84. ->setName(\'readme2\')
  85. ->setDescription(\'Generates the README\')
  86. ;
  87. ',
  88. ],
  89. [
  90. '<?php echo "$this->foo(\'with param containing ;\') ;" ;',
  91. ],
  92. [
  93. '<?php $this->foo();',
  94. ],
  95. [
  96. '<?php $this->foo() ;',
  97. ],
  98. [
  99. '<?php $this->foo(\'with param containing ;\') ;',
  100. ],
  101. [
  102. '<?php $this->foo(\'with param containing ) ; \') ;',
  103. ],
  104. [
  105. '<?php $this->foo("with param containing ) ; ") ; ?>',
  106. ],
  107. [
  108. '<?php $this->foo("with semicolon in string) ; "); ?>',
  109. ],
  110. [
  111. '<?php
  112. $this
  113. ->example();',
  114. '<?php
  115. $this
  116. ->example()
  117. ;',
  118. ],
  119. [
  120. '<?php
  121. Foo::bar() // test
  122. ;',
  123. '<?php
  124. Foo::bar() // test
  125. ;',
  126. ],
  127. [
  128. '<?php
  129. Foo::bar() # test
  130. ;',
  131. '<?php
  132. Foo::bar() # test
  133. ;',
  134. ],
  135. [
  136. '<?php
  137. self
  138. ::setName(\'readme1\')
  139. ->setDescription(\'Generates the README\');
  140. ',
  141. '<?php
  142. self
  143. ::setName(\'readme1\')
  144. ->setDescription(\'Generates the README\')
  145. ;
  146. ',
  147. ],
  148. [
  149. '<?php
  150. self
  151. ::setName(\'readme2\')
  152. ->setDescription(\'Generates the README\');
  153. ',
  154. '<?php
  155. self
  156. ::setName(\'readme2\')
  157. ->setDescription(\'Generates the README\')
  158. ;
  159. ',
  160. ],
  161. [
  162. '<?php echo "self::foo(\'with param containing ;\') ;" ;',
  163. ],
  164. [
  165. '<?php self::foo();',
  166. ],
  167. [
  168. '<?php self::foo() ;',
  169. ],
  170. [
  171. '<?php self::foo(\'with param containing ;\') ;',
  172. ],
  173. [
  174. '<?php self::foo(\'with param containing ) ; \') ;',
  175. ],
  176. [
  177. '<?php self::foo("with param containing ) ; ") ; ?>',
  178. ],
  179. [
  180. '<?php self::foo("with semicolon in string) ; "); ?>',
  181. ],
  182. [
  183. '<?php
  184. self
  185. ::example();',
  186. '<?php
  187. self
  188. ::example()
  189. ;',
  190. ],
  191. ];
  192. }
  193. /**
  194. * @param string $expected
  195. * @param null|string $input
  196. *
  197. * @dataProvider provideMessyWhitespacesMultiLineWhitespaceFixCases
  198. */
  199. public function testMessyWhitespacesMultiLineWhitespace($expected, $input = null)
  200. {
  201. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  202. $this->fixer->configure(['strategy' => MultilineWhitespaceBeforeSemicolonsFixer::STRATEGY_NO_MULTI_LINE]);
  203. $this->doTest($expected, $input);
  204. }
  205. public function provideMessyWhitespacesMultiLineWhitespaceFixCases()
  206. {
  207. return [
  208. [
  209. "<?php echo(1) // test\r\n;",
  210. ],
  211. ];
  212. }
  213. /**
  214. * @param string $expected
  215. * @param null|string $input
  216. *
  217. * @dataProvider provideSemicolonForChainedCallsFixCases
  218. */
  219. public function testSemicolonForChainedCallsFix($expected, $input = null)
  220. {
  221. $this->fixer->configure(['strategy' => MultilineWhitespaceBeforeSemicolonsFixer::STRATEGY_NEW_LINE_FOR_CHAINED_CALLS]);
  222. $this->doTest($expected, $input);
  223. }
  224. public function provideSemicolonForChainedCallsFixCases()
  225. {
  226. return [
  227. [
  228. '<?php
  229. $this
  230. ->method1()
  231. ->method2()
  232. ;
  233. ?>',
  234. '<?php
  235. $this
  236. ->method1()
  237. ->method2();
  238. ?>',
  239. ],
  240. [
  241. '<?php
  242. $this
  243. ->method1()
  244. ->method2() // comment
  245. ;
  246. ',
  247. '<?php
  248. $this
  249. ->method1()
  250. ->method2(); // comment
  251. ',
  252. ],
  253. [
  254. '<?php
  255. $service->method1()
  256. ->method2()
  257. ;
  258. $service->method3();
  259. $this
  260. ->method1()
  261. ->method2()
  262. ;',
  263. '<?php
  264. $service->method1()
  265. ->method2()
  266. ;
  267. $service->method3();
  268. $this
  269. ->method1()
  270. ->method2();',
  271. ],
  272. [
  273. '<?php
  274. $service
  275. ->method2()
  276. ;
  277. ?>',
  278. '<?php
  279. $service
  280. ->method2();
  281. ?>',
  282. ],
  283. [
  284. '<?php
  285. $service->method1()
  286. ->method2()
  287. ->method3()
  288. ->method4()
  289. ;
  290. ?>',
  291. '<?php
  292. $service->method1()
  293. ->method2()
  294. ->method3()
  295. ->method4();
  296. ?>',
  297. ],
  298. [
  299. '<?php
  300. $this->service->method1()
  301. ->method2([1, 2])
  302. ->method3(
  303. "2",
  304. 2,
  305. [1, 2]
  306. )
  307. ->method4()
  308. ;
  309. ?>',
  310. '<?php
  311. $this->service->method1()
  312. ->method2([1, 2])
  313. ->method3(
  314. "2",
  315. 2,
  316. [1, 2]
  317. )
  318. ->method4();
  319. ?>',
  320. ],
  321. [
  322. '<?php
  323. $service
  324. ->method1()
  325. ->method2()
  326. ->method3()
  327. ->method4()
  328. ;
  329. ?>',
  330. '<?php
  331. $service
  332. ->method1()
  333. ->method2()
  334. ->method3()
  335. ->method4();
  336. ?>',
  337. ],
  338. [
  339. '<?php
  340. $f = "g";
  341. $service
  342. ->method1("a", true)
  343. ->method2(true, false)
  344. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  345. ->method4(1, "a", $f)
  346. ;
  347. ?>',
  348. '<?php
  349. $f = "g";
  350. $service
  351. ->method1("a", true)
  352. ->method2(true, false)
  353. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  354. ->method4(1, "a", $f);
  355. ?>',
  356. ],
  357. [
  358. '<?php
  359. $f = "g";
  360. $service
  361. ->method1("a", true) // this is a comment
  362. /* ->method2(true, false) */
  363. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  364. ->method4(1, "a", $f) /* this is a comment */
  365. ;
  366. ?>',
  367. '<?php
  368. $f = "g";
  369. $service
  370. ->method1("a", true) // this is a comment
  371. /* ->method2(true, false) */
  372. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  373. ->method4(1, "a", $f); /* this is a comment */
  374. ?>',
  375. ],
  376. [
  377. '<?php
  378. $service->method1();
  379. $service->method2()->method3();
  380. ?>',
  381. ],
  382. [
  383. '<?php
  384. $service->method1() ;
  385. $service->method2()->method3() ;
  386. ?>',
  387. ],
  388. [
  389. '<?php
  390. $service
  391. ->method2(function ($a) {
  392. $a->otherCall()
  393. ->a()
  394. ->b()
  395. ;
  396. })
  397. ;
  398. ?>',
  399. '<?php
  400. $service
  401. ->method2(function ($a) {
  402. $a->otherCall()
  403. ->a()
  404. ->b()
  405. ;
  406. });
  407. ?>',
  408. ],
  409. [
  410. '<?php
  411. $data = $service
  412. ->method2(function ($a) {
  413. $a->otherCall()
  414. ->a()
  415. ->b(array_merge([
  416. 1 => 1,
  417. 2 => 2,
  418. ], $this->getOtherArray()
  419. ))
  420. ;
  421. })
  422. ;
  423. ?>',
  424. '<?php
  425. $data = $service
  426. ->method2(function ($a) {
  427. $a->otherCall()
  428. ->a()
  429. ->b(array_merge([
  430. 1 => 1,
  431. 2 => 2,
  432. ], $this->getOtherArray()
  433. ));
  434. });
  435. ?>',
  436. ],
  437. [
  438. '<?php
  439. $service
  440. ->method1(null, null, [
  441. null => null,
  442. 1 => $data->getId() > 0,
  443. ])
  444. ->method2(4, Type::class)
  445. ;
  446. ',
  447. '<?php
  448. $service
  449. ->method1(null, null, [
  450. null => null,
  451. 1 => $data->getId() > 0,
  452. ])
  453. ->method2(4, Type::class);
  454. ',
  455. ],
  456. [
  457. '<?php
  458. $this
  459. ->method1()
  460. ->method2()
  461. ;
  462. ?>',
  463. '<?php
  464. $this
  465. ->method1()
  466. ->method2();
  467. ?>',
  468. ],
  469. [
  470. '<?php
  471. self
  472. ::method1()
  473. ->method2()
  474. ;
  475. ?>',
  476. '<?php
  477. self
  478. ::method1()
  479. ->method2();
  480. ?>',
  481. ],
  482. [
  483. '<?php
  484. self
  485. ::method1()
  486. ->method2() // comment
  487. ;
  488. ',
  489. '<?php
  490. self
  491. ::method1()
  492. ->method2(); // comment
  493. ',
  494. ],
  495. [
  496. '<?php
  497. Service::method1()
  498. ->method2()
  499. ;
  500. Service::method3();
  501. $this
  502. ->method1()
  503. ->method2()
  504. ;',
  505. '<?php
  506. Service::method1()
  507. ->method2()
  508. ;
  509. Service::method3();
  510. $this
  511. ->method1()
  512. ->method2();',
  513. ],
  514. [
  515. '<?php
  516. Service
  517. ::method2()
  518. ;
  519. ?>',
  520. '<?php
  521. Service
  522. ::method2();
  523. ?>',
  524. ],
  525. [
  526. '<?php
  527. Service::method1()
  528. ->method2()
  529. ->method3()
  530. ->method4()
  531. ;
  532. ?>',
  533. '<?php
  534. Service::method1()
  535. ->method2()
  536. ->method3()
  537. ->method4();
  538. ?>',
  539. ],
  540. [
  541. '<?php
  542. self::method1()
  543. ->method2([1, 2])
  544. ->method3(
  545. "2",
  546. 2,
  547. [1, 2]
  548. )
  549. ->method4()
  550. ;
  551. ?>',
  552. '<?php
  553. self::method1()
  554. ->method2([1, 2])
  555. ->method3(
  556. "2",
  557. 2,
  558. [1, 2]
  559. )
  560. ->method4();
  561. ?>',
  562. ],
  563. [
  564. '<?php
  565. Service
  566. ::method1()
  567. ->method2()
  568. ->method3()
  569. ->method4()
  570. ;
  571. ?>',
  572. '<?php
  573. Service
  574. ::method1()
  575. ->method2()
  576. ->method3()
  577. ->method4();
  578. ?>',
  579. ],
  580. [
  581. '<?php
  582. $f = "g";
  583. Service
  584. ::method1("a", true)
  585. ->method2(true, false)
  586. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  587. ->method4(1, "a", $f)
  588. ;
  589. ?>',
  590. '<?php
  591. $f = "g";
  592. Service
  593. ::method1("a", true)
  594. ->method2(true, false)
  595. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  596. ->method4(1, "a", $f);
  597. ?>',
  598. ],
  599. [
  600. '<?php
  601. $f = "g";
  602. Service
  603. ::method1("a", true) // this is a comment
  604. /* ->method2(true, false) */
  605. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  606. ->method4(1, "a", $f) /* this is a comment */
  607. ;
  608. ?>',
  609. '<?php
  610. $f = "g";
  611. Service
  612. ::method1("a", true) // this is a comment
  613. /* ->method2(true, false) */
  614. ->method3([1, 2, 3], ["a" => "b", "c" => 1, "d" => true])
  615. ->method4(1, "a", $f); /* this is a comment */
  616. ?>',
  617. ],
  618. [
  619. '<?php
  620. Service::method1();
  621. Service::method2()->method3();
  622. ?>',
  623. ],
  624. [
  625. '<?php
  626. Service::method1() ;
  627. Service::method2()->method3() ;
  628. ?>',
  629. ],
  630. [
  631. '<?php
  632. Service
  633. ::method2(function ($a) {
  634. $a->otherCall()
  635. ->a()
  636. ->b()
  637. ;
  638. })
  639. ;
  640. ?>',
  641. '<?php
  642. Service
  643. ::method2(function ($a) {
  644. $a->otherCall()
  645. ->a()
  646. ->b()
  647. ;
  648. });
  649. ?>',
  650. ],
  651. [
  652. '<?php
  653. $data = Service
  654. ::method2(function () {
  655. Foo::otherCall()
  656. ->a()
  657. ->b(array_merge([
  658. 1 => 1,
  659. 2 => 2,
  660. ], $this->getOtherArray()
  661. ))
  662. ;
  663. })
  664. ;
  665. ?>',
  666. '<?php
  667. $data = Service
  668. ::method2(function () {
  669. Foo::otherCall()
  670. ->a()
  671. ->b(array_merge([
  672. 1 => 1,
  673. 2 => 2,
  674. ], $this->getOtherArray()
  675. ));
  676. });
  677. ?>',
  678. ],
  679. [
  680. '<?php
  681. Service
  682. ::method1(null, null, [
  683. null => null,
  684. 1 => $data->getId() > 0,
  685. ])
  686. ->method2(4, Type::class)
  687. ;
  688. ',
  689. '<?php
  690. Service
  691. ::method1(null, null, [
  692. null => null,
  693. 1 => $data->getId() > 0,
  694. ])
  695. ->method2(4, Type::class);
  696. ',
  697. ],
  698. [
  699. '<?php
  700. Service
  701. ::method1()
  702. ->method2()
  703. ;
  704. ?>',
  705. '<?php
  706. Service
  707. ::method1()
  708. ->method2();
  709. ?>',
  710. ],
  711. [
  712. '<?php
  713. function foo($bar)
  714. {
  715. if ($bar === 1) {
  716. $baz
  717. ->bar()
  718. ;
  719. }
  720. return (new Foo($bar))
  721. ->baz()
  722. ;
  723. }
  724. ?>',
  725. '<?php
  726. function foo($bar)
  727. {
  728. if ($bar === 1) {
  729. $baz
  730. ->bar();
  731. }
  732. return (new Foo($bar))
  733. ->baz();
  734. }
  735. ?>',
  736. ],
  737. [
  738. '<?php
  739. $foo = (new Foo($bar))
  740. ->baz()
  741. ;
  742. function foo($bar)
  743. {
  744. $foo = (new Foo($bar))
  745. ->baz()
  746. ;
  747. }
  748. ?>',
  749. '<?php
  750. $foo = (new Foo($bar))
  751. ->baz();
  752. function foo($bar)
  753. {
  754. $foo = (new Foo($bar))
  755. ->baz();
  756. }
  757. ?>',
  758. ],
  759. [
  760. '<?php $this
  761. ->methodA()
  762. ->methodB();',
  763. ],
  764. ];
  765. }
  766. /**
  767. * @param string $expected
  768. * @param null|string $input
  769. *
  770. * @dataProvider provideMessyWhitespacesSemicolonForChainedCallsFixCases
  771. */
  772. public function testMessyWhitespacesSemicolonForChainedCalls($expected, $input = null)
  773. {
  774. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  775. $this->fixer->configure(['strategy' => MultilineWhitespaceBeforeSemicolonsFixer::STRATEGY_NEW_LINE_FOR_CHAINED_CALLS]);
  776. $this->doTest($expected, $input);
  777. }
  778. public function provideMessyWhitespacesSemicolonForChainedCallsFixCases()
  779. {
  780. return [
  781. [
  782. "<?php\r\n\r\n \$this\r\n\t->method1()\r\n\t\t->method2()\r\n ;",
  783. "<?php\r\n\r\n \$this\r\n\t->method1()\r\n\t\t->method2();",
  784. ],
  785. [
  786. "<?php\r\n\r\n\t\$this->method1()\r\n\t\t->method2()\r\n\t\t->method(3)\r\n\t;",
  787. "<?php\r\n\r\n\t\$this->method1()\r\n\t\t->method2()\r\n\t\t->method(3);",
  788. ],
  789. [
  790. "<?php\r\n\r\n\t\$data = \$service\r\n\t ->method2(function (\$a) {\r\n\t\t\t\$a->otherCall()\r\n\t\t\t\t->a()\r\n\t\t\t\t->b(array_merge([\r\n\t\t\t\t\t\t1 => 1,\r\n\t\t\t\t\t\t2 => 2,\r\n\t\t\t\t\t], \$this->getOtherArray()\r\n\t\t\t\t))\r\n\t\t\t;\r\n\t\t})\r\n\t;\r\n?>",
  791. "<?php\r\n\r\n\t\$data = \$service\r\n\t ->method2(function (\$a) {\r\n\t\t\t\$a->otherCall()\r\n\t\t\t\t->a()\r\n\t\t\t\t->b(array_merge([\r\n\t\t\t\t\t\t1 => 1,\r\n\t\t\t\t\t\t2 => 2,\r\n\t\t\t\t\t], \$this->getOtherArray()\r\n\t\t\t\t));\r\n\t\t});\r\n?>",
  792. ],
  793. ];
  794. }
  795. /**
  796. * @param string $expected
  797. * @param string $input
  798. *
  799. * @requires PHP 7.3
  800. * @dataProvider provideFix73Cases
  801. */
  802. public function testFix73($expected, $input)
  803. {
  804. $this->fixer->configure(['strategy' => MultilineWhitespaceBeforeSemicolonsFixer::STRATEGY_NEW_LINE_FOR_CHAINED_CALLS]);
  805. $this->doTest($expected, $input);
  806. }
  807. public function provideFix73Cases()
  808. {
  809. return [
  810. [
  811. "<?php\n\$this\n ->one()\n ->two(2, )\n;",
  812. "<?php\n\$this\n ->one()\n ->two(2, );",
  813. ],
  814. [
  815. "<?php\n\$this\n ->one(1, )\n ->two()\n;",
  816. "<?php\n\$this\n ->one(1, )\n ->two();",
  817. ],
  818. ];
  819. }
  820. }