PhpdocAddMissingParamAnnotationFixerTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace PhpCsFixer\Tests\Fixer\Phpdoc;
  12. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  13. use PhpCsFixer\WhitespacesFixerConfig;
  14. /**
  15. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Phpdoc\PhpdocAddMissingParamAnnotationFixer
  20. */
  21. final class PhpdocAddMissingParamAnnotationFixerTest extends AbstractFixerTestCase
  22. {
  23. public function testConfigureRejectsUnknownConfigurationKey()
  24. {
  25. $key = 'foo';
  26. $this->expectException(\PhpCsFixer\ConfigurationException\InvalidConfigurationException::class);
  27. $this->expectExceptionMessage(sprintf(
  28. '[phpdoc_add_missing_param_annotation] Invalid configuration: The option "%s" does not exist.',
  29. $key
  30. ));
  31. $this->fixer->configure([
  32. $key => 'bar',
  33. ]);
  34. }
  35. /**
  36. * @dataProvider provideConfigureRejectsInvalidConfigurationValueCases
  37. *
  38. * @param mixed $value
  39. */
  40. public function testConfigureRejectsInvalidConfigurationValue($value)
  41. {
  42. $this->expectException(\PhpCsFixer\ConfigurationException\InvalidConfigurationException::class);
  43. $this->expectExceptionMessage(sprintf(
  44. 'expected to be of type "bool", but is of type "%s".',
  45. \is_object($value) ? \get_class($value) : \gettype($value)
  46. ));
  47. $this->fixer->configure([
  48. 'only_untyped' => $value,
  49. ]);
  50. }
  51. /**
  52. * @return array
  53. */
  54. public function provideConfigureRejectsInvalidConfigurationValueCases()
  55. {
  56. return [
  57. 'null' => [null],
  58. 'int' => [1],
  59. 'array' => [[]],
  60. 'float' => [0.1],
  61. 'object' => [new \stdClass()],
  62. ];
  63. }
  64. /**
  65. * @param string $expected
  66. * @param null|string $input
  67. *
  68. * @dataProvider provideFixCases
  69. */
  70. public function testFix($expected, $input = null, array $config = [])
  71. {
  72. $this->fixer->configure($config ?: ['only_untyped' => false]);
  73. $this->doTest($expected, $input);
  74. }
  75. public function provideFixCases()
  76. {
  77. return [
  78. [
  79. '<?php
  80. /**
  81. *
  82. */',
  83. ],
  84. [
  85. '<?php
  86. /**
  87. * @param int $foo
  88. * @param mixed $bar
  89. */
  90. function f1($foo, $bar) {}',
  91. '<?php
  92. /**
  93. * @param int $foo
  94. */
  95. function f1($foo, $bar) {}',
  96. ],
  97. [
  98. '<?php
  99. /**
  100. * @param int $bar
  101. * @param mixed $foo
  102. */
  103. function f2($foo, $bar) {}',
  104. '<?php
  105. /**
  106. * @param int $bar
  107. */
  108. function f2($foo, $bar) {}',
  109. ],
  110. [
  111. '<?php
  112. /**
  113. * @return void
  114. * @param mixed $foo
  115. * @param mixed $bar
  116. */
  117. function f3($foo, $bar) {}',
  118. '<?php
  119. /**
  120. * @return void
  121. */
  122. function f3($foo, $bar) {}',
  123. ],
  124. [
  125. '<?php
  126. abstract class Foo {
  127. /**
  128. * @param int $bar
  129. * @param mixed $foo
  130. */
  131. abstract public function f4a($foo, $bar);
  132. }',
  133. '<?php
  134. abstract class Foo {
  135. /**
  136. * @param int $bar
  137. */
  138. abstract public function f4a($foo, $bar);
  139. }',
  140. ],
  141. [
  142. '<?php
  143. class Foo {
  144. /**
  145. * @param int $bar
  146. * @param mixed $foo
  147. */
  148. static final public function f4b($foo, $bar) {}
  149. }',
  150. '<?php
  151. class Foo {
  152. /**
  153. * @param int $bar
  154. */
  155. static final public function f4b($foo, $bar) {}
  156. }',
  157. ],
  158. [
  159. '<?php
  160. class Foo {
  161. /**
  162. * @var int
  163. */
  164. private $foo;
  165. }',
  166. ],
  167. [
  168. '<?php
  169. /**
  170. * @param $bar No type !!
  171. * @param mixed $foo
  172. */
  173. function f5($foo, $bar) {}',
  174. '<?php
  175. /**
  176. * @param $bar No type !!
  177. */
  178. function f5($foo, $bar) {}',
  179. ],
  180. [
  181. '<?php
  182. /**
  183. * @param int
  184. * @param int $bar
  185. * @param Foo\Bar $foo
  186. */
  187. function f6(Foo\Bar $foo, $bar) {}',
  188. '<?php
  189. /**
  190. * @param int
  191. * @param int $bar
  192. */
  193. function f6(Foo\Bar $foo, $bar) {}',
  194. ],
  195. [
  196. '<?php
  197. /**
  198. * @param int $bar
  199. * @param null|string $foo
  200. */
  201. function f7(string $foo = nuLl, $bar) {}',
  202. '<?php
  203. /**
  204. * @param int $bar
  205. */
  206. function f7(string $foo = nuLl, $bar) {}',
  207. ],
  208. [
  209. '<?php
  210. /**
  211. * @param int $bar
  212. * @param mixed $baz
  213. *
  214. * @return void
  215. */
  216. function f9(string $foo, $bar, $baz) {}',
  217. '<?php
  218. /**
  219. * @param int $bar
  220. *
  221. * @return void
  222. */
  223. function f9(string $foo, $bar, $baz) {}',
  224. ['only_untyped' => true],
  225. ],
  226. [
  227. '<?php
  228. /**
  229. * @param bool|bool[] $caseSensitive Line 1
  230. * Line 2
  231. */
  232. function f11($caseSensitive) {}
  233. ',
  234. ],
  235. [
  236. '<?php
  237. /** @return string */
  238. function hello($string)
  239. {
  240. return $string;
  241. }',
  242. ],
  243. [
  244. '<?php
  245. /** @return string
  246. * @param mixed $string
  247. */
  248. function hello($string)
  249. {
  250. return $string;
  251. }',
  252. '<?php
  253. /** @return string
  254. */
  255. function hello($string)
  256. {
  257. return $string;
  258. }',
  259. ],
  260. [
  261. '<?php
  262. /**
  263. * @param mixed $string
  264. * @return string */
  265. function hello($string)
  266. {
  267. return $string;
  268. }',
  269. '<?php
  270. /**
  271. * @return string */
  272. function hello($string)
  273. {
  274. return $string;
  275. }',
  276. ],
  277. ];
  278. }
  279. /**
  280. * @param string $expected
  281. * @param null|string $input
  282. *
  283. * @dataProvider provideFix70Cases
  284. * @requires PHP 7.0
  285. */
  286. public function testFix70($expected, $input = null, array $config = [])
  287. {
  288. $this->fixer->configure($config ?: ['only_untyped' => false]);
  289. $this->doTest($expected, $input);
  290. }
  291. public function provideFix70Cases()
  292. {
  293. return [
  294. [
  295. '<?php
  296. /**
  297. * @param int $bar
  298. * @param string $foo
  299. */
  300. function f8(string $foo = "null", $bar) {}',
  301. '<?php
  302. /**
  303. * @param int $bar
  304. */
  305. function f8(string $foo = "null", $bar) {}',
  306. ],
  307. [
  308. '<?php
  309. /**
  310. * @{inheritdoc}
  311. */
  312. function f10(string $foo = "null", $bar) {}',
  313. ],
  314. ];
  315. }
  316. /**
  317. * @param string $expected
  318. * @param null|string $input
  319. *
  320. * @dataProvider provideFix71Cases
  321. * @requires PHP 7.1
  322. */
  323. public function testFix71($expected, $input = null, array $config = [])
  324. {
  325. $this->fixer->configure($config ?: ['only_untyped' => false]);
  326. $this->doTest($expected, $input);
  327. }
  328. public function provideFix71Cases()
  329. {
  330. return [
  331. [
  332. '<?php
  333. /**
  334. * @param int $bar
  335. * @param ?array $foo
  336. */
  337. function p1(?array $foo = null, $bar) {}',
  338. '<?php
  339. /**
  340. * @param int $bar
  341. */
  342. function p1(?array $foo = null, $bar) {}',
  343. ],
  344. ];
  345. }
  346. /**
  347. * @param string $expected
  348. * @param null|string $input
  349. *
  350. * @dataProvider provideMessyWhitespacesCases
  351. */
  352. public function testMessyWhitespaces($expected, $input = null, array $config = [])
  353. {
  354. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  355. $this->fixer->configure($config ?: ['only_untyped' => false]);
  356. $this->doTest($expected, $input);
  357. }
  358. public function provideMessyWhitespacesCases()
  359. {
  360. return [
  361. [
  362. "<?php\r\n\t/**\r\n\t * @param int \$bar\r\n\t * @param null|string \$foo\r\n\t */\r\n\tfunction f7(string \$foo = nuLl, \$bar) {}",
  363. "<?php\r\n\t/**\r\n\t * @param int \$bar\r\n\t */\r\n\tfunction f7(string \$foo = nuLl, \$bar) {}",
  364. ],
  365. ];
  366. }
  367. /**
  368. * @param string $expected
  369. * @param string $input
  370. *
  371. * @dataProvider provideByReferenceCases
  372. */
  373. public function testByReference($expected, $input)
  374. {
  375. $this->fixer->configure(['only_untyped' => false]);
  376. $this->doTest($expected, $input);
  377. }
  378. public function provideByReferenceCases()
  379. {
  380. return [
  381. [
  382. '<?php
  383. /**
  384. * something
  385. * @param mixed $numbers
  386. */
  387. function add(&$numbers) {}
  388. ',
  389. '<?php
  390. /**
  391. * something
  392. */
  393. function add(&$numbers) {}
  394. ',
  395. ],
  396. [
  397. '<?php
  398. /**
  399. * something
  400. * @param null|array $numbers
  401. */
  402. function add(array &$numbers = null) {}
  403. ',
  404. '<?php
  405. /**
  406. * something
  407. */
  408. function add(array &$numbers = null) {}
  409. ',
  410. ],
  411. ];
  412. }
  413. /**
  414. * @param string $expected
  415. * @param string $input
  416. *
  417. * @dataProvider provideVariableNumberOfArgumentsCases
  418. */
  419. public function testVariableNumberOfArguments($expected, $input)
  420. {
  421. $this->fixer->configure(['only_untyped' => false]);
  422. $this->doTest($expected, $input);
  423. }
  424. public function provideVariableNumberOfArgumentsCases()
  425. {
  426. return [
  427. [
  428. '<?php
  429. /**
  430. * something
  431. * @param array $numbers
  432. */
  433. function sum(...$numbers) {}
  434. ',
  435. '<?php
  436. /**
  437. * something
  438. */
  439. function sum(...$numbers) {}
  440. ',
  441. ],
  442. [
  443. '<?php
  444. /**
  445. * @param int $a
  446. * @param array $numbers
  447. */
  448. function sum($a, ...$numbers) {}
  449. ',
  450. '<?php
  451. /**
  452. * @param int $a
  453. */
  454. function sum($a, ...$numbers) {}
  455. ',
  456. ],
  457. [
  458. '<?php
  459. /**
  460. * @param \Date[] $numbers
  461. */
  462. function sum(\Date ...$numbers) {}
  463. ',
  464. '<?php
  465. /**
  466. */
  467. function sum(\Date ...$numbers) {}
  468. ',
  469. ],
  470. ];
  471. }
  472. }