PhpdocAlignFixerTest.php 34 KB

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