PhpdocNoAliasTagFixerTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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\ConfigurationException\InvalidFixerConfigurationException;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. /**
  16. * @author Graham Campbell <hello@gjcampbell.co.uk>
  17. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  18. *
  19. * @internal
  20. *
  21. * @covers \PhpCsFixer\Fixer\Phpdoc\PhpdocNoAliasTagFixer
  22. *
  23. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Phpdoc\PhpdocNoAliasTagFixer>
  24. *
  25. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Phpdoc\PhpdocNoAliasTagFixer
  26. */
  27. final class PhpdocNoAliasTagFixerTest extends AbstractFixerTestCase
  28. {
  29. public function testInvalidConfigCase1(): void
  30. {
  31. $this->expectException(InvalidFixerConfigurationException::class);
  32. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: Tag to replace must be a string\.$#');
  33. $this->fixer->configure(['replacements' => [1 => 'abc']]); // @phpstan-ignore-line
  34. }
  35. public function testInvalidConfigCase2(): void
  36. {
  37. $this->expectException(InvalidFixerConfigurationException::class);
  38. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: The option "replacements" with value array is expected to be of type "string\[\]", but one of the elements is of type "null"\.$#');
  39. $this->fixer->configure(['replacements' => ['a' => null]]); // @phpstan-ignore-line
  40. }
  41. public function testInvalidConfigCase3a(): void
  42. {
  43. $this->expectException(InvalidFixerConfigurationException::class);
  44. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: Tag "see" cannot be replaced by invalid tag "link\*\/"\.$#');
  45. $this->fixer->configure(['replacements' => ['see' => 'link*/']]);
  46. }
  47. public function testInvalidConfigCase3b(): void
  48. {
  49. $this->expectException(InvalidFixerConfigurationException::class);
  50. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: The option "foo" does not exist. Defined options are: "replacements"\.$#');
  51. $this->fixer->configure(['foo' => 123]);
  52. }
  53. public function testInvalidConfigCase4(): void
  54. {
  55. $this->expectException(InvalidFixerConfigurationException::class);
  56. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: Cannot change tag "link" to tag "see", as the tag "see" is configured to be replaced to "link"\.$#');
  57. $this->fixer->configure(['replacements' => [
  58. 'link' => 'see',
  59. 'a' => 'b',
  60. 'see' => 'link',
  61. ]]);
  62. }
  63. public function testInvalidConfigCase5(): void
  64. {
  65. $this->expectException(InvalidFixerConfigurationException::class);
  66. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: Cannot change tag "b" to tag "see", as the tag "see" is configured to be replaced to "link"\.$#');
  67. $this->fixer->configure(['replacements' => [
  68. 'b' => 'see',
  69. 'see' => 'link',
  70. 'link' => 'b',
  71. ]]);
  72. }
  73. public function testInvalidConfigCase6(): void
  74. {
  75. $this->expectException(InvalidFixerConfigurationException::class);
  76. $this->expectExceptionMessageMatches('#^\[phpdoc_no_alias_tag\] Invalid configuration: Cannot change tag "see" to tag "link", as the tag "link" is configured to be replaced to "b"\.$#');
  77. $this->fixer->configure(['replacements' => [
  78. 'see' => 'link',
  79. 'link' => 'b',
  80. ]]);
  81. }
  82. /**
  83. * @dataProvider providePropertyFixCases
  84. */
  85. public function testPropertyFix(string $expected, ?string $input = null): void
  86. {
  87. $this->fixer->configure(['replacements' => [
  88. 'property-read' => 'property',
  89. 'property-write' => 'property',
  90. ]]);
  91. $this->doTest($expected, $input);
  92. }
  93. /**
  94. * @return iterable<array{0: string, 1?: string}>
  95. */
  96. public static function providePropertyFixCases(): iterable
  97. {
  98. yield [
  99. '<?php
  100. /**
  101. *
  102. */',
  103. ];
  104. yield [
  105. '<?php
  106. /**
  107. * @property string $foo
  108. */',
  109. '<?php
  110. /**
  111. * @property-read string $foo
  112. */',
  113. ];
  114. yield [
  115. '<?php /** @property mixed $bar */',
  116. '<?php /** @property-write mixed $bar */',
  117. ];
  118. }
  119. /**
  120. * @dataProvider provideTypeToVarFixCases
  121. */
  122. public function testTypeToVarFix(string $expected, ?string $input = null): void
  123. {
  124. $this->fixer->configure(['replacements' => [
  125. 'type' => 'var',
  126. ]]);
  127. $this->doTest($expected, $input);
  128. }
  129. /**
  130. * @return iterable<array{0: string, 1?: string}>
  131. */
  132. public static function provideTypeToVarFixCases(): iterable
  133. {
  134. yield [
  135. '<?php
  136. /**
  137. *
  138. */',
  139. ];
  140. yield [
  141. '<?php
  142. /**
  143. * @var string Hello!
  144. */',
  145. '<?php
  146. /**
  147. * @type string Hello!
  148. */',
  149. ];
  150. yield [
  151. '<?php /** @var string Hello! */',
  152. '<?php /** @type string Hello! */',
  153. ];
  154. yield [
  155. '<?php
  156. /**
  157. * Initializes this class with the given options.
  158. *
  159. * @param array $options {
  160. * @var bool $required Whether this element is required
  161. * @var string $label The display name for this element
  162. * }
  163. */',
  164. '<?php
  165. /**
  166. * Initializes this class with the given options.
  167. *
  168. * @param array $options {
  169. * @type bool $required Whether this element is required
  170. * @type string $label The display name for this element
  171. * }
  172. */',
  173. ];
  174. }
  175. /**
  176. * @dataProvider provideVarToTypeFixCases
  177. */
  178. public function testVarToTypeFix(string $expected, ?string $input = null): void
  179. {
  180. $this->fixer->configure(['replacements' => [
  181. 'var' => 'type',
  182. ]]);
  183. $this->doTest($expected, $input);
  184. }
  185. /**
  186. * @return iterable<array{0: string, 1?: string}>
  187. */
  188. public static function provideVarToTypeFixCases(): iterable
  189. {
  190. yield [
  191. '<?php
  192. /**
  193. *
  194. */',
  195. ];
  196. yield [
  197. '<?php
  198. /**
  199. * @type string Hello!
  200. */',
  201. '<?php
  202. /**
  203. * @var string Hello!
  204. */',
  205. ];
  206. yield [
  207. '<?php /** @type string Hello! */',
  208. '<?php /** @var string Hello! */',
  209. ];
  210. yield [
  211. '<?php
  212. /**
  213. * Initializes this class with the given options.
  214. *
  215. * @param array $options {
  216. * @type bool $required Whether this element is required
  217. * @type string $label The display name for this element
  218. * }
  219. */',
  220. '<?php
  221. /**
  222. * Initializes this class with the given options.
  223. *
  224. * @param array $options {
  225. * @var bool $required Whether this element is required
  226. * @var string $label The display name for this element
  227. * }
  228. */',
  229. ];
  230. }
  231. public function testLinkToSee(): void
  232. {
  233. $this->fixer->configure(['replacements' => [
  234. 'link' => 'see',
  235. ]]);
  236. $this->doTest(
  237. '<?php /** @see https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#710-link-deprecated */',
  238. '<?php /** @link https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#710-link-deprecated */'
  239. );
  240. }
  241. /**
  242. * @dataProvider provideDefaultConfigCases
  243. */
  244. public function testDefaultConfig(string $expected, ?string $input = null): void
  245. {
  246. $this->doTest($expected, $input);
  247. }
  248. /**
  249. * @return iterable<array{string, string}>
  250. */
  251. public static function provideDefaultConfigCases(): iterable
  252. {
  253. yield [
  254. '<?php /** @see https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#710-link-deprecated */',
  255. '<?php /** @link https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#710-link-deprecated */',
  256. ];
  257. yield [
  258. '<?php /** @property mixed $bar */',
  259. '<?php /** @property-write mixed $bar */',
  260. ];
  261. yield [
  262. '<?php /** @property mixed $bar */',
  263. '<?php /** @property-read mixed $bar */',
  264. ];
  265. yield [
  266. '<?php /** @var string Hello! */',
  267. '<?php /** @type string Hello! */',
  268. ];
  269. }
  270. }