MethodArgumentSpaceFixerTest.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  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\FunctionNotation;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @author Kuanhung Chen <ericj.tw@gmail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer
  21. *
  22. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer>
  23. *
  24. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer
  25. */
  26. final class MethodArgumentSpaceFixerTest extends AbstractFixerTestCase
  27. {
  28. /**
  29. * @param _AutogeneratedInputConfiguration $configuration
  30. *
  31. * @dataProvider provideFixCases
  32. */
  33. public function testFix(string $expected, ?string $input = null, array $configuration = []): void
  34. {
  35. $indent = ' ';
  36. $lineEnding = "\n";
  37. if (str_contains($expected, "\t")) {
  38. $indent = "\t";
  39. } elseif (preg_match('/\n \S/', $expected)) {
  40. $indent = ' ';
  41. }
  42. if (str_contains($expected, "\r")) {
  43. $lineEnding = "\r\n";
  44. }
  45. $this->fixer->configure($configuration);
  46. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig(
  47. $indent,
  48. $lineEnding
  49. ));
  50. $this->doTest($expected, $input);
  51. }
  52. /**
  53. * @param _AutogeneratedInputConfiguration $configuration
  54. *
  55. * @dataProvider provideFixCases
  56. */
  57. public function testFixWithDifferentLineEndings(string $expected, ?string $input = null, array $configuration = []): void
  58. {
  59. if (null !== $input) {
  60. $input = str_replace("\n", "\r\n", $input);
  61. }
  62. $this->testFix(
  63. str_replace("\n", "\r\n", $expected),
  64. $input,
  65. $configuration
  66. );
  67. }
  68. public static function provideFixCases(): iterable
  69. {
  70. yield [
  71. '<?php
  72. // space '.'
  73. $var1 = $a->some_method(
  74. $var2
  75. );
  76. // space '.'
  77. $var2 = some_function(
  78. $var2
  79. );
  80. // space '.'
  81. $var2a = $z[1](
  82. $var2a
  83. );
  84. '.'
  85. $var3 = function( $a, $b ) { };
  86. ',
  87. '<?php
  88. // space '.'
  89. $var1 = $a->some_method(
  90. $var2);
  91. // space '.'
  92. $var2 = some_function(
  93. $var2);
  94. // space '.'
  95. $var2a = $z[1](
  96. $var2a
  97. );
  98. '.'
  99. $var3 = function( $a , $b ) { };
  100. ',
  101. [
  102. 'on_multiline' => 'ensure_fully_multiline',
  103. ],
  104. ];
  105. yield 'default' => [
  106. '<?php xyz("", "", "", "");',
  107. '<?php xyz("","","","");',
  108. ];
  109. yield 'test method arguments' => [
  110. '<?php function xyz($a=10, $b=20, $c=30) {}',
  111. '<?php function xyz($a=10,$b=20,$c=30) {}',
  112. ];
  113. yield 'test method arguments with multiple spaces' => [
  114. '<?php function xyz($a=10, $b=20, $c=30) {}',
  115. '<?php function xyz($a=10, $b=20 , $c=30) {}',
  116. ];
  117. yield 'test method arguments with multiple spaces (kmsac)' => [
  118. '<?php function xyz($a=10, $b=20, $c=30) {}',
  119. '<?php function xyz($a=10, $b=20 , $c=30) {}',
  120. ['keep_multiple_spaces_after_comma' => true],
  121. ];
  122. yield 'test method call (I)' => [
  123. '<?php xyz($a=10, $b=20, $c=30);',
  124. '<?php xyz($a=10 ,$b=20,$c=30);',
  125. ];
  126. yield 'test method call (II)' => [
  127. '<?php xyz($a=10, $b=20, $this->foo(), $c=30);',
  128. '<?php xyz($a=10,$b=20 ,$this->foo() ,$c=30);',
  129. ];
  130. yield 'test method call with multiple spaces (I)' => [
  131. '<?php xyz($a=10, $b=20, $c=30);',
  132. '<?php xyz($a=10 , $b=20 , $c=30);',
  133. ];
  134. yield 'test method call with multiple spaces (I) (kmsac)' => [
  135. '<?php xyz($a=10, $b=20, $c=30);',
  136. '<?php xyz($a=10 , $b=20 , $c=30);',
  137. ['keep_multiple_spaces_after_comma' => true],
  138. ];
  139. yield 'test method call with tab' => [
  140. '<?php xyz($a=10, $b=20, $c=30);',
  141. "<?php xyz(\$a=10 , \$b=20 ,\t \$c=30);",
  142. ];
  143. yield 'test method call with tab (kmsac)' => [
  144. "<?php xyz(\$a=10, \$b=20,\t \$c=30);",
  145. "<?php xyz(\$a=10 , \$b=20 ,\t \$c=30);",
  146. ['keep_multiple_spaces_after_comma' => true],
  147. ];
  148. yield 'test method call with multiple spaces (II)' => [
  149. '<?php xyz($a=10, $b=20, $this->foo(), $c=30);',
  150. '<?php xyz($a=10,$b=20 , $this->foo() ,$c=30);',
  151. ];
  152. yield 'test method call with multiple spaces (II) (kmsac)' => [
  153. '<?php xyz($a=10, $b=20, $this->foo(), $c=30);',
  154. '<?php xyz($a=10,$b=20 , $this->foo() ,$c=30);',
  155. ['keep_multiple_spaces_after_comma' => true],
  156. ];
  157. yield 'test named class constructor call' => [
  158. '<?php new Foo($a=10, $b=20, $this->foo(), $c=30);',
  159. '<?php new Foo($a=10,$b=20 ,$this->foo() ,$c=30);',
  160. ];
  161. yield 'test named class constructor call with multiple spaces' => [
  162. '<?php new Foo($a=10, $b=20, $c=30);',
  163. '<?php new Foo($a=10 , $b=20 , $c=30);',
  164. ];
  165. yield 'test named class constructor call with multiple spaces (kmsac)' => [
  166. '<?php new Foo($a=10, $b=20, $c=30);',
  167. '<?php new Foo($a=10 , $b=20 , $c=30);',
  168. ['keep_multiple_spaces_after_comma' => true],
  169. ];
  170. yield 'test anonymous class constructor call' => [
  171. '<?php new class ($a=10, $b=20, $this->foo(), $c=30) {};',
  172. '<?php new class ($a=10,$b=20 ,$this->foo() ,$c=30) {};',
  173. ];
  174. yield 'test anonymous class constructor call with multiple spaces' => [
  175. '<?php new class ($a=10, $b=20, $c=30) extends Foo {};',
  176. '<?php new class ($a=10 , $b=20 , $c=30) extends Foo {};',
  177. ];
  178. yield 'test anonymous class constructor call with multiple spaces (kmsac)' => [
  179. '<?php new class ($a=10, $b=20, $c=30) {};',
  180. '<?php new class ($a=10 , $b=20 , $c=30) {};',
  181. ['keep_multiple_spaces_after_comma' => true],
  182. ];
  183. yield 'test receiving data in list context with omitted values' => [
  184. '<?php list($a, $b, , , $c) = foo();',
  185. '<?php list($a, $b,, ,$c) = foo();',
  186. ];
  187. yield 'test receiving data in list context with omitted values and multiple spaces' => [
  188. '<?php list($a, $b, , , $c) = foo();',
  189. '<?php list($a, $b,, ,$c) = foo();',
  190. ];
  191. yield 'test receiving data in list context with omitted values and multiple spaces (kmsac)' => [
  192. '<?php list($a, $b, , , $c) = foo();',
  193. '<?php list($a, $b,, ,$c) = foo();',
  194. ['keep_multiple_spaces_after_comma' => true],
  195. ];
  196. yield 'skip array' => [
  197. '<?php array(10 , 20 ,30); $foo = [ 10,50 , 60 ] ?>',
  198. ];
  199. yield 'list call with trailing comma' => [
  200. '<?php list($path, $mode, ) = foo();',
  201. '<?php list($path, $mode,) = foo();',
  202. ];
  203. yield 'list call with trailing comma multi line' => [
  204. '<?php
  205. list(
  206. $a,
  207. $b,
  208. ) = foo();
  209. ',
  210. '<?php
  211. list(
  212. $a ,
  213. $b ,
  214. ) = foo();
  215. ',
  216. ];
  217. yield 'inline comments with spaces' => [
  218. '<?php xyz($a=10, /*comment1*/ $b=2000, /*comment2*/ $c=30);',
  219. '<?php xyz($a=10, /*comment1*/ $b=2000,/*comment2*/ $c=30);',
  220. ];
  221. yield 'inline comments with spaces (kmsac)' => [
  222. '<?php xyz($a=10, /*comment1*/ $b=2000, /*comment2*/ $c=30);',
  223. '<?php xyz($a=10, /*comment1*/ $b=2000,/*comment2*/ $c=30);',
  224. ['keep_multiple_spaces_after_comma' => true],
  225. ];
  226. yield 'multi line testing method call' => [
  227. '<?php if (1) {
  228. xyz(
  229. $a=10,
  230. $b=20,
  231. $c=30
  232. );
  233. }',
  234. '<?php if (1) {
  235. xyz(
  236. $a=10 ,
  237. $b=20,
  238. $c=30
  239. );
  240. }',
  241. ];
  242. yield 'multi line anonymous class constructor call' => [
  243. '<?php if (1) {
  244. new class (
  245. $a=10,
  246. $b=20,
  247. $c=30
  248. ) {};
  249. }',
  250. '<?php if (1) {
  251. new class (
  252. $a=10 ,
  253. $b=20,$c=30) {};
  254. }',
  255. ];
  256. yield 'skip arrays but replace arg methods' => [
  257. '<?php fnc(1, array(2, func2(6, 7) ,4), 5);',
  258. '<?php fnc(1,array(2, func2(6, 7) ,4), 5);',
  259. ];
  260. yield 'skip arrays but replace arg methods (kmsac)' => [
  261. '<?php fnc(1, array(2, func2(6, 7) ,4), 5);',
  262. '<?php fnc(1,array(2, func2(6, 7) ,4), 5);',
  263. ['keep_multiple_spaces_after_comma' => true],
  264. ];
  265. yield 'ignore commas inside call argument' => [
  266. '<?php fnc(1, array(2, 3 ,4), 5);',
  267. ];
  268. yield 'skip multi line array' => [
  269. '<?php
  270. array(
  271. 10 ,
  272. 20,
  273. 30
  274. );',
  275. ];
  276. yield 'skip short array' => [
  277. '<?php
  278. $foo = ["a"=>"apple", "b"=>"bed" ,"c"=>"car"];
  279. $bar = ["a" ,"b" ,"c"];
  280. ',
  281. ];
  282. yield 'don\'t change HEREDOC and NOWDOC' => [
  283. "<?php if (1) {
  284. \$this->foo(
  285. <<<EOTXTa
  286. heredoc
  287. EOTXTa
  288. ,
  289. <<<'EOTXTb'
  290. nowdoc
  291. EOTXTb
  292. ,
  293. 'foo'
  294. );
  295. }",
  296. ];
  297. yield 'with_random_comments on_multiline:ignore' => [
  298. '<?php xyz#
  299. (#
  300. ""#
  301. ,#
  302. $a#
  303. );',
  304. null,
  305. ['on_multiline' => 'ignore'],
  306. ];
  307. yield 'with_random_comments on_multiline:ensure_single_line' => [
  308. '<?php xyz#
  309. (#
  310. ""#
  311. ,#
  312. $a#
  313. );',
  314. null,
  315. ['on_multiline' => 'ensure_single_line'],
  316. ];
  317. yield 'with_random_comments on_multiline:ensure_fully_multiline' => [
  318. '<?php xyz#
  319. (#
  320. ""#
  321. ,#
  322. $a#
  323. );',
  324. '<?php xyz#
  325. (#
  326. ""#
  327. ,#
  328. $a#
  329. );',
  330. ['on_multiline' => 'ensure_fully_multiline'],
  331. ];
  332. yield 'test half-multiline function becomes fully-multiline' => [
  333. <<<'EXPECTED'
  334. <?php
  335. functionCall(
  336. 'a',
  337. 'b',
  338. 'c'
  339. );
  340. EXPECTED,
  341. <<<'INPUT'
  342. <?php
  343. functionCall(
  344. 'a', 'b',
  345. 'c'
  346. );
  347. INPUT,
  348. ];
  349. yield 'test wrongly formatted half-multiline function becomes fully-multiline' => [
  350. '<?php
  351. f(
  352. 1,
  353. 2,
  354. 3
  355. );',
  356. '<?php
  357. f(1,2,
  358. 3);',
  359. ];
  360. yield 'function calls with here doc cannot be anything but multiline' => [
  361. <<<'EXPECTED'
  362. <?php
  363. str_replace(
  364. "\n",
  365. PHP_EOL,
  366. <<<'TEXT'
  367. 1) someFile.php
  368. TEXT
  369. );
  370. EXPECTED,
  371. <<<'INPUT'
  372. <?php
  373. str_replace("\n", PHP_EOL, <<<'TEXT'
  374. 1) someFile.php
  375. TEXT
  376. );
  377. INPUT,
  378. ];
  379. yield 'test barely multiline function with blank lines becomes fully-multiline' => [
  380. <<<'EXPECTED'
  381. <?php
  382. functionCall(
  383. 'a',
  384. 'b',
  385. 'c'
  386. );
  387. EXPECTED,
  388. <<<'INPUT'
  389. <?php
  390. functionCall('a', 'b',
  391. 'c');
  392. INPUT,
  393. ];
  394. yield 'test indentation is preserved' => [
  395. <<<'EXPECTED'
  396. <?php
  397. if (true) {
  398. functionCall(
  399. 'a',
  400. 'b',
  401. 'c'
  402. );
  403. }
  404. EXPECTED,
  405. <<<'INPUT'
  406. <?php
  407. if (true) {
  408. functionCall(
  409. 'a', 'b',
  410. 'c'
  411. );
  412. }
  413. INPUT,
  414. ];
  415. yield 'test multiline array arguments do not trigger multiline' => [
  416. <<<'EXPECTED'
  417. <?php
  418. defraculate(1, array(
  419. 'a',
  420. 'b',
  421. 'c',
  422. ), 42);
  423. EXPECTED,
  424. ];
  425. yield 'test multiline function arguments do not trigger multiline' => [
  426. <<<'EXPECTED'
  427. <?php
  428. defraculate(1, function () {
  429. $a = 42;
  430. }, 42);
  431. EXPECTED,
  432. ];
  433. yield 'test violation after opening parenthesis' => [
  434. <<<'EXPECTED'
  435. <?php
  436. defraculate(
  437. 1,
  438. 2,
  439. 3
  440. );
  441. EXPECTED,
  442. <<<'INPUT'
  443. <?php
  444. defraculate(
  445. 1, 2, 3);
  446. INPUT,
  447. ];
  448. yield 'test violation after opening parenthesis, indented with two spaces' => [
  449. <<<'EXPECTED'
  450. <?php
  451. defraculate(
  452. 1,
  453. 2,
  454. 3
  455. );
  456. EXPECTED,
  457. <<<'INPUT'
  458. <?php
  459. defraculate(
  460. 1, 2, 3);
  461. INPUT,
  462. ];
  463. yield 'test violation after opening parenthesis, indented with tabs' => [
  464. <<<'EXPECTED'
  465. <?php
  466. defraculate(
  467. 1,
  468. 2,
  469. 3
  470. );
  471. EXPECTED,
  472. <<<'INPUT'
  473. <?php
  474. defraculate(
  475. 1, 2, 3);
  476. INPUT,
  477. ];
  478. yield 'test violation before closing parenthesis' => [
  479. <<<'EXPECTED'
  480. <?php
  481. defraculate(
  482. 1,
  483. 2,
  484. 3
  485. );
  486. EXPECTED,
  487. <<<'INPUT'
  488. <?php
  489. defraculate(1, 2, 3
  490. );
  491. INPUT,
  492. ];
  493. yield 'test violation before closing parenthesis in nested call' => [
  494. <<<'EXPECTED'
  495. <?php
  496. getSchwifty('rick', defraculate(
  497. 1,
  498. 2,
  499. 3
  500. ), 'morty');
  501. EXPECTED,
  502. <<<'INPUT'
  503. <?php
  504. getSchwifty('rick', defraculate(1, 2, 3
  505. ), 'morty');
  506. INPUT,
  507. ];
  508. yield 'test with comment between arguments' => [
  509. <<<'EXPECTED'
  510. <?php
  511. functionCall(
  512. 'a', /* comment */
  513. 'b',
  514. 'c'
  515. );
  516. EXPECTED,
  517. <<<'INPUT'
  518. <?php
  519. functionCall(
  520. 'a',/* comment */'b',
  521. 'c'
  522. );
  523. INPUT,
  524. ];
  525. yield 'test with deeply nested arguments' => [
  526. <<<'EXPECTED'
  527. <?php
  528. foo(
  529. 'a',
  530. 'b',
  531. [
  532. 'c',
  533. 'd', bar('e', 'f'),
  534. baz(
  535. 'g',
  536. ['h',
  537. 'i',
  538. ]
  539. ),
  540. ]
  541. );
  542. EXPECTED,
  543. <<<'INPUT'
  544. <?php
  545. foo('a',
  546. 'b',
  547. [
  548. 'c',
  549. 'd', bar('e', 'f'),
  550. baz('g',
  551. ['h',
  552. 'i',
  553. ]),
  554. ]);
  555. INPUT,
  556. ];
  557. yield 'multiline string argument' => [
  558. <<<'UNAFFECTED'
  559. <?php
  560. $this->with('<?php
  561. %s
  562. class FooClass
  563. {
  564. }', $comment, false);
  565. UNAFFECTED,
  566. ];
  567. yield 'arrays with whitespace inside' => [
  568. <<<'UNAFFECTED'
  569. <?php
  570. $a = array/**/( 1);
  571. $a = array/**/( 12,
  572. 7);
  573. $a = array/***/(123, 7);
  574. $a = array ( 1,
  575. 2);
  576. UNAFFECTED,
  577. ];
  578. yield 'test code that should not be affected (because not a function nor a method)' => [
  579. <<<'UNAFFECTED'
  580. <?php
  581. if (true &&
  582. true
  583. ) {
  584. // do whatever
  585. }
  586. UNAFFECTED,
  587. ];
  588. yield 'test ungodly code' => [
  589. <<<'EXPECTED'
  590. <?php
  591. $a = function#
  592. (#
  593. #
  594. $a#
  595. #
  596. ,#
  597. #
  598. $b,
  599. $c#
  600. #
  601. )#
  602. use (
  603. $b1,
  604. $c1,
  605. $d1
  606. ) {
  607. };
  608. EXPECTED,
  609. <<<'INPUT'
  610. <?php
  611. $a = function#
  612. (#
  613. #
  614. $a#
  615. #
  616. ,#
  617. #
  618. $b,$c#
  619. #
  620. )#
  621. use ($b1,
  622. $c1,$d1) {
  623. };
  624. INPUT,
  625. ];
  626. yield 'test list' => [
  627. <<<'UNAFFECTED'
  628. <?php
  629. // no fix
  630. list($a,
  631. $b, $c) = $a;
  632. isset($a,
  633. $b, $c);
  634. unset($a,
  635. $b, $c);
  636. array(1,
  637. 2,3
  638. );
  639. UNAFFECTED,
  640. ];
  641. yield 'test function argument with multiline echo in it' => [
  642. <<<'UNAFFECTED'
  643. <?php
  644. call_user_func(function ($arguments) {
  645. echo 'a',
  646. 'b';
  647. }, $argv);
  648. UNAFFECTED,
  649. ];
  650. yield 'test function argument with oneline echo in it' => [
  651. <<<'EXPECTED'
  652. <?php
  653. call_user_func(
  654. function ($arguments) {
  655. echo 'a', 'b';
  656. },
  657. $argv
  658. );
  659. EXPECTED,
  660. <<<'INPUT'
  661. <?php
  662. call_user_func(function ($arguments) {
  663. echo 'a', 'b';
  664. },
  665. $argv);
  666. INPUT,
  667. ];
  668. yield 'ensure_single_line' => [
  669. <<<'EXPECTED'
  670. <?php
  671. function foo($a, $b) {
  672. // foo
  673. }
  674. foo($a, $b);
  675. EXPECTED,
  676. <<<'INPUT'
  677. <?php
  678. function foo(
  679. $a,
  680. $b
  681. ) {
  682. // foo
  683. }
  684. foo(
  685. $a,
  686. $b
  687. );
  688. INPUT,
  689. ['on_multiline' => 'ensure_single_line'],
  690. ];
  691. yield 'ensure_single_line_with_random_comments' => [
  692. <<<'EXPECTED'
  693. <?php
  694. function foo(/* foo */// bar
  695. $a, /* foo */// bar
  696. $b#foo
  697. ) {
  698. // foo
  699. }
  700. foo(/* foo */// bar
  701. $a, /* foo */// bar
  702. $b#foo
  703. );
  704. EXPECTED,
  705. null,
  706. ['on_multiline' => 'ensure_single_line'],
  707. ];
  708. yield 'ensure_single_line_with_consecutive_newlines' => [
  709. <<<'EXPECTED'
  710. <?php
  711. function foo($a, $b) {
  712. // foo
  713. }
  714. foo($a, $b);
  715. EXPECTED,
  716. <<<'INPUT'
  717. <?php
  718. function foo(
  719. $a,
  720. $b
  721. ) {
  722. // foo
  723. }
  724. foo(
  725. $a,
  726. $b
  727. );
  728. INPUT,
  729. ['on_multiline' => 'ensure_single_line'],
  730. ];
  731. yield 'ensure_single_line_methods' => [
  732. <<<'EXPECTED'
  733. <?php
  734. class Foo {
  735. public static function foo1($a, $b, $c) {}
  736. private function foo2($a, $b, $c) {}
  737. }
  738. EXPECTED,
  739. <<<'INPUT'
  740. <?php
  741. class Foo {
  742. public static function foo1(
  743. $a,
  744. $b,
  745. $c
  746. ) {}
  747. private function foo2(
  748. $a,
  749. $b,
  750. $c
  751. ) {}
  752. }
  753. INPUT,
  754. ['on_multiline' => 'ensure_single_line'],
  755. ];
  756. yield 'ensure_single_line_methods_in_anonymous_class' => [
  757. <<<'EXPECTED'
  758. <?php
  759. new class {
  760. public static function foo1($a, $b, $c) {}
  761. private function foo2($a, $b, $c) {}
  762. };
  763. EXPECTED,
  764. <<<'INPUT'
  765. <?php
  766. new class {
  767. public static function foo1(
  768. $a,
  769. $b,
  770. $c
  771. ) {}
  772. private function foo2(
  773. $a,
  774. $b,
  775. $c
  776. ) {}
  777. };
  778. INPUT,
  779. ['on_multiline' => 'ensure_single_line'],
  780. ];
  781. yield 'ensure_single_line_keep_spaces_after_comma' => [
  782. <<<'EXPECTED'
  783. <?php
  784. function foo($a, $b) {
  785. // foo
  786. }
  787. foo($a, $b);
  788. EXPECTED,
  789. <<<'INPUT'
  790. <?php
  791. function foo(
  792. $a,
  793. $b
  794. ) {
  795. // foo
  796. }
  797. foo(
  798. $a,
  799. $b
  800. );
  801. INPUT,
  802. [
  803. 'on_multiline' => 'ensure_single_line',
  804. 'keep_multiple_spaces_after_comma' => true,
  805. ],
  806. ];
  807. yield 'fix closing parenthesis (without trailing comma)' => [
  808. '<?php
  809. if (true) {
  810. execute(
  811. $foo,
  812. $bar
  813. );
  814. }',
  815. '<?php
  816. if (true) {
  817. execute(
  818. $foo,
  819. $bar
  820. );
  821. }',
  822. [
  823. 'on_multiline' => 'ensure_fully_multiline',
  824. ],
  825. ];
  826. yield 'test anonymous functions' => [
  827. '<?php
  828. $example = function () use ($message1, $message2) {
  829. };',
  830. '<?php
  831. $example = function () use ($message1,$message2) {
  832. };',
  833. ];
  834. yield 'test first element in same line, space before comma and inconsistent indent' => [
  835. '<?php foo(
  836. "aaa
  837. bbb",
  838. $c,
  839. $d,
  840. $e,
  841. $f
  842. );
  843. ',
  844. '<?php foo("aaa
  845. bbb",
  846. $c, $d ,
  847. $e,
  848. $f);
  849. ',
  850. ];
  851. yield 'test first element in same line, space before comma and inconsistent indent with comments' => [
  852. '<?php foo(
  853. "aaa
  854. bbb", // comment1
  855. $c, /** comment2 */
  856. $d,
  857. $e/* comment3 */,
  858. $f
  859. );# comment4
  860. ',
  861. '<?php foo("aaa
  862. bbb", // comment1
  863. $c, /** comment2 */$d ,
  864. $e/* comment3 */,
  865. $f);# comment4
  866. ',
  867. ];
  868. yield [
  869. '<?php
  870. foo(
  871. /* bar */
  872. "baz"
  873. );
  874. ',
  875. '<?php
  876. foo(
  877. /* bar */ "baz"
  878. );
  879. ',
  880. ];
  881. yield [<<<'PHP'
  882. <?php
  883. function f()
  884. {
  885. echo <<<TEXT
  886. some text
  887. {$object->method(
  888. 42
  889. )}
  890. some text
  891. TEXT;
  892. }
  893. PHP];
  894. yield [<<<'PHP'
  895. <?php
  896. function f()
  897. {
  898. echo <<<'TEXT'
  899. some text
  900. {$object->method(
  901. 42
  902. )}
  903. some text
  904. TEXT;
  905. }
  906. PHP];
  907. yield [<<<'PHP'
  908. <?php
  909. function f()
  910. {
  911. echo <<<TEXT
  912. some text
  913. some value: {$object->method(
  914. 42
  915. )}
  916. some text
  917. TEXT;
  918. }
  919. PHP];
  920. }
  921. /**
  922. * @param _AutogeneratedInputConfiguration $config
  923. *
  924. * @dataProvider provideFix2Cases
  925. */
  926. public function testFix2(string $expected, ?string $input = null, array $config = []): void
  927. {
  928. $this->fixer->configure($config);
  929. $this->doTest($expected, $input);
  930. }
  931. public static function provideFix2Cases(): iterable
  932. {
  933. yield [
  934. '<?php function A($c, ...$a){}',
  935. '<?php function A($c ,...$a){}',
  936. ];
  937. yield [
  938. <<<'EXPECTED'
  939. <?php
  940. foo(
  941. <<<'EOD'
  942. bar
  943. EOD,
  944. 'baz'
  945. );
  946. EXPECTED,
  947. <<<'INPUT'
  948. <?php
  949. foo(
  950. <<<'EOD'
  951. bar
  952. EOD
  953. ,
  954. 'baz'
  955. );
  956. INPUT,
  957. ['after_heredoc' => true],
  958. ];
  959. yield [
  960. <<<'EXPECTED'
  961. <?php
  962. foo(
  963. $bar,
  964. $baz,
  965. );
  966. EXPECTED,
  967. null,
  968. ['on_multiline' => 'ensure_fully_multiline'],
  969. ];
  970. yield [
  971. '<?php
  972. functionCall(
  973. 1,
  974. 2,
  975. 3,
  976. );',
  977. '<?php
  978. functionCall(
  979. 1, 2,
  980. 3,
  981. );',
  982. [
  983. 'on_multiline' => 'ensure_fully_multiline',
  984. ],
  985. ];
  986. yield [
  987. '<?php foo(1, 2, 3, );',
  988. '<?php foo(1,2,3,);',
  989. ];
  990. yield [
  991. '<?php
  992. $fn = fn(
  993. $test1,
  994. $test2
  995. ) => null;',
  996. '<?php
  997. $fn = fn(
  998. $test1, $test2
  999. ) => null;',
  1000. [
  1001. 'on_multiline' => 'ensure_fully_multiline',
  1002. ],
  1003. ];
  1004. }
  1005. /**
  1006. * @param _AutogeneratedInputConfiguration $config
  1007. *
  1008. * @dataProvider provideFix80Cases
  1009. *
  1010. * @requires PHP 8.0
  1011. */
  1012. public function testFix80(string $expected, ?string $input = null, array $config = []): void
  1013. {
  1014. $this->fixer->configure($config);
  1015. $this->doTest($expected, $input);
  1016. }
  1017. public static function provideFix80Cases(): iterable
  1018. {
  1019. yield 'multiple attributes' => [
  1020. '<?php
  1021. class MyClass
  1022. {
  1023. public function __construct(
  1024. private string $id,
  1025. #[Foo]
  1026. #[Bar]
  1027. private ?string $name = null,
  1028. ) {}
  1029. }',
  1030. '<?php
  1031. class MyClass
  1032. {
  1033. public function __construct(
  1034. private string $id,
  1035. #[Foo] #[Bar] private ?string $name = null,
  1036. ) {}
  1037. }',
  1038. ];
  1039. yield 'keep attributes as-is' => [
  1040. '<?php
  1041. class MyClass
  1042. {
  1043. public function __construct(
  1044. private string $id,
  1045. #[Foo] #[Bar] private ?string $name = null,
  1046. ) {}
  1047. }',
  1048. null,
  1049. [
  1050. 'attribute_placement' => 'ignore',
  1051. ],
  1052. ];
  1053. yield 'multiple attributes on the same line as argument' => [
  1054. '<?php
  1055. class MyClass
  1056. {
  1057. public function __construct(
  1058. private string $id,
  1059. #[Foo] #[Bar] private ?string $name = null,
  1060. ) {}
  1061. }',
  1062. '<?php
  1063. class MyClass
  1064. {
  1065. public function __construct(
  1066. private string $id,
  1067. #[Foo]
  1068. #[Bar]
  1069. private ?string $name = null,
  1070. ) {}
  1071. }',
  1072. [
  1073. 'attribute_placement' => 'same_line',
  1074. ],
  1075. ];
  1076. yield 'single attribute markup with comma separated list' => [
  1077. '<?php
  1078. class MyClass
  1079. {
  1080. public function __construct(
  1081. private string $id,
  1082. #[Foo, Bar]
  1083. private ?string $name = null,
  1084. ) {}
  1085. }',
  1086. '<?php
  1087. class MyClass
  1088. {
  1089. public function __construct(
  1090. private string $id,
  1091. #[Foo, Bar] private ?string $name = null,
  1092. ) {}
  1093. }',
  1094. ];
  1095. yield 'attributes with arguments' => [
  1096. '<?php
  1097. class MyClass
  1098. {
  1099. public function __construct(
  1100. private string $id,
  1101. #[Foo(value: 1234, otherValue: [1, 2, 3])]
  1102. #[Bar(Bar::BAZ, array(\'[\',\']\'))]
  1103. private ?string $name = null,
  1104. ) {}
  1105. }',
  1106. '<?php
  1107. class MyClass
  1108. {
  1109. public function __construct(
  1110. private string $id,
  1111. #[Foo(value: 1234, otherValue: [1, 2, 3])] #[Bar(Bar::BAZ, array(\'[\',\']\'))] private ?string $name = null,
  1112. ) {}
  1113. }',
  1114. ];
  1115. yield 'fully qualified attributes' => [
  1116. '<?php
  1117. function foo(
  1118. #[\Foo\Bar]
  1119. $bar,
  1120. #[\Foo\Baz]
  1121. $baz,
  1122. #[\Foo\Buzz]
  1123. $buzz
  1124. ) {}',
  1125. '<?php
  1126. function foo(
  1127. #[\Foo\Bar] $bar, #[\Foo\Baz] $baz, #[\Foo\Buzz] $buzz
  1128. ) {}',
  1129. ];
  1130. yield 'multiline attributes' => [
  1131. '<?php
  1132. function foo(
  1133. $foo,
  1134. #[
  1135. Foo\Bar,
  1136. Foo\Baz,
  1137. Foo\Buzz(a: \'astral\', b: 1234),
  1138. ]
  1139. $bar
  1140. ) {}',
  1141. '<?php
  1142. function foo($foo, #[
  1143. Foo\Bar,
  1144. Foo\Baz,
  1145. Foo\Buzz(a: \'astral\', b: 1234),
  1146. ] $bar) {}',
  1147. ];
  1148. }
  1149. /**
  1150. * @dataProvider provideFix81Cases
  1151. *
  1152. * @requires PHP 8.1
  1153. */
  1154. public function testFix81(string $expected, ?string $input = null): void
  1155. {
  1156. $this->doTest($expected, $input);
  1157. }
  1158. /**
  1159. * @return iterable<array{string, string}>
  1160. */
  1161. public static function provideFix81Cases(): iterable
  1162. {
  1163. yield [
  1164. '<?php
  1165. [Foo::class, \'method\'](
  1166. ...
  1167. ) ?>',
  1168. '<?php
  1169. [Foo::class, \'method\']( ...
  1170. ) ?>',
  1171. ];
  1172. }
  1173. }