GeneralAttributeRemoveFixerTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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\AttributeNotation;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Raffaele Carelle <raffaele.carelle@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\AttributeNotation\GeneralAttributeRemoveFixer
  20. *
  21. * @requires PHP 8.0
  22. *
  23. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\AttributeNotation\GeneralAttributeRemoveFixer>
  24. *
  25. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\AttributeNotation\GeneralAttributeRemoveFixer
  26. */
  27. final class GeneralAttributeRemoveFixerTest extends AbstractFixerTestCase
  28. {
  29. /**
  30. * @param _AutogeneratedInputConfiguration $configuration
  31. *
  32. * @dataProvider provideFixCases
  33. */
  34. public function testFix(string $expected, ?string $input = null, array $configuration = []): void
  35. {
  36. $this->fixer->configure($configuration);
  37. $this->doTest($expected, $input);
  38. }
  39. /**
  40. * @return iterable<array{0: string, 1?: string, 2?: array<string, mixed>}>
  41. */
  42. public static function provideFixCases(): iterable
  43. {
  44. yield 'Explicit in namespace' => [
  45. '<?php
  46. namespace Test;
  47. use A\B\Foo;
  48. use A\B\Bar as BarAlias;
  49. use A\B as AB;
  50. #[Foo(4, \'baz qux\')]
  51. #[AB\Baz(prop: \'baz\')]
  52. #[\A\B\Qux()]
  53. #[Corge]
  54. function f() {}
  55. ',
  56. '<?php
  57. namespace Test;
  58. use A\B\Foo;
  59. use A\B\Bar as BarAlias;
  60. use A\B as AB;
  61. #[Foo(4, \'baz qux\')]
  62. #[BarAlias(3)]
  63. #[AB\Baz(prop: \'baz\')]
  64. #[\A\B\Qux()]
  65. #[A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  66. #[Corge]
  67. function f() {}
  68. ',
  69. [
  70. 'attributes' => ['A\B\Bar', 'Test\A\B\Quux'],
  71. ],
  72. ];
  73. yield 'Explicit in global namespace' => [
  74. '<?php
  75. use A\B\Foo;
  76. use A\B\Bar as BarAlias;
  77. use A\B as AB;
  78. #[A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  79. #[AB\Baz(prop: \'baz\')]
  80. #[Foo(4, \'baz qux\')]
  81. function f() {}
  82. ',
  83. '<?php
  84. use A\B\Foo;
  85. use A\B\Bar as BarAlias;
  86. use A\B as AB;
  87. #[A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  88. #[BarAlias(3)]
  89. #[AB\Baz(prop: \'baz\')]
  90. #[Foo(4, \'baz qux\')]
  91. #[\A\B\Qux()]
  92. #[Corge]
  93. function f() {}
  94. ',
  95. [
  96. 'attributes' => ['\A\B\Qux', '\Corge', 'A\B\Bar'],
  97. ],
  98. ];
  99. yield 'Multiple namespaces' => [
  100. '<?php
  101. namespace Test
  102. {
  103. use A\B\Foo;
  104. use A\B\Bar as BarAlias;
  105. function f() {}
  106. }
  107. namespace Test2
  108. {
  109. use A\B\Bar as BarAlias;
  110. use A\B as AB;
  111. #[\A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  112. function f() {}
  113. }
  114. namespace Test
  115. {
  116. use A\B\Foo;
  117. use A\B\Bar as BarAlias2;
  118. function f2() {}
  119. }
  120. namespace
  121. {
  122. use A\B\Foo;
  123. use A\B\Bar as BarAlias3;
  124. function f() {}
  125. }
  126. ',
  127. '<?php
  128. namespace Test
  129. {
  130. use A\B\Foo;
  131. use A\B\Bar as BarAlias;
  132. #[AB\Baz(prop: \'baz\')]
  133. #[Foo(4, \'baz qux\')]
  134. #[BarAlias(3)]
  135. function f() {}
  136. }
  137. namespace Test2
  138. {
  139. use A\B\Bar as BarAlias;
  140. use A\B as AB;
  141. #[BarAlias(3)]
  142. #[AB\Baz(prop: \'baz\')]
  143. #[\A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  144. function f() {}
  145. }
  146. namespace Test
  147. {
  148. use A\B\Foo;
  149. use A\B\Bar as BarAlias2;
  150. #[AB\Baz(prop: \'baz\')]
  151. #[Foo(4, \'baz qux\')]
  152. #[BarAlias2(3)]
  153. function f2() {}
  154. }
  155. namespace
  156. {
  157. use A\B\Foo;
  158. use A\B\Bar as BarAlias3;
  159. #[AB\Baz(prop: \'baz\')]
  160. #[Foo(4, \'baz qux\')]
  161. #[BarAlias3(3)]
  162. function f() {}
  163. }
  164. ',
  165. [
  166. 'attributes' => ['A\B\Bar', 'Test\AB\Baz', 'A\B\Quux', 'A\B\Baz', 'A\B\Foo', '\AB\Baz'],
  167. ],
  168. ];
  169. yield 'With whitespaces' => [
  170. '<?php
  171. namespace Test;
  172. use A\B\Foo;
  173. use A\B\Bar as BarAlias;
  174. use A\B as AB;
  175. #[ \A\B\Qux() ]
  176. #[ BarAlias (3) ]
  177. #[ Corge ]
  178. function f() {}
  179. ',
  180. '<?php
  181. namespace Test;
  182. use A\B\Foo;
  183. use A\B\Bar as BarAlias;
  184. use A\B as AB;
  185. #[ AB\Baz (prop: \'baz\') ]
  186. #[ A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\') ]
  187. #[ \A\B\Qux() ]
  188. #[ BarAlias (3) ]
  189. #[ Corge ]
  190. #[ Foo (4, \'baz qux\') ]
  191. function f() {}
  192. ',
  193. [
  194. 'attributes' => ['A\B\Foo', 'Test\A\B\Quux', 'A\B\Baz'],
  195. ],
  196. ];
  197. yield 'With docblock' => [
  198. '<?php
  199. namespace Test;
  200. use A\B\Foo;
  201. use A\B\Bar as BarAlias;
  202. use A\B as AB;
  203. /**
  204. * Start docblock
  205. */
  206. /**
  207. * AB\Baz docblock
  208. */
  209. #[AB\Baz(prop: \'baz\')]
  210. #[A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  211. #[BarAlias(3)]
  212. #[Foo(4, \'baz qux\')]
  213. /**
  214. * End docblock
  215. */
  216. class X
  217. {}
  218. function f2(/** Start docblock */#[Foo(4, \'baz qux\')] #[BarAlias(3)] /** End docblock */string $param) {}
  219. ',
  220. '<?php
  221. namespace Test;
  222. use A\B\Foo;
  223. use A\B\Bar as BarAlias;
  224. use A\B as AB;
  225. /**
  226. * Start docblock
  227. */
  228. /**
  229. * AB\Baz docblock
  230. */
  231. #[AB\Baz(prop: \'baz\')]
  232. #[A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\')]
  233. #[\A\B\Qux()]
  234. #[BarAlias(3)]
  235. /**
  236. * Corge docblock
  237. */
  238. #[Corge]
  239. #[Foo(4, \'baz qux\')]
  240. /**
  241. * End docblock
  242. */
  243. class X
  244. {}
  245. function f2(/** Start docblock */#[Foo(4, \'baz qux\')] #[BarAlias(3)] #[\A\B\Qux()] /** Corge docblock */#[Corge] /** End docblock */string $param) {}
  246. ',
  247. [
  248. 'attributes' => ['Test\Corge', '\A\B\Qux'],
  249. ],
  250. ];
  251. yield 'With comments' => [
  252. '<?php
  253. namespace Test;
  254. use A\B\Foo;
  255. use A\B\Bar as BarAlias;
  256. use A\B as AB;
  257. function f() {}
  258. ',
  259. '<?php
  260. namespace Test;
  261. use A\B\Foo;
  262. use A\B\Bar as BarAlias;
  263. use A\B as AB;
  264. #[/* comment */A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\') /* comment */]
  265. #[ /* comment */ BarAlias/* comment */(3)/* comment */]
  266. #[/* comment */ Corge/* comment */]
  267. #[/* comment */AB\Baz /* comment */ (prop: \'baz\') /* comment */ ]
  268. #[/* comment */Foo/* comment */(4, \'baz qux\') /* comment */ ]
  269. #[ /* comment */ \A\B\Qux()/* comment */]
  270. function f() {}
  271. ',
  272. [
  273. 'attributes' => ['Test\A\B\Quux', 'A\B\Bar', 'Test\Corge', 'A\B\Baz', 'A\B\Foo', '\A\B\Qux'],
  274. ],
  275. ];
  276. yield 'With multiple attributes' => [
  277. '<?php
  278. namespace Test;
  279. use A\B\Foo;
  280. use A\B\Bar as BarAlias;
  281. use A\B as AB;
  282. #[
  283. AB\Baz(prop: \'baz\'),
  284. A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'),
  285. BarAlias(3),
  286. Corge
  287. ]
  288. class X
  289. {
  290. #[ AB\Baz(prop: \'baz\'), A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'), BarAlias(3), Corge]
  291. public function y() {}
  292. }
  293. ',
  294. '<?php
  295. namespace Test;
  296. use A\B\Foo;
  297. use A\B\Bar as BarAlias;
  298. use A\B as AB;
  299. #[
  300. AB\Baz(prop: \'baz\'),
  301. A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'),
  302. \A\B\Qux(),
  303. BarAlias(3),
  304. Corge,
  305. Foo(4, \'baz qux\'),
  306. ]
  307. class X
  308. {
  309. #[ AB\Baz(prop: \'baz\'), A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'), \A\B\Qux(), BarAlias(3), Corge,Foo(4, \'baz qux\')]
  310. public function y() {}
  311. }
  312. ',
  313. [
  314. 'attributes' => ['A\B\Foo', '\A\B\Qux'],
  315. ],
  316. ];
  317. yield 'Multiline with no trailing comma' => [
  318. '<?php
  319. namespace Test;
  320. use A\B\Foo;
  321. use A\B\Bar as BarAlias;
  322. use A\B as AB;
  323. class X
  324. {}
  325. ',
  326. '<?php
  327. namespace Test;
  328. use A\B\Foo;
  329. use A\B\Bar as BarAlias;
  330. use A\B as AB;
  331. #[
  332. AB\Baz(prop: \'baz\'),
  333. A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'),
  334. \A\B\Qux(),
  335. BarAlias(3),
  336. Corge,
  337. Foo(4, \'baz qux\')
  338. ]
  339. class X
  340. {}
  341. ',
  342. [
  343. 'attributes' => ['A\B\Foo', '\A\B\Qux', 'A\B\Baz', 'Test\A\B\Quux', 'A\B\Bar', 'Test\Corge'],
  344. ],
  345. ];
  346. yield 'Multiple with comments' => [
  347. '<?php
  348. namespace Test;
  349. use A\B\Foo;
  350. use A\B\Bar as BarAlias;
  351. use A\B as AB;
  352. #[
  353. /*
  354. * AB\Baz comment
  355. */
  356. AB\Baz(prop: \'baz\'),
  357. A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'),
  358. \A\B\Qux(),
  359. BarAlias(3)
  360. ]
  361. class X
  362. {
  363. #[ /* AB\Baz comment */AB\Baz(prop: \'baz\'), A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'), \A\B\Qux(), BarAlias(3)]
  364. public function y() {}
  365. }
  366. ',
  367. '<?php
  368. namespace Test;
  369. use A\B\Foo;
  370. use A\B\Bar as BarAlias;
  371. use A\B as AB;
  372. #[
  373. /*
  374. * AB\Baz comment
  375. */
  376. AB\Baz(prop: \'baz\'),
  377. A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'),
  378. \A\B\Qux(),
  379. BarAlias(3),
  380. /*
  381. * Corge comment
  382. */
  383. Corge,
  384. /**
  385. * Foo docblock
  386. */
  387. Foo(4, \'baz qux\'),
  388. ]
  389. class X
  390. {
  391. #[ /* AB\Baz comment */AB\Baz(prop: \'baz\'), A\B\Quux(prop1: [1, 2, 4], prop2: true, prop3: \'foo bar\'), \A\B\Qux(), BarAlias(3), /* Corge comment */Corge,/** Foo docblock */Foo(4, \'baz qux\')]
  392. public function y() {}
  393. }
  394. ',
  395. [
  396. 'attributes' => ['A\B\Foo', 'Test\Corge'],
  397. ],
  398. ];
  399. }
  400. }