NoTrailingCommaInSinglelineFixerTest.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  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\Basic;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @internal
  16. *
  17. * @covers \PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer
  18. */
  19. final class NoTrailingCommaInSinglelineFixerTest extends AbstractFixerTestCase
  20. {
  21. /**
  22. * @dataProvider provideFixCases
  23. */
  24. public function testFix(string $expected, ?string $input = null): void
  25. {
  26. $this->doTest($expected, $input);
  27. }
  28. public static function provideFixCases(): iterable
  29. {
  30. yield [
  31. '<?php [$x, $y] = $a;',
  32. '<?php [$x, $y,] = $a;',
  33. ];
  34. yield 'group_import' => [
  35. '<?php use a\{ClassA, ClassB};',
  36. '<?php use a\{ClassA, ClassB,};',
  37. ];
  38. yield 'lots of nested' => [
  39. '<?php $a = [1,[1,[1,[1,[1,[1,[1,[1]],[1,[1,[1,[1,[1,[1,[1,[1]]]]]]]]]]]]]];',
  40. '<?php $a = [1,[1,[1,[1,[1,[1,[1,[1,],],[1,[1,[1,[1,[1,[1,[1,[1,],],],],],],],],],],],],],];',
  41. ];
  42. }
  43. /**
  44. * @dataProvider provideFixNoTrailingCommaInSinglelineFunctionCallCases
  45. */
  46. public function testFixNoTrailingCommaInSinglelineFunctionCall(string $expected, string $input = null): void
  47. {
  48. $this->fixer->configure(['elements' => ['arguments']]);
  49. $this->doTest($expected, $input);
  50. }
  51. public static function provideFixNoTrailingCommaInSinglelineFunctionCallCases(): iterable
  52. {
  53. yield 'simple var' => [
  54. '<?php $a(1);',
  55. '<?php $a(1,);',
  56. ];
  57. yield '&' => [
  58. '<?php $a = &foo($a);',
  59. '<?php $a = &foo($a,);',
  60. ];
  61. yield 'open' => [
  62. '<?php foo($a);',
  63. '<?php foo($a,);',
  64. ];
  65. yield '=' => [
  66. '<?php $b = foo($a);',
  67. '<?php $b = foo($a,);',
  68. ];
  69. yield '.' => [
  70. '<?php $c = $b . foo($a);',
  71. '<?php $c = $b . foo($a,);',
  72. ];
  73. yield '(' => [
  74. '<?php (foo($a/* 1X */ /* 2 */ ));',
  75. '<?php (foo($a /* 1X */ , /* 2 */ ));',
  76. ];
  77. yield '\\' => [
  78. '<?php \foo($a);',
  79. '<?php \foo($a,);',
  80. ];
  81. yield 'A\\' => [
  82. '<?php A\foo($a);',
  83. '<?php A\foo($a,);',
  84. ];
  85. yield '\A\\' => [
  86. '<?php \A\foo($a);',
  87. '<?php \A\foo($a,);',
  88. ];
  89. yield ';' => [
  90. '<?php ; foo($a);',
  91. '<?php ; foo($a,);',
  92. ];
  93. yield '}' => [
  94. '<?php if ($a) { echo 1;} foo($a);',
  95. '<?php if ($a) { echo 1;} foo($a,);',
  96. ];
  97. yield 'test method call' => [
  98. '<?php $o->abc($a);',
  99. '<?php $o->abc($a,);',
  100. ];
  101. yield 'nested call' => [
  102. '<?php $o->abc($a,foo(1));',
  103. '<?php $o->abc($a,foo(1,));',
  104. ];
  105. yield 'wrapped' => [
  106. '<?php echo (new Process())->getOutput(1);',
  107. '<?php echo (new Process())->getOutput(1,);',
  108. ];
  109. yield 'dynamic function and method calls' => [
  110. '<?php $b->$a(1); $c("");',
  111. '<?php $b->$a(1,); $c("",);',
  112. ];
  113. yield 'static function call' => [
  114. '<?php
  115. unset($foo->bar);
  116. $b = isset($foo->bar);
  117. ',
  118. '<?php
  119. unset($foo->bar,);
  120. $b = isset($foo->bar,);
  121. ',
  122. ];
  123. yield 'unset' => [
  124. '<?php A::foo(1);',
  125. '<?php A::foo(1,);',
  126. ];
  127. yield 'anonymous_class construction' => [
  128. '<?php new class(1, 2) {};',
  129. '<?php new class(1, 2,) {};',
  130. ];
  131. yield 'array/property access call' => [
  132. '<?php
  133. $a = [
  134. "e" => static function(int $a): void{ echo $a;},
  135. "d" => [
  136. [2 => static function(int $a): void{ echo $a;}]
  137. ]
  138. ];
  139. $a["e"](1);
  140. $a["d"][0][2](1);
  141. $z = new class { public static function b(int $a): void {echo $a; }};
  142. $z::b(1);
  143. ${$e}(1);
  144. $$e(2);
  145. $f(0)(1);
  146. $g["e"](1); // foo',
  147. '<?php
  148. $a = [
  149. "e" => static function(int $a): void{ echo $a;},
  150. "d" => [
  151. [2 => static function(int $a): void{ echo $a;}]
  152. ]
  153. ];
  154. $a["e"](1,);
  155. $a["d"][0][2](1,);
  156. $z = new class { public static function b(int $a): void {echo $a; }};
  157. $z::b(1,);
  158. ${$e}(1,);
  159. $$e(2,);
  160. $f(0,)(1,);
  161. $g["e"](1,); // foo',
  162. ];
  163. yield 'do not fix' => [
  164. '<?php
  165. function someFunction ($p1){}
  166. function & foo($a,$b): array { return []; }
  167. foo (
  168. 1,
  169. 2,
  170. );
  171. $a = new class (
  172. $a,
  173. ) {};
  174. isset($a, $b);
  175. unset($a,$b);
  176. list($a,$b) = $a;
  177. $a = [1,2,3,];
  178. $a = array(1,2,3,);
  179. function foo1(string $param = null ): void
  180. {
  181. }
  182. ;',
  183. ];
  184. }
  185. /**
  186. * @dataProvider provideFix80NoTrailingCommaInSinglelineFunctionCallFixerCases
  187. *
  188. * @requires PHP 8.0
  189. */
  190. public function testFix80NoTrailingCommaInSinglelineFunctionCallFixer(string $expected, string $input = null): void
  191. {
  192. $this->doTest($expected, $input);
  193. }
  194. public static function provideFix80NoTrailingCommaInSinglelineFunctionCallFixerCases(): iterable
  195. {
  196. yield [
  197. '<?php function foo(
  198. #[MyAttr(1, 2,)] Type $myParam,
  199. ) {}
  200. $foo1b = function() use ($bar, ) {};
  201. ',
  202. ];
  203. }
  204. /**
  205. * @dataProvider provideFix81NoTrailingCommaInSinglelineFunctionCallFixerCases
  206. *
  207. * @requires PHP 8.1
  208. */
  209. public function testFix81NoTrailingCommaInSinglelineFunctionCallFixer(string $expected, ?string $input = null): void
  210. {
  211. $this->doTest($expected, $input);
  212. }
  213. public static function provideFix81NoTrailingCommaInSinglelineFunctionCallFixerCases(): iterable
  214. {
  215. yield [
  216. '<?php $object?->method(1); strlen(...);',
  217. '<?php $object?->method(1,); strlen(...);',
  218. ];
  219. }
  220. /**
  221. * @dataProvider provideFixNoTrailingCommaInSinglelineArrayFixerCases
  222. */
  223. public function testFixNoTrailingCommaInSinglelineArrayFixer(string $expected, ?string $input = null): void
  224. {
  225. $this->fixer->configure(['elements' => ['array']]);
  226. $this->doTest($expected, $input);
  227. }
  228. public static function provideFixNoTrailingCommaInSinglelineArrayFixerCases(): iterable
  229. {
  230. yield ['<?php $x = array();'];
  231. yield ['<?php $x = array("foo");'];
  232. yield [
  233. '<?php $x = array("foo");',
  234. '<?php $x = array("foo", );',
  235. ];
  236. yield ["<?php \$x = array(\n'foo', \n);"];
  237. yield ["<?php \$x = array('foo', \n);"];
  238. yield ["<?php \$x = array(array('foo'), \n);", "<?php \$x = array(array('foo',), \n);"];
  239. yield ["<?php \$x = array(array('foo',\n), \n);"];
  240. yield [
  241. '<?php
  242. $test = array("foo", <<<TWIG
  243. foo
  244. TWIG
  245. , $twig, );',
  246. ];
  247. yield [
  248. '<?php
  249. $test = array(
  250. "foo", <<<TWIG
  251. foo
  252. TWIG
  253. , $twig, );',
  254. ];
  255. yield [
  256. '<?php
  257. $test = array("foo", <<<\'TWIG\'
  258. foo
  259. TWIG
  260. , $twig, );',
  261. ];
  262. yield [
  263. '<?php
  264. $test = array(
  265. "foo", <<<\'TWIG\'
  266. foo
  267. TWIG
  268. , $twig, );',
  269. ];
  270. // Short syntax
  271. yield ['<?php $x = array([]);'];
  272. yield ['<?php $x = [[]];'];
  273. yield ['<?php $x = ["foo"];', '<?php $x = ["foo",];'];
  274. yield ['<?php $x = bar(["foo"]);', '<?php $x = bar(["foo",]);'];
  275. yield ["<?php \$x = bar([['foo'],\n]);"];
  276. yield ["<?php \$x = ['foo', \n];"];
  277. yield ['<?php $x = array([]);', '<?php $x = array([],);'];
  278. yield ['<?php $x = [[]];', '<?php $x = [[],];'];
  279. yield ['<?php $x = [$y[""]];', '<?php $x = [$y[""],];'];
  280. yield [
  281. '<?php
  282. $test = ["foo", <<<TWIG
  283. foo
  284. TWIG
  285. , $twig, ];',
  286. ];
  287. yield [
  288. '<?php
  289. $test = [
  290. "foo", <<<TWIG
  291. foo
  292. TWIG
  293. , $twig, ];',
  294. ];
  295. yield [
  296. '<?php
  297. $test = ["foo", <<<\'TWIG\'
  298. foo
  299. TWIG
  300. , $twig, ];',
  301. ];
  302. yield [
  303. '<?php
  304. $test = [
  305. "foo", <<<\'TWIG\'
  306. foo
  307. TWIG
  308. , $twig, ];',
  309. ];
  310. yield [
  311. '<?php $x = array(...$foo);',
  312. '<?php $x = array(...$foo, );',
  313. ];
  314. yield [
  315. '<?php $x = [...$foo];',
  316. '<?php $x = [...$foo, ];',
  317. ];
  318. }
  319. /**
  320. * @dataProvider provideFixNoTrailingCommaInListCallFixerCases
  321. */
  322. public function testFixNoTrailingCommaInListCallFixer(string $expected, ?string $input = null): void
  323. {
  324. $this->fixer->configure(['elements' => ['array_destructuring']]);
  325. $this->doTest($expected, $input);
  326. }
  327. public static function provideFixNoTrailingCommaInListCallFixerCases(): iterable
  328. {
  329. yield [
  330. '<?php
  331. list($a1, $b) = foo();
  332. list($a2, , $c, $d) = foo();
  333. list($a3, , $c) = foo();
  334. list($a4) = foo();
  335. list($a5 , $b) = foo();
  336. list($a6, /* $b */, $c) = foo();
  337. ',
  338. '<?php
  339. list($a1, $b) = foo();
  340. list($a2, , $c, $d, ) = foo();
  341. list($a3, , $c, , ) = foo();
  342. list($a4, , , , , ) = foo();
  343. list($a5 , $b , ) = foo();
  344. list($a6, /* $b */, $c, ) = foo();
  345. ',
  346. ];
  347. yield [
  348. '<?php
  349. list(
  350. $a#
  351. ,#
  352. #
  353. ) = $a;',
  354. ];
  355. yield [
  356. '<?php
  357. [$a7, $b] = foo();
  358. [$a8, , $c, $d] = foo();
  359. [$a9, , $c] = foo();
  360. [$a10] = foo();
  361. [$a11 , $b] = foo();
  362. [$a12, /* $b */, $c] = foo();
  363. ',
  364. '<?php
  365. [$a7, $b] = foo();
  366. [$a8, , $c, $d, ] = foo();
  367. [$a9, , $c, , ] = foo();
  368. [$a10, , , , , ] = foo();
  369. [$a11 , $b , ] = foo();
  370. [$a12, /* $b */, $c, ] = foo();
  371. ',
  372. ];
  373. }
  374. }