NoPhp4ConstructorFixerTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  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\ClassNotation;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Matteo Beccati <matteo@beccati.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\NoPhp4ConstructorFixer
  20. */
  21. final class NoPhp4ConstructorFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideFixCases
  25. */
  26. public function testFix(string $expected, ?string $input = null): void
  27. {
  28. $this->doTest($expected, $input);
  29. }
  30. public static function provideFixCases(): iterable
  31. {
  32. yield [
  33. '<?php $a = new class {};',
  34. ];
  35. yield [
  36. '<?php $a = new class {}?>',
  37. ];
  38. yield [
  39. '<?php
  40. $a = new Foo() <=> 1;
  41. $a = new Foo <=> 1;
  42. $a = new class() {};
  43. $a = new class() implements Foo{};
  44. $a = new class() /**/ extends Bar1{};
  45. $a = new class() extends Bar2 implements Foo{};
  46. $a = new class() extends Bar3 implements Foo, Foo2{};
  47. $a = new class() {};
  48. $a = new class {};
  49. $a = new class implements Foo{};
  50. $a = new class /**/ extends Bar1{};
  51. $a = new class extends Bar2 implements Foo{};
  52. $a = new class extends Bar3 implements Foo, Foo2{};
  53. $a = new class {}?>
  54. ',
  55. ];
  56. yield 'simple class 1' => [
  57. <<<'EOF'
  58. <?php
  59. class Foo
  60. {
  61. public function __construct($bar)
  62. {
  63. var_dump(1);
  64. }
  65. }
  66. EOF
  67. ,
  68. <<<'EOF'
  69. <?php
  70. class Foo
  71. {
  72. public function Foo($bar)
  73. {
  74. var_dump(1);
  75. }
  76. }
  77. EOF
  78. ];
  79. yield 'simple class 2' => [
  80. <<<'EOF'
  81. <?php
  82. class Foo
  83. {
  84. public#
  85. function#
  86. __construct#
  87. (#
  88. $bar#
  89. )#
  90. {}
  91. }
  92. EOF
  93. ,
  94. <<<'EOF'
  95. <?php
  96. class Foo
  97. {
  98. public#
  99. function#
  100. Foo#
  101. (#
  102. $bar#
  103. )#
  104. {}
  105. }
  106. EOF
  107. ];
  108. yield 'namespace' => [<<<'EOF'
  109. <?php
  110. namespace Baz\Qux;
  111. class Foo
  112. {
  113. public function __construct($bar)
  114. {
  115. var_dump(1);
  116. }
  117. public function Foo($bar)
  118. {
  119. var_dump(2);
  120. }
  121. }
  122. EOF];
  123. yield 'namespace 2' => [<<<'EOF'
  124. <?php
  125. namespace Baz\Qux
  126. {
  127. class Foo
  128. {
  129. public function __construct($bar)
  130. {
  131. var_dump(1);
  132. }
  133. public function Foo($bar)
  134. {
  135. var_dump(2);
  136. }
  137. }
  138. class Bar
  139. {
  140. public function Bar()
  141. {
  142. var_dump(3);
  143. }
  144. }
  145. }
  146. EOF];
  147. yield 'namespace global' => [
  148. <<<'EOF'
  149. <?php
  150. namespace {
  151. class Foo
  152. {
  153. function __construct($bar)
  154. {
  155. var_dump(1);
  156. }
  157. }
  158. }
  159. EOF,
  160. <<<'EOF'
  161. <?php
  162. namespace {
  163. class Foo
  164. {
  165. function Foo($bar)
  166. {
  167. var_dump(1);
  168. }
  169. }
  170. }
  171. EOF
  172. ];
  173. yield 'PHP 5 only' => [<<<'EOF'
  174. <?php
  175. class Foo
  176. {
  177. function __construct($bar)
  178. {
  179. var_dump(1);
  180. }
  181. function bar()
  182. {
  183. var_dump(3);
  184. }
  185. }
  186. EOF];
  187. yield 'PHP 4 only' => [
  188. <<<'EOF'
  189. <?php
  190. class Foo
  191. {
  192. /**
  193. * Constructor
  194. */
  195. function __construct($bar)
  196. {
  197. var_dump(1);
  198. }
  199. function bar()
  200. {
  201. var_dump(3);
  202. }
  203. }
  204. EOF,
  205. <<<'EOF'
  206. <?php
  207. class Foo
  208. {
  209. /**
  210. * Constructor
  211. */
  212. function foO($bar)
  213. {
  214. var_dump(1);
  215. }
  216. function bar()
  217. {
  218. var_dump(3);
  219. }
  220. }
  221. EOF
  222. ];
  223. yield 'both the right way 1' => [
  224. <<<'EOF'
  225. <?php
  226. class Foo
  227. {
  228. /**
  229. * Constructor
  230. */
  231. public function __construct()
  232. {
  233. var_dump(1);
  234. }
  235. public function bar()
  236. {
  237. var_dump(3);
  238. }
  239. }
  240. EOF,
  241. <<<'EOF'
  242. <?php
  243. class Foo
  244. {
  245. /**
  246. * Constructor
  247. */
  248. public function __construct()
  249. {
  250. var_dump(1);
  251. }
  252. /**
  253. * PHP-4 Constructor
  254. */
  255. function Foo()
  256. {
  257. // Call PHP5!
  258. $this->__construct();
  259. }
  260. public function bar()
  261. {
  262. var_dump(3);
  263. }
  264. }
  265. EOF,
  266. ];
  267. yield 'both the right way 2' => [
  268. <<<'EOF'
  269. <?php
  270. class Foo
  271. {
  272. /**
  273. * Constructor
  274. */
  275. public function __construct($bar)
  276. {
  277. var_dump(1);
  278. }
  279. public function bar()
  280. {
  281. var_dump(3);
  282. }
  283. }
  284. EOF,
  285. <<<'EOF'
  286. <?php
  287. class Foo
  288. {
  289. /**
  290. * Constructor
  291. */
  292. public function __construct($bar)
  293. {
  294. var_dump(1);
  295. }
  296. /**
  297. * PHP-4 Constructor
  298. */
  299. function Foo($bar)
  300. {
  301. // Call PHP5!
  302. $this->__construct($bar);
  303. }
  304. public function bar()
  305. {
  306. var_dump(3);
  307. }
  308. }
  309. EOF
  310. ];
  311. yield 'both the right way 3' => [
  312. <<<'EOF'
  313. <?php
  314. class Foo
  315. {
  316. /**
  317. * Constructor
  318. */
  319. public function __construct($bar = 1, $baz = null)
  320. {
  321. var_dump(1);
  322. }
  323. public function bar()
  324. {
  325. var_dump(3);
  326. }
  327. }
  328. EOF,
  329. <<<'EOF'
  330. <?php
  331. class Foo
  332. {
  333. /**
  334. * Constructor
  335. */
  336. public function __construct($bar = 1, $baz = null)
  337. {
  338. var_dump(1);
  339. }
  340. /**
  341. * PHP-4 Constructor
  342. */
  343. function Foo($bar = 1, $baz = null)
  344. {
  345. // Call PHP5!
  346. $this->__construct($bar, $baz);
  347. }
  348. public function bar()
  349. {
  350. var_dump(3);
  351. }
  352. }
  353. EOF
  354. ];
  355. yield 'both the other way around 1' => [
  356. <<<'EOF'
  357. <?php
  358. class Foo
  359. {
  360. /**
  361. * PHP-4 Constructor.
  362. *
  363. * This is the real constructor. It's the one that most likely contains any meaningful info in the docblock.
  364. */
  365. private function __construct($bar)
  366. {
  367. var_dump(1);
  368. }
  369. function bar()
  370. {
  371. var_dump(3);
  372. }
  373. }
  374. EOF,
  375. <<<'EOF'
  376. <?php
  377. class Foo
  378. {
  379. /**
  380. * PHP-5 Constructor.
  381. *
  382. * This docblock is removed, along with the entire wrapper method.
  383. */
  384. protected function __construct($bar)
  385. {
  386. // Call The Real Constructor, not the hippy fake one!
  387. $this->Foo($bar);
  388. }
  389. /**
  390. * PHP-4 Constructor.
  391. *
  392. * This is the real constructor. It's the one that most likely contains any meaningful info in the docblock.
  393. */
  394. private function Foo($bar)
  395. {
  396. var_dump(1);
  397. }
  398. function bar()
  399. {
  400. var_dump(3);
  401. }
  402. }
  403. EOF
  404. ];
  405. yield 'PHP 4 parent' => [
  406. <<<'EOF'
  407. <?php
  408. class Foo extends FooParEnt
  409. {
  410. /**
  411. * Constructor
  412. */
  413. function __construct($bar)
  414. {
  415. parent::__construct(1);
  416. var_dump(9);
  417. }
  418. function bar()
  419. {
  420. var_dump(3);
  421. }
  422. }
  423. EOF,
  424. <<<'EOF'
  425. <?php
  426. class Foo extends FooParEnt
  427. {
  428. /**
  429. * Constructor
  430. */
  431. function Foo($bar)
  432. {
  433. parent::FooPaRent(1);
  434. var_dump(9);
  435. }
  436. function bar()
  437. {
  438. var_dump(3);
  439. }
  440. }
  441. EOF
  442. ];
  443. yield 'PHP 4 parent init' => [
  444. <<<'EOF'
  445. <?php
  446. class Foo extends FooParent
  447. {
  448. /**
  449. * Constructor
  450. */
  451. function __construct($bar)
  452. {
  453. parent::init(1);
  454. var_dump(9);
  455. }
  456. function bar()
  457. {
  458. var_dump(3);
  459. }
  460. }
  461. EOF,
  462. <<<'EOF'
  463. <?php
  464. class Foo extends FooParent
  465. {
  466. /**
  467. * Constructor
  468. */
  469. function Foo($bar)
  470. {
  471. parent::init(1);
  472. var_dump(9);
  473. }
  474. function bar()
  475. {
  476. var_dump(3);
  477. }
  478. }
  479. EOF
  480. ];
  481. yield 'mixed parent' => [
  482. <<<'EOF'
  483. <?php
  484. class Foo extends FooParent
  485. {
  486. /**
  487. * Constructor
  488. */
  489. function __construcT($bar)
  490. {
  491. parent::__construct(1);
  492. var_dump(9);
  493. }
  494. function bar()
  495. {
  496. var_dump(3);
  497. }
  498. }
  499. EOF,
  500. <<<'EOF'
  501. <?php
  502. class Foo extends FooParent
  503. {
  504. /**
  505. * Constructor
  506. */
  507. function __construcT($bar)
  508. {
  509. parent::FooParenT(1);
  510. var_dump(9);
  511. }
  512. function bar()
  513. {
  514. var_dump(3);
  515. }
  516. }
  517. EOF
  518. ];
  519. yield 'mixed parent 2' => [
  520. <<<'EOF'
  521. <?php
  522. class Foo extends FooParent
  523. {
  524. /**
  525. * Constructor
  526. */
  527. function __construcT($bar)
  528. {
  529. parent::__construct(1);
  530. var_dump(9);
  531. }
  532. function bar()
  533. {
  534. var_dump(3);
  535. }
  536. }
  537. EOF,
  538. <<<'EOF'
  539. <?php
  540. class Foo extends FooParent
  541. {
  542. /**
  543. * Constructor
  544. */
  545. function __construcT($bar)
  546. {
  547. $this->FooParenT(1);
  548. var_dump(9);
  549. }
  550. function bar()
  551. {
  552. var_dump(3);
  553. }
  554. }
  555. EOF
  556. ];
  557. yield 'parent other' => [
  558. <<<'EOF'
  559. <?php
  560. class Foo extends FooParent
  561. {
  562. /**
  563. * Constructor
  564. */
  565. function __construct($bar)
  566. {
  567. parent::__construct(1);
  568. var_dump(9);
  569. }
  570. function bar()
  571. {
  572. var_dump(3);
  573. }
  574. }
  575. EOF,
  576. <<<'EOF'
  577. <?php
  578. class Foo extends FooParent
  579. {
  580. /**
  581. * Constructor
  582. */
  583. function Foo($bar)
  584. {
  585. $this->FooParent(1);
  586. var_dump(9);
  587. }
  588. function bar()
  589. {
  590. var_dump(3);
  591. }
  592. }
  593. EOF
  594. ];
  595. yield 'parent other 2' => [
  596. <<<'EOF'
  597. <?php
  598. class Foo extends FooParent
  599. {
  600. /**
  601. * Constructor
  602. */
  603. function __construct($bar)
  604. {
  605. parent::__construct(1);
  606. var_dump(9);
  607. }
  608. function bar()
  609. {
  610. var_dump(3);
  611. }
  612. }
  613. EOF,
  614. <<<'EOF'
  615. <?php
  616. class Foo extends FooParent
  617. {
  618. /**
  619. * Constructor
  620. */
  621. function Foo($bar)
  622. {
  623. FooParent::FooParent(1);
  624. var_dump(9);
  625. }
  626. function bar()
  627. {
  628. var_dump(3);
  629. }
  630. }
  631. EOF
  632. ];
  633. yield 'class with anonymous' => [
  634. <<<'EOF'
  635. <?php
  636. class Foo {
  637. private $bar;
  638. public function __construct()
  639. {
  640. $this->bar = function () {};
  641. }
  642. }
  643. EOF,
  644. <<<'EOF'
  645. <?php
  646. class Foo {
  647. private $bar;
  648. public function Foo()
  649. {
  650. $this->bar = function () {};
  651. }
  652. }
  653. EOF
  654. ];
  655. yield 'class with comments' => [
  656. <<<'EOF'
  657. <?php
  658. class /* test */
  659. // another
  660. Foo {
  661. public function /* test */ __construct($param) {
  662. }
  663. }
  664. EOF,
  665. <<<'EOF'
  666. <?php
  667. class /* test */
  668. // another
  669. Foo {
  670. public function /* test */ Foo($param) {
  671. }
  672. }
  673. EOF
  674. ];
  675. yield 'alpha beta' => [<<<'EOF'
  676. <?php
  677. class Foo
  678. {
  679. public function Foo()
  680. {
  681. echo 'alpha';
  682. }
  683. public function __construct()
  684. {
  685. echo 'beta';
  686. }
  687. }
  688. EOF];
  689. yield 'alpha beta trick 1' => [<<<'EOF'
  690. <?php
  691. class Foo
  692. {
  693. public function Foo()
  694. {
  695. // This is not $this->__construct()
  696. echo 'alpha';
  697. }
  698. public function __construct()
  699. {
  700. echo 'beta';
  701. }
  702. }
  703. EOF];
  704. yield 'alpha beta trick 2' => [<<<'EOF'
  705. <?php
  706. class Foo
  707. {
  708. public function Foo()
  709. {
  710. echo 'alpha';
  711. }
  712. public function __construct()
  713. {
  714. // This is not $this->Foo()
  715. echo 'beta';
  716. }
  717. }
  718. EOF];
  719. yield 'alpha beta trick 3' => [<<<'EOF'
  720. <?php
  721. class Foo
  722. {
  723. public function Foo()
  724. {
  725. echo 'alpha';
  726. /* yeah, ok let's construct it anyway */
  727. $this->__construct();
  728. }
  729. public function __construct()
  730. {
  731. echo 'beta';
  732. }
  733. }
  734. EOF];
  735. yield 'alpha beta trick 4 with another class' => [
  736. <<<'EOF'
  737. <?php
  738. class Foo
  739. {
  740. public function Foo()
  741. {
  742. echo 'alpha';
  743. }
  744. public function __construct()
  745. {
  746. $this->Foo();
  747. // Do something more!
  748. echo 'beta';
  749. }
  750. }
  751. Class Bar
  752. {
  753. function __construct()
  754. {
  755. $this->foo = 1;
  756. }
  757. }
  758. EOF,
  759. <<<'EOF'
  760. <?php
  761. class Foo
  762. {
  763. public function Foo()
  764. {
  765. echo 'alpha';
  766. }
  767. public function __construct()
  768. {
  769. $this->Foo();
  770. // Do something more!
  771. echo 'beta';
  772. }
  773. }
  774. Class Bar
  775. {
  776. function bar()
  777. {
  778. $this->foo = 1;
  779. }
  780. }
  781. EOF
  782. ];
  783. yield 'abstract' => [<<<'EOF'
  784. <?php
  785. abstract class Foo
  786. {
  787. abstract function Foo();
  788. }
  789. EOF];
  790. yield 'abstract trick' => [<<<'EOF'
  791. <?php
  792. abstract class Foo
  793. {
  794. abstract public function Foo();
  795. public function bar()
  796. {
  797. // This is messed up, I know
  798. $this->__construct();
  799. }
  800. public function __construct()
  801. {
  802. $this->baz = 1;
  803. }
  804. }
  805. EOF];
  806. yield 'parent multiple classes' => [
  807. <<<'EOF'
  808. <?php
  809. class Class1 extends Parent1
  810. {
  811. function __construct($foo)
  812. {
  813. parent::__construct();
  814. echo "something";
  815. }
  816. }
  817. class Class2 extends Parent2
  818. {
  819. function __construct($foo)
  820. {
  821. echo "something";
  822. }
  823. }
  824. ?>
  825. EOF,
  826. <<<'EOF'
  827. <?php
  828. class Class1 extends Parent1
  829. {
  830. function __construct($foo)
  831. {
  832. $this->Parent1();
  833. echo "something";
  834. }
  835. }
  836. class Class2 extends Parent2
  837. {
  838. function __construct($foo)
  839. {
  840. echo "something";
  841. }
  842. }
  843. ?>
  844. EOF
  845. ];
  846. yield 'infinite recursion' => [
  847. <<<'EOF'
  848. <?php
  849. class Parent1
  850. {
  851. function __construct()
  852. {
  853. echo "foobar";
  854. }
  855. }
  856. class Class1 extends Parent1
  857. {
  858. function __construct($foo)
  859. {
  860. parent::__construct();
  861. echo "something";
  862. }
  863. }
  864. ?>
  865. EOF,
  866. <<<'EOF'
  867. <?php
  868. class Parent1
  869. {
  870. function __construct()
  871. {
  872. echo "foobar";
  873. }
  874. }
  875. class Class1 extends Parent1
  876. {
  877. function Class1($foo)
  878. {
  879. $this->__construct();
  880. echo "something";
  881. }
  882. }
  883. ?>
  884. EOF
  885. ];
  886. }
  887. /**
  888. * @dataProvider provideFix80Cases
  889. *
  890. * @requires PHP 8.0
  891. */
  892. public function testFix80(string $expected, ?string $input = null): void
  893. {
  894. $this->doTest($expected, $input);
  895. }
  896. public static function provideFix80Cases(): iterable
  897. {
  898. yield [
  899. <<<'EOF'
  900. <?php
  901. class Foo
  902. {
  903. public function __construct($bar,)
  904. {
  905. var_dump(1);
  906. }
  907. }
  908. EOF
  909. ,
  910. <<<'EOF'
  911. <?php
  912. class Foo
  913. {
  914. public function Foo($bar,)
  915. {
  916. var_dump(1);
  917. }
  918. }
  919. EOF
  920. ];
  921. yield [
  922. '<?php
  923. class Foo
  924. {
  925. public function __construct()
  926. {
  927. }
  928. }',
  929. '<?php
  930. class Foo
  931. {
  932. public function Foo()
  933. {
  934. }
  935. }',
  936. ];
  937. yield [
  938. '<?php
  939. class Foo
  940. {
  941. public function __construct()
  942. {
  943. $this?->__construct();
  944. }
  945. }',
  946. '<?php
  947. class Foo
  948. {
  949. public function Foo()
  950. {
  951. $this?->__construct();
  952. }
  953. }',
  954. ];
  955. yield [
  956. '<?php
  957. class Foo extends Bar
  958. {
  959. public function __construct()
  960. {
  961. parent::__construct();
  962. }
  963. }',
  964. '<?php
  965. class Foo extends Bar
  966. {
  967. public function Foo()
  968. {
  969. $this?->Bar();
  970. }
  971. }',
  972. ];
  973. yield [
  974. '<?php
  975. class Foo
  976. {
  977. /**
  978. * Constructor
  979. */
  980. public function __construct($bar = 1, $baz = null)
  981. {
  982. var_dump(1);
  983. }
  984. }
  985. ',
  986. '<?php
  987. class Foo
  988. {
  989. /**
  990. * Constructor
  991. */
  992. public function __construct($bar = 1, $baz = null)
  993. {
  994. var_dump(1);
  995. }
  996. /**
  997. * PHP-4 Constructor
  998. */
  999. function Foo($bar = 1, $baz = null)
  1000. {
  1001. $this?->__construct($bar, $baz);
  1002. }
  1003. }
  1004. ',
  1005. ];
  1006. }
  1007. }