PhpdocAlignFixerTest.php 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  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. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @internal
  17. *
  18. * @covers \PhpCsFixer\Fixer\Phpdoc\PhpdocAlignFixer
  19. */
  20. final class PhpdocAlignFixerTest extends AbstractFixerTestCase
  21. {
  22. public function testFix(): void
  23. {
  24. $this->fixer->configure(['tags' => ['param']]);
  25. $expected = <<<'EOF'
  26. <?php
  27. /**
  28. * @param EngineInterface $templating
  29. * @param string $format
  30. * @param int $code An HTTP response status code
  31. * @param bool $debug
  32. * @param mixed &$reference A parameter passed by reference
  33. */
  34. EOF;
  35. $input = <<<'EOF'
  36. <?php
  37. /**
  38. * @param EngineInterface $templating
  39. * @param string $format
  40. * @param int $code An HTTP response status code
  41. * @param bool $debug
  42. * @param mixed &$reference A parameter passed by reference
  43. */
  44. EOF;
  45. $this->doTest($expected, $input);
  46. }
  47. public function testFixLeftAlign(): void
  48. {
  49. $this->fixer->configure(['tags' => ['param'], 'align' => 'left']);
  50. $expected = <<<'EOF'
  51. <?php
  52. /**
  53. * @param EngineInterface $templating
  54. * @param string $format
  55. * @param int $code An HTTP response status code
  56. * @param bool $debug
  57. * @param mixed &$reference A parameter passed by reference
  58. */
  59. EOF;
  60. $input = <<<'EOF'
  61. <?php
  62. /**
  63. * @param EngineInterface $templating
  64. * @param string $format
  65. * @param int $code An HTTP response status code
  66. * @param bool $debug
  67. * @param mixed &$reference A parameter passed by reference
  68. */
  69. EOF;
  70. $this->doTest($expected, $input);
  71. }
  72. public function testFixPartiallyUntyped(): void
  73. {
  74. $this->fixer->configure(['tags' => ['param']]);
  75. $expected = <<<'EOF'
  76. <?php
  77. /**
  78. * @param $id
  79. * @param $parentId
  80. * @param int $websiteId
  81. * @param $position
  82. * @param int[][] $siblings
  83. */
  84. EOF;
  85. $input = <<<'EOF'
  86. <?php
  87. /**
  88. * @param $id
  89. * @param $parentId
  90. * @param int $websiteId
  91. * @param $position
  92. * @param int[][] $siblings
  93. */
  94. EOF;
  95. $this->doTest($expected, $input);
  96. }
  97. public function testFixPartiallyUntypedLeftAlign(): void
  98. {
  99. $this->fixer->configure(['tags' => ['param'], 'align' => 'left']);
  100. $expected = <<<'EOF'
  101. <?php
  102. /**
  103. * @param $id
  104. * @param $parentId
  105. * @param int $websiteId
  106. * @param $position
  107. * @param int[][] $siblings
  108. */
  109. EOF;
  110. $input = <<<'EOF'
  111. <?php
  112. /**
  113. * @param $id
  114. * @param $parentId
  115. * @param int $websiteId
  116. * @param $position
  117. * @param int[][] $siblings
  118. */
  119. EOF;
  120. $this->doTest($expected, $input);
  121. }
  122. public function testFixMultiLineDesc(): void
  123. {
  124. $this->fixer->configure(['tags' => ['param', 'property', 'method']]);
  125. $expected = <<<'EOF'
  126. <?php
  127. /**
  128. * @param EngineInterface $templating
  129. * @param string $format
  130. * @param int $code An HTTP response status code
  131. * See constants
  132. * @param bool $debug
  133. * @param bool $debug See constants
  134. * See constants
  135. * @param mixed &$reference A parameter passed by reference
  136. * @property mixed $foo A foo
  137. * See constants
  138. * @method static baz($bop) A method that does a thing
  139. * It does it well
  140. */
  141. EOF;
  142. $input = <<<'EOF'
  143. <?php
  144. /**
  145. * @param EngineInterface $templating
  146. * @param string $format
  147. * @param int $code An HTTP response status code
  148. * See constants
  149. * @param bool $debug
  150. * @param bool $debug See constants
  151. * See constants
  152. * @param mixed &$reference A parameter passed by reference
  153. * @property mixed $foo A foo
  154. * See constants
  155. * @method static baz($bop) A method that does a thing
  156. * It does it well
  157. */
  158. EOF;
  159. $this->doTest($expected, $input);
  160. }
  161. public function testFixMultiLineDescLeftAlign(): void
  162. {
  163. $this->fixer->configure(['tags' => ['param', 'property', 'method'], 'align' => 'left']);
  164. $expected = <<<'EOF'
  165. <?php
  166. /**
  167. * @param EngineInterface $templating
  168. * @param string $format
  169. * @param int $code An HTTP response status code
  170. * See constants
  171. * @param bool $debug
  172. * @param bool $debug See constants
  173. * See constants
  174. * @param mixed &$reference A parameter passed by reference
  175. * @property mixed $foo A foo
  176. * See constants
  177. * @method static baz($bop) A method that does a thing
  178. * It does it well
  179. */
  180. EOF;
  181. $input = <<<'EOF'
  182. <?php
  183. /**
  184. * @param EngineInterface $templating
  185. * @param string $format
  186. * @param int $code An HTTP response status code
  187. * See constants
  188. * @param bool $debug
  189. * @param bool $debug See constants
  190. * See constants
  191. * @param mixed &$reference A parameter passed by reference
  192. * @property mixed $foo A foo
  193. * See constants
  194. * @method static baz($bop) A method that does a thing
  195. * It does it well
  196. */
  197. EOF;
  198. $this->doTest($expected, $input);
  199. }
  200. public function testFixMultiLineDescWithThrows(): void
  201. {
  202. $this->fixer->configure(['tags' => ['param', 'return', 'throws']]);
  203. $expected = <<<'EOF'
  204. <?php
  205. /**
  206. * @param EngineInterface $templating
  207. * @param string $format
  208. * @param int $code An HTTP response status code
  209. * See constants
  210. * @param bool $debug
  211. * @param bool $debug See constants
  212. * See constants
  213. * @param mixed &$reference A parameter passed by reference
  214. *
  215. * @return Foo description foo
  216. *
  217. * @throws Foo description foo
  218. * description foo
  219. */
  220. EOF;
  221. $input = <<<'EOF'
  222. <?php
  223. /**
  224. * @param EngineInterface $templating
  225. * @param string $format
  226. * @param int $code An HTTP response status code
  227. * See constants
  228. * @param bool $debug
  229. * @param bool $debug See constants
  230. * See constants
  231. * @param mixed &$reference A parameter passed by reference
  232. *
  233. * @return Foo description foo
  234. *
  235. * @throws Foo description foo
  236. * description foo
  237. */
  238. EOF;
  239. $this->doTest($expected, $input);
  240. }
  241. public function testFixMultiLineDescWithThrowsLeftAlign(): void
  242. {
  243. $this->fixer->configure(['tags' => ['param', 'return', 'throws'], 'align' => 'left']);
  244. $expected = <<<'EOF'
  245. <?php
  246. /**
  247. * @param EngineInterface $templating
  248. * @param string $format
  249. * @param int $code An HTTP response status code
  250. * See constants
  251. * @param bool $debug
  252. * @param bool $debug See constants
  253. * See constants
  254. * @param mixed &$reference A parameter passed by reference
  255. *
  256. * @return Foo description foo
  257. *
  258. * @throws Foo description foo
  259. * description foo
  260. */
  261. EOF;
  262. $input = <<<'EOF'
  263. <?php
  264. /**
  265. * @param EngineInterface $templating
  266. * @param string $format
  267. * @param int $code An HTTP response status code
  268. * See constants
  269. * @param bool $debug
  270. * @param bool $debug See constants
  271. * See constants
  272. * @param mixed &$reference A parameter passed by reference
  273. *
  274. * @return Foo description foo
  275. *
  276. * @throws Foo description foo
  277. * description foo
  278. */
  279. EOF;
  280. $this->doTest($expected, $input);
  281. }
  282. public function testFixWithReturnAndThrows(): void
  283. {
  284. $this->fixer->configure(['tags' => ['param', 'throws', 'return']]);
  285. $expected = <<<'EOF'
  286. <?php
  287. /**
  288. * @param EngineInterface $templating
  289. * @param mixed &$reference A parameter passed by reference
  290. * @throws Bar description bar
  291. * @return Foo description foo
  292. */
  293. EOF;
  294. $input = <<<'EOF'
  295. <?php
  296. /**
  297. * @param EngineInterface $templating
  298. * @param mixed &$reference A parameter passed by reference
  299. * @throws Bar description bar
  300. * @return Foo description foo
  301. */
  302. EOF;
  303. $this->doTest($expected, $input);
  304. }
  305. /**
  306. * References the issue #55 on github issue
  307. * https://github.com/FriendsOfPhp/PHP-CS-Fixer/issues/55.
  308. */
  309. public function testFixThreeParamsWithReturn(): void
  310. {
  311. $this->fixer->configure(['tags' => ['param', 'return']]);
  312. $expected = <<<'EOF'
  313. <?php
  314. /**
  315. * @param string $param1
  316. * @param bool $param2 lorem ipsum
  317. * @param string $param3 lorem ipsum
  318. * @return int lorem ipsum
  319. */
  320. EOF;
  321. $input = <<<'EOF'
  322. <?php
  323. /**
  324. * @param string $param1
  325. * @param bool $param2 lorem ipsum
  326. * @param string $param3 lorem ipsum
  327. * @return int lorem ipsum
  328. */
  329. EOF;
  330. $this->doTest($expected, $input);
  331. }
  332. public function testFixOnlyReturn(): void
  333. {
  334. $this->fixer->configure(['tags' => ['return']]);
  335. $expected = <<<'EOF'
  336. <?php
  337. /**
  338. * @return Foo description foo
  339. */
  340. EOF;
  341. $input = <<<'EOF'
  342. <?php
  343. /**
  344. * @return Foo description foo
  345. */
  346. EOF;
  347. $this->doTest($expected, $input);
  348. }
  349. public function testReturnWithDollarThis(): void
  350. {
  351. $this->fixer->configure(['tags' => ['param', 'return']]);
  352. $expected = <<<'EOF'
  353. <?php
  354. /**
  355. * @param Foo $foo
  356. * @return $this
  357. */
  358. EOF;
  359. $input = <<<'EOF'
  360. <?php
  361. /**
  362. * @param Foo $foo
  363. * @return $this
  364. */
  365. EOF;
  366. $this->doTest($expected, $input);
  367. }
  368. public function testCustomAnnotationsStayUntouched(): void
  369. {
  370. $this->fixer->configure(['tags' => ['return']]);
  371. $expected = <<<'EOF'
  372. <?php
  373. /**
  374. * @return string
  375. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  376. */
  377. EOF;
  378. $input = <<<'EOF'
  379. <?php
  380. /**
  381. * @return string
  382. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  383. */
  384. EOF;
  385. $this->doTest($expected, $input);
  386. }
  387. public function testCustomAnnotationsStayUntouched2(): void
  388. {
  389. $this->fixer->configure(['tags' => ['var']]);
  390. $expected = <<<'EOF'
  391. <?php
  392. class X
  393. {
  394. /**
  395. * @var Collection<Value>|Value[]
  396. * @ORM\ManyToMany(
  397. * targetEntity="\Dl\Component\DomainModel\Product\Value\AbstractValue",
  398. * inversedBy="externalAliases"
  399. * )
  400. */
  401. private $values;
  402. }
  403. EOF;
  404. $this->doTest($expected);
  405. }
  406. public function testFixTestLeftAlign(): void
  407. {
  408. $this->fixer->configure(['tags' => ['param'], 'align' => 'left']);
  409. $expected = <<<'EOF'
  410. <?php
  411. /**
  412. * @param int $a
  413. * @param string $b
  414. *
  415. * @dataProvider dataJobCreation
  416. */
  417. EOF;
  418. $input = <<<'EOF'
  419. <?php
  420. /**
  421. * @param int $a
  422. * @param string $b
  423. *
  424. * @dataProvider dataJobCreation
  425. */
  426. EOF;
  427. $this->doTest($expected, $input);
  428. }
  429. public function testFixTest(): void
  430. {
  431. $this->fixer->configure(['tags' => ['param']]);
  432. $expected = <<<'EOF'
  433. <?php
  434. /**
  435. * @param int $a
  436. * @param string|null $b
  437. *
  438. * @dataProvider dataJobCreation
  439. */
  440. EOF;
  441. $input = <<<'EOF'
  442. <?php
  443. /**
  444. * @param int $a
  445. * @param string|null $b
  446. *
  447. * @dataProvider dataJobCreation
  448. */
  449. EOF;
  450. $this->doTest($expected, $input);
  451. }
  452. public function testFixWithVar(): void
  453. {
  454. $this->fixer->configure(['tags' => ['var']]);
  455. $expected = <<<'EOF'
  456. <?php
  457. /**
  458. * @var Type
  459. */
  460. EOF;
  461. $input = <<<'EOF'
  462. <?php
  463. /**
  464. * @var Type
  465. */
  466. EOF;
  467. $this->doTest($expected, $input);
  468. }
  469. public function testFixWithType(): void
  470. {
  471. $this->fixer->configure(['tags' => ['type']]);
  472. $expected = <<<'EOF'
  473. <?php
  474. /**
  475. * @type Type
  476. */
  477. EOF;
  478. $input = <<<'EOF'
  479. <?php
  480. /**
  481. * @type Type
  482. */
  483. EOF;
  484. $this->doTest($expected, $input);
  485. }
  486. public function testFixWithVarAndDescription(): void
  487. {
  488. $this->fixer->configure(['tags' => ['var']]);
  489. $expected = <<<'EOF'
  490. <?php
  491. /**
  492. * This is a variable.
  493. *
  494. * @var Type
  495. */
  496. EOF;
  497. $input = <<<'EOF'
  498. <?php
  499. /**
  500. * This is a variable.
  501. *
  502. * @var Type
  503. */
  504. EOF;
  505. $this->doTest($expected, $input);
  506. }
  507. public function testFixWithVarAndInlineDescription(): void
  508. {
  509. $this->fixer->configure(['tags' => ['var']]);
  510. $expected = <<<'EOF'
  511. <?php
  512. /**
  513. * @var Type This is a variable.
  514. */
  515. EOF;
  516. $input = <<<'EOF'
  517. <?php
  518. /**
  519. * @var Type This is a variable.
  520. */
  521. EOF;
  522. $this->doTest($expected, $input);
  523. }
  524. public function testFixWithTypeAndInlineDescription(): void
  525. {
  526. $this->fixer->configure(['tags' => ['type']]);
  527. $expected = <<<'EOF'
  528. <?php
  529. /**
  530. * @type Type This is a variable.
  531. */
  532. EOF;
  533. $input = <<<'EOF'
  534. <?php
  535. /**
  536. * @type Type This is a variable.
  537. */
  538. EOF;
  539. $this->doTest($expected, $input);
  540. }
  541. public function testRetainsNewLineCharacters(): void
  542. {
  543. $this->fixer->configure(['tags' => ['param']]);
  544. // when we're not modifying a docblock, then line endings shouldn't change
  545. $this->doTest("<?php\r /**\r * @param Example Hello there!\r */\r");
  546. }
  547. public function testMalformedDocBlock(): void
  548. {
  549. $this->fixer->configure(['tags' => ['return']]);
  550. $input = <<<'EOF'
  551. <?php
  552. /**
  553. * @return string
  554. * */
  555. EOF;
  556. $this->doTest($input);
  557. }
  558. public function testDifferentIndentation(): void
  559. {
  560. $this->fixer->configure(['tags' => ['param', 'return']]);
  561. $expected = <<<'EOF'
  562. <?php
  563. /**
  564. * @param int $limit
  565. * @param string $more
  566. *
  567. * @return array
  568. */
  569. /**
  570. * @param int $limit
  571. * @param string $more
  572. *
  573. * @return array
  574. */
  575. EOF;
  576. $input = <<<'EOF'
  577. <?php
  578. /**
  579. * @param int $limit
  580. * @param string $more
  581. *
  582. * @return array
  583. */
  584. /**
  585. * @param int $limit
  586. * @param string $more
  587. *
  588. * @return array
  589. */
  590. EOF;
  591. $this->doTest($expected, $input);
  592. }
  593. public function testDifferentIndentationLeftAlign(): void
  594. {
  595. $this->fixer->configure(['tags' => ['param', 'return'], 'align' => 'left']);
  596. $expected = <<<'EOF'
  597. <?php
  598. /**
  599. * @param int $limit
  600. * @param string $more
  601. *
  602. * @return array
  603. */
  604. /**
  605. * @param int $limit
  606. * @param string $more
  607. *
  608. * @return array
  609. */
  610. EOF;
  611. $input = <<<'EOF'
  612. <?php
  613. /**
  614. * @param int $limit
  615. * @param string $more
  616. *
  617. * @return array
  618. */
  619. /**
  620. * @param int $limit
  621. * @param string $more
  622. *
  623. * @return array
  624. */
  625. EOF;
  626. $this->doTest($expected, $input);
  627. }
  628. /**
  629. * @dataProvider provideMessyWhitespacesCases
  630. */
  631. public function testMessyWhitespaces(array $config, string $expected, string $input, WhitespacesFixerConfig $whitespacesFixerConfig): void
  632. {
  633. $this->fixer->configure($config);
  634. $this->fixer->setWhitespacesConfig($whitespacesFixerConfig);
  635. $this->doTest($expected, $input);
  636. }
  637. public function provideMessyWhitespacesCases()
  638. {
  639. return [
  640. [
  641. ['tags' => ['type']],
  642. "<?php\r\n\t/**\r\n\t * @type Type This is a variable.\r\n\t */",
  643. "<?php\r\n\t/**\r\n\t * @type Type This is a variable.\r\n\t */",
  644. new WhitespacesFixerConfig("\t", "\r\n"),
  645. ],
  646. [
  647. ['tags' => ['param', 'return']],
  648. "<?php\r\n/**\r\n * @param int \$limit\r\n * @param string \$more\r\n *\r\n * @return array\r\n */",
  649. "<?php\r\n/**\r\n * @param int \$limit\r\n * @param string \$more\r\n *\r\n * @return array\r\n */",
  650. new WhitespacesFixerConfig("\t", "\r\n"),
  651. ],
  652. [
  653. [],
  654. "<?php\r\n/**\r\n * @param int \$limit\r\n * @param string \$more\r\n *\r\n * @return array\r\n */",
  655. "<?php\r\n/**\r\n * @param int \$limit\r\n * @param string \$more\r\n *\r\n * @return array\r\n */",
  656. new WhitespacesFixerConfig("\t", "\r\n"),
  657. ],
  658. [
  659. [],
  660. "<?php\n/**\n * @param int \$a\n * @param int \$b\n * ABC\n */",
  661. "<?php\n/**\n * @param int \$a\n * @param int \$b\n * ABC\n */",
  662. new WhitespacesFixerConfig(' ', "\n"),
  663. ],
  664. [
  665. [],
  666. "<?php\r\n/**\r\n * @param int \$z\r\n * @param int \$b\r\n * XYZ\r\n */",
  667. "<?php\r\n/**\r\n * @param int \$z\r\n * @param int \$b\r\n * XYZ\r\n */",
  668. new WhitespacesFixerConfig(' ', "\r\n"),
  669. ],
  670. ];
  671. }
  672. public function testCanFixBadFormatted(): void
  673. {
  674. $this->fixer->configure(['tags' => ['var']]);
  675. $expected = "<?php\n /**\n * @var Foo */\n";
  676. $this->doTest($expected);
  677. }
  678. public function testFixUnicode(): void
  679. {
  680. $this->fixer->configure(['tags' => ['param', 'return']]);
  681. $expected = <<<'EOF'
  682. <?php
  683. /**
  684. * Method test.
  685. *
  686. * @param int $foobar Description
  687. * @param string $foo Description
  688. * @param mixed $bar Description word_with_ą
  689. * @param int|null $test Description
  690. */
  691. $a = 1;
  692. /**
  693. * @return string
  694. * @SuppressWarnings(PHPMD.UnusedLocalVariable) word_with_ą
  695. */
  696. $b = 1;
  697. EOF;
  698. $input = <<<'EOF'
  699. <?php
  700. /**
  701. * Method test.
  702. *
  703. * @param int $foobar Description
  704. * @param string $foo Description
  705. * @param mixed $bar Description word_with_ą
  706. * @param int|null $test Description
  707. */
  708. $a = 1;
  709. /**
  710. * @return string
  711. * @SuppressWarnings(PHPMD.UnusedLocalVariable) word_with_ą
  712. */
  713. $b = 1;
  714. EOF;
  715. $this->doTest($expected, $input);
  716. }
  717. public function testDoesAlignPropertyByDefault(): void
  718. {
  719. $expected = <<<'EOF'
  720. <?php
  721. /**
  722. * @param int $foobar Description
  723. * @return int
  724. * @throws Exception
  725. * @var FooBar
  726. * @type BarFoo
  727. * @property string $foo Hello World
  728. */
  729. EOF;
  730. $input = <<<'EOF'
  731. <?php
  732. /**
  733. * @param int $foobar Description
  734. * @return int
  735. * @throws Exception
  736. * @var FooBar
  737. * @type BarFoo
  738. * @property string $foo Hello World
  739. */
  740. EOF;
  741. $this->doTest($expected, $input);
  742. }
  743. public function testAlignsProperty(): void
  744. {
  745. $this->fixer->configure(['tags' => ['param', 'property', 'return', 'throws', 'type', 'var']]);
  746. $expected = <<<'EOF'
  747. <?php
  748. /**
  749. * @param int $foobar Description
  750. * @return int
  751. * @throws Exception
  752. * @var FooBar
  753. * @type BarFoo
  754. * @property string $foo Hello World
  755. */
  756. EOF;
  757. $input = <<<'EOF'
  758. <?php
  759. /**
  760. * @param int $foobar Description
  761. * @return int
  762. * @throws Exception
  763. * @var FooBar
  764. * @type BarFoo
  765. * @property string $foo Hello World
  766. */
  767. EOF;
  768. $this->doTest($expected, $input);
  769. }
  770. public function testDoesAlignMethodByDefault(): void
  771. {
  772. $expected = <<<'EOF'
  773. <?php
  774. /**
  775. * @param int $foobar Description
  776. * @return int
  777. * @throws Exception
  778. * @var FooBar
  779. * @type BarFoo
  780. * @method string foo(string $bar) Hello World
  781. */
  782. EOF;
  783. $input = <<<'EOF'
  784. <?php
  785. /**
  786. * @param int $foobar Description
  787. * @return int
  788. * @throws Exception
  789. * @var FooBar
  790. * @type BarFoo
  791. * @method string foo(string $bar) Hello World
  792. */
  793. EOF;
  794. $this->doTest($expected, $input);
  795. }
  796. public function testAlignsMethod(): void
  797. {
  798. $this->fixer->configure(['tags' => ['param', 'method', 'return', 'throws', 'type', 'var']]);
  799. $expected = <<<'EOF'
  800. <?php
  801. /**
  802. * @param int $foobar Description
  803. * @return int
  804. * @throws Exception
  805. * @var FooBar
  806. * @type BarFoo
  807. * @method int foo(string $bar, string ...$things, int &$baz) Description
  808. */
  809. EOF;
  810. $input = <<<'EOF'
  811. <?php
  812. /**
  813. * @param int $foobar Description
  814. * @return int
  815. * @throws Exception
  816. * @var FooBar
  817. * @type BarFoo
  818. * @method int foo(string $bar, string ...$things, int &$baz) Description
  819. */
  820. EOF;
  821. $this->doTest($expected, $input);
  822. }
  823. public function testAlignsMethodWithoutParameters(): void
  824. {
  825. $this->fixer->configure(['tags' => ['method', 'property']]);
  826. $expected = <<<'EOF'
  827. <?php
  828. /**
  829. * @property string $foo Desc
  830. * @method int foo() Description
  831. */
  832. EOF;
  833. $input = <<<'EOF'
  834. <?php
  835. /**
  836. * @property string $foo Desc
  837. * @method int foo() Description
  838. */
  839. EOF;
  840. $this->doTest($expected, $input);
  841. }
  842. public function testAlignsMethodWithoutParametersLeftAlign(): void
  843. {
  844. $this->fixer->configure(['tags' => ['method', 'property'], 'align' => 'left']);
  845. $expected = <<<'EOF'
  846. <?php
  847. /**
  848. * @property string $foo Desc
  849. * @method int foo() Description
  850. */
  851. EOF;
  852. $input = <<<'EOF'
  853. <?php
  854. /**
  855. * @property string $foo Desc
  856. * @method int foo() Description
  857. */
  858. EOF;
  859. $this->doTest($expected, $input);
  860. }
  861. public function testDoesNotFormatMethod(): void
  862. {
  863. $this->fixer->configure(['tags' => ['method']]);
  864. $input = <<<'EOF'
  865. <?php
  866. /**
  867. * @method int foo( string $bar ) Description
  868. */
  869. EOF;
  870. $this->doTest($input);
  871. }
  872. public function testAlignsMethodWithoutReturnType(): void
  873. {
  874. $this->fixer->configure(['tags' => ['method', 'property']]);
  875. $expected = <<<'EOF'
  876. <?php
  877. /**
  878. * @property string $foo Desc
  879. * @method int foo() Description
  880. * @method bar() Descrip
  881. */
  882. EOF;
  883. $input = <<<'EOF'
  884. <?php
  885. /**
  886. * @property string $foo Desc
  887. * @method int foo() Description
  888. * @method bar() Descrip
  889. */
  890. EOF;
  891. $this->doTest($expected, $input);
  892. }
  893. public function testAlignsMethodsWithoutReturnType(): void
  894. {
  895. $this->fixer->configure(['tags' => ['method']]);
  896. $expected = <<<'EOF'
  897. <?php
  898. /**
  899. * @method fooBaz() Description
  900. * @method bar(string $foo) Descrip
  901. */
  902. EOF;
  903. $input = <<<'EOF'
  904. <?php
  905. /**
  906. * @method fooBaz() Description
  907. * @method bar(string $foo) Descrip
  908. */
  909. EOF;
  910. $this->doTest($expected, $input);
  911. }
  912. public function testDoesNotAlignWithEmptyConfig(): void
  913. {
  914. $this->fixer->configure(['tags' => []]);
  915. $input = <<<'EOF'
  916. <?php
  917. /**
  918. * @param int $foobar Description
  919. * @return int
  920. * @throws Exception
  921. * @var FooBar
  922. * @type BarFoo
  923. * @property string $foo Hello World
  924. * @method int bar() Description
  925. */
  926. EOF;
  927. $this->doTest($input);
  928. }
  929. /**
  930. * @dataProvider provideVariadicCases
  931. */
  932. public function testVariadicParams(array $config, string $expected, string $input): void
  933. {
  934. $this->fixer->configure($config);
  935. $this->doTest($expected, $input);
  936. }
  937. public function provideVariadicCases()
  938. {
  939. return [
  940. [
  941. ['tags' => ['param']],
  942. '<?php
  943. final class Sample
  944. {
  945. /**
  946. * @param int[] $a A
  947. * @param int &$b B
  948. * @param array ...$c C
  949. */
  950. public function sample2($a, &$b, ...$c)
  951. {
  952. }
  953. }
  954. ',
  955. '<?php
  956. final class Sample
  957. {
  958. /**
  959. * @param int[] $a A
  960. * @param int &$b B
  961. * @param array ...$c C
  962. */
  963. public function sample2($a, &$b, ...$c)
  964. {
  965. }
  966. }
  967. ',
  968. ],
  969. [
  970. ['tags' => ['param']],
  971. '<?php
  972. final class Sample
  973. {
  974. /**
  975. * @param int $a
  976. * @param int $b
  977. * @param array[] ...$c
  978. */
  979. public function sample2($a, $b, ...$c)
  980. {
  981. }
  982. }
  983. ',
  984. '<?php
  985. final class Sample
  986. {
  987. /**
  988. * @param int $a
  989. * @param int $b
  990. * @param array[] ...$c
  991. */
  992. public function sample2($a, $b, ...$c)
  993. {
  994. }
  995. }
  996. ',
  997. ],
  998. [
  999. ['tags' => ['param'], 'align' => 'left'],
  1000. '<?php
  1001. final class Sample
  1002. {
  1003. /**
  1004. * @param int $a
  1005. * @param int $b
  1006. * @param array[] ...$c
  1007. */
  1008. public function sample2($a, $b, ...$c)
  1009. {
  1010. }
  1011. }
  1012. ',
  1013. '<?php
  1014. final class Sample
  1015. {
  1016. /**
  1017. * @param int $a
  1018. * @param int $b
  1019. * @param array[] ...$c
  1020. */
  1021. public function sample2($a, $b, ...$c)
  1022. {
  1023. }
  1024. }
  1025. ',
  1026. ],
  1027. [
  1028. ['tags' => ['property', 'property-read', 'property-write']],
  1029. '<?php
  1030. /**
  1031. * @property string $myMagicProperty
  1032. * @property-read string $myMagicReadyProperty
  1033. * @property-write string $myMagicWriteProperty
  1034. */
  1035. class Foo {}
  1036. ',
  1037. '<?php
  1038. /**
  1039. * @property string $myMagicProperty
  1040. * @property-read string $myMagicReadyProperty
  1041. * @property-write string $myMagicWriteProperty
  1042. */
  1043. class Foo {}
  1044. ',
  1045. ],
  1046. ];
  1047. }
  1048. /**
  1049. * @dataProvider provideInvalidPhpdocCases
  1050. */
  1051. public function testInvalidPhpdocsAreUnchanged(array $config, string $input): void
  1052. {
  1053. $this->fixer->configure($config);
  1054. $this->doTest($input);
  1055. }
  1056. public function provideInvalidPhpdocCases()
  1057. {
  1058. return [
  1059. [
  1060. ['tags' => ['param', 'return', 'throws', 'type', 'var']],
  1061. '<?php
  1062. /**
  1063. * @ Security("is_granted(\'CANCEL\', giftCard)")
  1064. */
  1065. ',
  1066. ],
  1067. [
  1068. ['tags' => ['param', 'return', 'throws', 'type', 'var', 'method']],
  1069. '<?php
  1070. /**
  1071. * @ Security("is_granted(\'CANCEL\', giftCard)")
  1072. */
  1073. ',
  1074. ],
  1075. [
  1076. ['tags' => ['param', 'return', 'throws', 'type', 'var']],
  1077. '<?php
  1078. /**
  1079. * @ Security("is_granted(\'CANCEL\', giftCard)")
  1080. * @ foo bar
  1081. * @ foo
  1082. */
  1083. ',
  1084. ],
  1085. ];
  1086. }
  1087. }