PhpdocToCommentFixerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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\Phpdoc;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Ceeram <ceeram@cakephp.org>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Phpdoc\PhpdocToCommentFixer
  20. */
  21. final class PhpdocToCommentFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideDocblocksCases
  25. */
  26. public function testFix(string $expected, ?string $input = null): void
  27. {
  28. $this->doTest($expected, $input);
  29. }
  30. /**
  31. * @dataProvider provideTraitsCases
  32. */
  33. public function testFixTraits(string $expected, ?string $input = null): void
  34. {
  35. $this->doTest($expected, $input);
  36. }
  37. public function provideDocblocksCases()
  38. {
  39. $cases = [];
  40. $cases[] = [
  41. '<?php
  42. /**
  43. * Do not convert this
  44. */
  45. namespace Docs;
  46. /**
  47. * Do not convert this
  48. */
  49. class DocBlocks
  50. {
  51. /**
  52. * Do not convert this
  53. */
  54. const STRUCTURAL = true;
  55. /**
  56. * Do not convert this
  57. */
  58. protected $indent = false;
  59. /**
  60. * Do not convert this
  61. */
  62. var $oldPublicStyle;
  63. /**
  64. * Do not convert this
  65. */
  66. public function test() {}
  67. /**
  68. * Do not convert this
  69. */
  70. private function testPrivate() {}
  71. /**
  72. * Do not convert this
  73. */
  74. function testNoVisibility() {}
  75. }',
  76. ];
  77. $cases[] = [
  78. '<?php namespace Docs;
  79. /**
  80. * Do not convert this
  81. */
  82. /**
  83. * Do not convert this
  84. */
  85. class DocBlocks{}
  86. ',
  87. ];
  88. $cases[] = [
  89. '<?php
  90. /**
  91. * Do not convert this
  92. */
  93. namespace Foo;
  94. ',
  95. ];
  96. $cases[] = [
  97. '<?php
  98. $first = true;// needed because by default first docblock is never fixed.
  99. /**
  100. * Do not convert this
  101. */
  102. abstract class DocBlocks
  103. {
  104. /**
  105. * Do not convert this
  106. */
  107. abstract public function test();
  108. }',
  109. ];
  110. $cases[] = [
  111. '<?php
  112. $first = true;// needed because by default first docblock is never fixed.
  113. /**
  114. * Do not convert this
  115. */
  116. interface DocBlocks
  117. {
  118. public function test();
  119. }',
  120. ];
  121. $cases[] = [
  122. '<?php
  123. namespace NS;
  124. /**
  125. * Do not
  126. */
  127. final class Foo
  128. {
  129. }',
  130. ];
  131. $cases[] = [
  132. '<?php
  133. $first = true;// needed because by default first docblock is never fixed.
  134. /**
  135. * Do not convert this
  136. */
  137. require "require.php";
  138. /**
  139. * Do not convert this
  140. */
  141. require_once "require_once.php";
  142. /**
  143. * Do not convert this
  144. */
  145. include "include.php";
  146. /**
  147. * Do not convert this
  148. */
  149. include_once "include_once.php";
  150. ',
  151. ];
  152. $cases[] = [
  153. '<?php
  154. $first = true;// needed because by default first docblock is never fixed.
  155. /**
  156. * Do not convert this
  157. *
  158. * @var int
  159. */
  160. $a = require "require.php";
  161. /**
  162. * Do not convert this
  163. *
  164. * @var int
  165. */
  166. $b = require_once "require_once.php";
  167. /**
  168. * Do not convert this
  169. *
  170. * @var int
  171. */
  172. $c = include "include.php";
  173. /**
  174. * Do not convert this
  175. *
  176. * @var int
  177. */
  178. $d = include_once "include_once.php";
  179. /**
  180. * @var Composer\Autoload\ClassLoader $loader
  181. */
  182. $loader = require_once __DIR__."/vendor/autoload.php";
  183. ',
  184. ];
  185. $cases[] = [
  186. '<?php
  187. $first = true;// needed because by default first docblock is never fixed.
  188. /**
  189. * @var ClassLoader $loader
  190. */
  191. $loader = require_once __DIR__."/../app/autoload.php";
  192. ',
  193. ];
  194. $cases[] = [
  195. '<?php
  196. $first = true;// needed because by default first docblock is never fixed.
  197. /**
  198. * Do not convert this
  199. *
  200. * @var Foo
  201. */
  202. $foo = createFoo();
  203. ',
  204. ];
  205. $cases[] = [
  206. '<?php
  207. $first = true;// needed because by default first docblock is never fixed.
  208. /**
  209. * Do not convert this
  210. *
  211. * @var bool $local
  212. */
  213. $local = true;
  214. ',
  215. ];
  216. $cases[] = [
  217. '<?php
  218. $first = true;// needed because by default first docblock is never fixed.
  219. /**
  220. * Comment
  221. */
  222. $local = true;
  223. ',
  224. ];
  225. $cases[] = [
  226. '<?php
  227. $first = true;// needed because by default first docblock is never fixed.
  228. /** @var \Sqlite3 $sqlite */
  229. foreach($connections as $sqlite) {
  230. $sqlite->open($path);
  231. }',
  232. ];
  233. $cases[] = [
  234. '<?php
  235. $first = true;// needed because by default first docblock is never fixed.
  236. /** @var \Sqlite3 $sqlite */
  237. foreach($connections as $key => $sqlite) {
  238. $sqlite->open($path);
  239. }',
  240. ];
  241. $cases[] = [
  242. '<?php
  243. $first = true;// needed because by default first docblock is never fixed.
  244. /** @var int $key */
  245. foreach($connections as $key => $sqlite) {
  246. $sqlite->open($path);
  247. }',
  248. ];
  249. $cases[] = [
  250. '<?php
  251. $first = true;// needed because by default first docblock is never fixed.
  252. /* This should not be a docblock */
  253. foreach($connections as $key => $sqlite) {
  254. $sqlite->open($path);
  255. }',
  256. '<?php
  257. $first = true;// needed because by default first docblock is never fixed.
  258. /** This should not be a docblock */
  259. foreach($connections as $key => $sqlite) {
  260. $sqlite->open($path);
  261. }',
  262. ];
  263. $cases[] = [
  264. '<?php
  265. $first = true;// needed because by default first docblock is never fixed.
  266. /* there should be no docblock here */
  267. $sqlite1->open($path);
  268. ',
  269. '<?php
  270. $first = true;// needed because by default first docblock is never fixed.
  271. /** there should be no docblock here */
  272. $sqlite1->open($path);
  273. ',
  274. ];
  275. $cases[] = [
  276. '<?php
  277. $first = true;// needed because by default first docblock is never fixed.
  278. /* there should be no docblock here */
  279. $i++;
  280. ',
  281. '<?php
  282. $first = true;// needed because by default first docblock is never fixed.
  283. /** there should be no docblock here */
  284. $i++;
  285. ',
  286. ];
  287. $cases[] = [
  288. '<?php
  289. $first = true;// needed because by default first docblock is never fixed.
  290. /** @var int $index */
  291. $index = $a[\'number\'];
  292. ',
  293. ];
  294. $cases[] = [
  295. '<?php
  296. $first = true;// needed because by default first docblock is never fixed.
  297. /** @var string $two */
  298. list($one, $two) = explode("," , $csvLines);
  299. ',
  300. ];
  301. $cases[] = [
  302. '<?php
  303. $first = true;// needed because by default first docblock is never fixed.
  304. /* This should be a comment */
  305. list($one, $two) = explode("," , $csvLines);
  306. ',
  307. '<?php
  308. $first = true;// needed because by default first docblock is never fixed.
  309. /** This should be a comment */
  310. list($one, $two) = explode("," , $csvLines);
  311. ',
  312. ];
  313. $cases[] = [
  314. '<?php
  315. $first = true;// needed because by default first docblock is never fixed.
  316. /** @var int $index */
  317. foreach ($foo->getPairs($c->bar(), $bar) as $index => list($a, $b)) {
  318. // Do something with $index, $a and $b
  319. }
  320. /** @var \Closure $value */
  321. if (!$value = $this->getValue()) {
  322. return false;
  323. }
  324. /** @var string $name */
  325. switch ($name = $this->getName()) {
  326. case "John":
  327. return false;
  328. case "Jane":
  329. return true;
  330. }
  331. /** @var string $content */
  332. while ($content = $this->getContent()) {
  333. $name .= $content;
  334. }
  335. /** @var int $size */
  336. for($i = 0, $size = count($people); $i < $size; ++$i) {
  337. $people[$i][\'salt\'] = mt_rand(000000, 999999);
  338. }',
  339. ];
  340. $cases[] = [
  341. '<?php
  342. $first = true;// needed because by default first docblock is never fixed.
  343. /* @var int $wrong */
  344. foreach ($foo->getPairs($c->bar(), $bar) as $index => list($a, $b)) {
  345. // Do something with $index, $a and $b
  346. }
  347. /* @var \Closure $notValue */
  348. if (!$value = $this->getValue()) {
  349. return false;
  350. }
  351. /* @var string $notName */
  352. switch ($name = $this->getName()) {
  353. case "John":
  354. return false;
  355. case "Jane":
  356. return true;
  357. }
  358. /* @var string $notContent */
  359. while ($content = $this->getContent()) {
  360. $name .= $content;
  361. }
  362. /* @var int $notSize */
  363. for($i = 0, $size = count($people); $i < $size; ++$i) {
  364. $people[$i][\'salt\'] = mt_rand(000000, 999999);
  365. }',
  366. '<?php
  367. $first = true;// needed because by default first docblock is never fixed.
  368. /** @var int $wrong */
  369. foreach ($foo->getPairs($c->bar(), $bar) as $index => list($a, $b)) {
  370. // Do something with $index, $a and $b
  371. }
  372. /** @var \Closure $notValue */
  373. if (!$value = $this->getValue()) {
  374. return false;
  375. }
  376. /** @var string $notName */
  377. switch ($name = $this->getName()) {
  378. case "John":
  379. return false;
  380. case "Jane":
  381. return true;
  382. }
  383. /** @var string $notContent */
  384. while ($content = $this->getContent()) {
  385. $name .= $content;
  386. }
  387. /** @var int $notSize */
  388. for($i = 0, $size = count($people); $i < $size; ++$i) {
  389. $people[$i][\'salt\'] = mt_rand(000000, 999999);
  390. }',
  391. ];
  392. $cases[] = [
  393. '<?php
  394. /* This should be a comment */
  395. ',
  396. '<?php
  397. /** This should be a comment */
  398. ',
  399. ];
  400. $cases[] = [
  401. '<?php
  402. /**
  403. * This is a page level docblock should stay untouched
  404. */
  405. echo "Some string";
  406. ',
  407. ];
  408. $cases[] = [
  409. '<?php
  410. $first = true;// needed because by default first docblock is never fixed.
  411. /** @var \NumberFormatter $formatter */
  412. static $formatter;
  413. ',
  414. ];
  415. $cases[] = [
  416. '<?php
  417. $first = true;// needed because by default first docblock is never fixed.
  418. function getNumberFormatter()
  419. {
  420. /** @var \NumberFormatter $formatter */
  421. static $formatter;
  422. }
  423. ',
  424. ];
  425. $cases[] = [
  426. '<?php
  427. class A
  428. {
  429. public function b()
  430. {
  431. /** @var int $c */
  432. print($c = 0);
  433. }
  434. }
  435. ',
  436. ];
  437. $cases[] = ['<?php
  438. /** header */
  439. echo 123;
  440. /** @var int $bar1 */
  441. (print($bar1 = 0));
  442. ',
  443. ];
  444. $cases[] = [
  445. '<?php
  446. /** header */
  447. echo 123;
  448. /** @var ClassLoader $loader */
  449. $loader = require __DIR__.\'/../vendor/autoload.php\';
  450. ',
  451. ];
  452. return $cases;
  453. }
  454. public function provideTraitsCases()
  455. {
  456. return [
  457. [
  458. '<?php
  459. $first = true;// needed because by default first docblock is never fixed.
  460. /**
  461. * Do not convert this
  462. */
  463. trait DocBlocks
  464. {
  465. public function test() {}
  466. }',
  467. ],
  468. ];
  469. }
  470. /**
  471. * @dataProvider provideFix70Cases
  472. * @requires PHP 7.0
  473. */
  474. public function testFix70(string $expected, ?string $input = null): void
  475. {
  476. $this->doTest($expected, $input);
  477. }
  478. public function provideFix70Cases()
  479. {
  480. return [
  481. [
  482. '<?php
  483. /** header */
  484. echo 123;
  485. /** @var User $bar3 */
  486. ($bar3 = tmp())->doSomething();
  487. /** @var Session $session */ # test
  488. $session = new Session();
  489. ',
  490. ],
  491. ];
  492. }
  493. /**
  494. * @dataProvider provideFix71Cases
  495. * @requires PHP 7.1
  496. */
  497. public function testFix71(string $expected, ?string $input = null): void
  498. {
  499. $this->doTest($expected, $input);
  500. }
  501. public function provideFix71Cases()
  502. {
  503. return [
  504. [
  505. '<?php
  506. $first = true;// needed because by default first docblock is never fixed.
  507. /** @var int $a */
  508. [$a] = $b;
  509. /* @var int $c */
  510. [$a] = $c;
  511. ',
  512. '<?php
  513. $first = true;// needed because by default first docblock is never fixed.
  514. /** @var int $a */
  515. [$a] = $b;
  516. /** @var int $c */
  517. [$a] = $c;
  518. ',
  519. ],
  520. [
  521. '<?php
  522. $first = true;// needed because by default first docblock is never fixed.
  523. /**
  524. * @var int $a
  525. */
  526. [$a] = $b;
  527. ',
  528. ],
  529. ];
  530. }
  531. /**
  532. * @dataProvider provideFix74Cases
  533. * @requires PHP 7.4
  534. */
  535. public function testFix74(string $expected, ?string $input = null): void
  536. {
  537. $this->doTest($expected, $input);
  538. }
  539. public function provideFix74Cases()
  540. {
  541. return [
  542. [
  543. '<?php
  544. class Foo {
  545. /**
  546. * Do not convert this
  547. */
  548. private int $foo;
  549. }',
  550. ],
  551. [
  552. '<?php
  553. class Foo {
  554. /**
  555. * Do not convert this
  556. */
  557. protected ?string $foo;
  558. }',
  559. ],
  560. [
  561. '<?php
  562. class Foo {
  563. /**
  564. * Do not convert this
  565. */
  566. public ? float $foo;
  567. }',
  568. ],
  569. [
  570. '<?php
  571. class Foo {
  572. /**
  573. * Do not convert this
  574. */
  575. var ? Foo\Bar $foo;
  576. }',
  577. ],
  578. [
  579. '<?php
  580. class Foo {
  581. /**
  582. * Do not convert this
  583. */
  584. var ? array $foo;
  585. }',
  586. ],
  587. ];
  588. }
  589. /**
  590. * @dataProvider provideFix80Cases
  591. * @requires PHP 8.0
  592. */
  593. public function testFix80(string $expected, ?string $input = null): void
  594. {
  595. $this->doTest($expected, $input);
  596. }
  597. public function provideFix80Cases()
  598. {
  599. return [
  600. [
  601. '<?php
  602. /**
  603. * @Annotation
  604. */
  605. #[CustomAnnotationA]
  606. Class MyAnnotation3
  607. {
  608. /**
  609. * @Annotation
  610. */
  611. #[CustomAnnotationB]
  612. #[CustomAnnotationC]
  613. public function foo() {}
  614. /**
  615. * @Annotation
  616. */
  617. #[CustomAnnotationD]
  618. public $var;
  619. /*
  620. * end of class
  621. */
  622. }',
  623. '<?php
  624. /**
  625. * @Annotation
  626. */
  627. #[CustomAnnotationA]
  628. Class MyAnnotation3
  629. {
  630. /**
  631. * @Annotation
  632. */
  633. #[CustomAnnotationB]
  634. #[CustomAnnotationC]
  635. public function foo() {}
  636. /**
  637. * @Annotation
  638. */
  639. #[CustomAnnotationD]
  640. public $var;
  641. /**
  642. * end of class
  643. */
  644. }',
  645. ],
  646. ];
  647. }
  648. }