ArrayIndentationFixerTest.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  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\Whitespace;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\WhitespacesFixerConfig;
  15. /**
  16. * @internal
  17. *
  18. * @covers \PhpCsFixer\Fixer\Whitespace\ArrayIndentationFixer
  19. */
  20. final class ArrayIndentationFixerTest extends AbstractFixerTestCase
  21. {
  22. /**
  23. * @dataProvider provideFixCases
  24. */
  25. public function testFix(string $expected, ?string $input = null): void
  26. {
  27. $this->doTest($expected, $input);
  28. }
  29. public static function provideFixCases(): iterable
  30. {
  31. return self::withLongArraySyntaxCases([
  32. [
  33. <<<'EXPECTED'
  34. <?php
  35. $foo = [
  36. 'foo',
  37. 'bar' => 'baz',
  38. ];
  39. EXPECTED
  40. ,
  41. <<<'INPUT'
  42. <?php
  43. $foo = [
  44. 'foo',
  45. 'bar' => 'baz',
  46. ];
  47. INPUT
  48. ,
  49. ],
  50. [
  51. <<<'EXPECTED'
  52. <?php
  53. $foo = [
  54. 'foo',
  55. 'bar' => 'baz',
  56. ];
  57. EXPECTED
  58. ,
  59. <<<'INPUT'
  60. <?php
  61. $foo = [
  62. 'foo',
  63. 'bar' => 'baz',
  64. ];
  65. INPUT
  66. ,
  67. ],
  68. [
  69. <<<'EXPECTED'
  70. <?php
  71. $foo = [
  72. ['bar', 'baz'],
  73. [
  74. 'bar',
  75. 'baz'
  76. ],
  77. ];
  78. EXPECTED
  79. ,
  80. <<<'INPUT'
  81. <?php
  82. $foo = [
  83. ['bar', 'baz'],
  84. [
  85. 'bar',
  86. 'baz'
  87. ],
  88. ];
  89. INPUT
  90. ,
  91. ],
  92. [
  93. <<<'EXPECTED'
  94. <?php
  95. $foo = [
  96. ['foo',
  97. 'bar',
  98. ['foo',
  99. 'bar',
  100. ['foo',
  101. 'bar',
  102. 'baz']],
  103. 'baz'],
  104. ];
  105. EXPECTED
  106. ,
  107. <<<'INPUT'
  108. <?php
  109. $foo = [
  110. ['foo',
  111. 'bar',
  112. ['foo',
  113. 'bar',
  114. ['foo',
  115. 'bar',
  116. 'baz']],
  117. 'baz'],
  118. ];
  119. INPUT
  120. ,
  121. ],
  122. [
  123. <<<'EXPECTED'
  124. <?php
  125. class Foo
  126. {
  127. public $foo = [
  128. ['bar', 'baz'],
  129. [
  130. 'bar',
  131. 'baz'
  132. ],
  133. ];
  134. public function bar()
  135. {
  136. return [
  137. ['bar', 'baz'],
  138. [
  139. 'bar',
  140. 'baz'
  141. ],
  142. ];
  143. }
  144. }
  145. EXPECTED
  146. ,
  147. <<<'INPUT'
  148. <?php
  149. class Foo
  150. {
  151. public $foo = [
  152. ['bar', 'baz'],
  153. [
  154. 'bar',
  155. 'baz'
  156. ],
  157. ];
  158. public function bar()
  159. {
  160. return [
  161. ['bar', 'baz'],
  162. [
  163. 'bar',
  164. 'baz'
  165. ],
  166. ];
  167. }
  168. }
  169. INPUT
  170. ,
  171. ],
  172. [
  173. <<<'EXPECTED'
  174. <?php
  175. $foo = [
  176. 'foo' => foo(
  177. 1,
  178. 2
  179. ),
  180. 'bar' => bar(
  181. 1,
  182. 2
  183. ),
  184. 'baz' => baz(
  185. 1,
  186. 2
  187. ),
  188. ];
  189. EXPECTED
  190. ,
  191. <<<'INPUT'
  192. <?php
  193. $foo = [
  194. 'foo' => foo(
  195. 1,
  196. 2
  197. ),
  198. 'bar' => bar(
  199. 1,
  200. 2
  201. ),
  202. 'baz' => baz(
  203. 1,
  204. 2
  205. ),
  206. ];
  207. INPUT
  208. ,
  209. ],
  210. [
  211. <<<'EXPECTED'
  212. <?php
  213. $foo = [
  214. 'foo' => ['bar' => [
  215. 'baz',
  216. ]],
  217. 'qux',
  218. ];
  219. EXPECTED
  220. ,
  221. <<<'INPUT'
  222. <?php
  223. $foo = [
  224. 'foo' => ['bar' => [
  225. 'baz',
  226. ]],
  227. 'qux',
  228. ];
  229. INPUT
  230. ,
  231. ],
  232. [
  233. <<<'EXPECTED'
  234. <?php
  235. $foo = [
  236. 'foo' => [
  237. (new Foo())
  238. ->foo(),
  239. ],
  240. ];
  241. EXPECTED
  242. ,
  243. <<<'INPUT'
  244. <?php
  245. $foo = [
  246. 'foo' => [
  247. (new Foo())
  248. ->foo(),
  249. ],
  250. ];
  251. INPUT
  252. ,
  253. ],
  254. [
  255. <<<'EXPECTED'
  256. <?php
  257. $foo = [
  258. [new Foo(
  259. )],
  260. [new Foo(
  261. )],
  262. ];
  263. EXPECTED
  264. ,
  265. <<<'INPUT'
  266. <?php
  267. $foo = [
  268. [new Foo(
  269. )],
  270. [new Foo(
  271. )],
  272. ];
  273. INPUT
  274. ,
  275. ],
  276. [
  277. <<<'EXPECTED'
  278. <?php
  279. $foo = new Foo([
  280. (new Bar())
  281. ->foo([
  282. 'foo',
  283. 'foo',
  284. ])
  285. ->bar(['bar', 'bar'])
  286. ->baz([
  287. 'baz',
  288. 'baz',
  289. ])
  290. ,
  291. ]);
  292. EXPECTED
  293. ,
  294. <<<'INPUT'
  295. <?php
  296. $foo = new Foo([
  297. (new Bar())
  298. ->foo([
  299. 'foo',
  300. 'foo',
  301. ])
  302. ->bar(['bar', 'bar'])
  303. ->baz([
  304. 'baz',
  305. 'baz',
  306. ])
  307. ,
  308. ]);
  309. INPUT
  310. ,
  311. ],
  312. [
  313. <<<'EXPECTED'
  314. <?php
  315. class Foo
  316. {
  317. public function bar()
  318. {
  319. $foo = [
  320. 'foo',
  321. 'foo',
  322. ];
  323. $bar = [
  324. 'bar',
  325. 'bar',
  326. ];
  327. }
  328. }
  329. EXPECTED
  330. ,
  331. <<<'INPUT'
  332. <?php
  333. class Foo
  334. {
  335. public function bar()
  336. {
  337. $foo = [
  338. 'foo',
  339. 'foo',
  340. ];
  341. $bar = [
  342. 'bar',
  343. 'bar',
  344. ];
  345. }
  346. }
  347. INPUT
  348. ,
  349. ],
  350. [
  351. <<<'EXPECTED'
  352. <?php
  353. class Foo
  354. {
  355. public function bar()
  356. {
  357. return new Bar([
  358. (new Baz())
  359. ->qux([function ($a) {
  360. foreach ($a as $b) {
  361. if ($b) {
  362. throw new Exception(sprintf(
  363. 'Oops: %s',
  364. $b
  365. ));
  366. }
  367. }
  368. }]),
  369. ]);
  370. }
  371. }
  372. EXPECTED
  373. ,
  374. <<<'INPUT'
  375. <?php
  376. class Foo
  377. {
  378. public function bar()
  379. {
  380. return new Bar([
  381. (new Baz())
  382. ->qux([function ($a) {
  383. foreach ($a as $b) {
  384. if ($b) {
  385. throw new Exception(sprintf(
  386. 'Oops: %s',
  387. $b
  388. ));
  389. }
  390. }
  391. }]),
  392. ]);
  393. }
  394. }
  395. INPUT
  396. ,
  397. ],
  398. [
  399. <<<'EXPECTED'
  400. <?php
  401. $foo = [
  402. 'Foo'.
  403. foo()
  404. .bar()
  405. ,
  406. ];
  407. EXPECTED
  408. ,
  409. <<<'INPUT'
  410. <?php
  411. $foo = [
  412. 'Foo'.
  413. foo()
  414. .bar()
  415. ,
  416. ];
  417. INPUT
  418. ,
  419. ],
  420. [
  421. <<<'EXPECTED'
  422. <?php
  423. $foo = [
  424. [new \stdClass()],
  425. 'foo',
  426. ];
  427. EXPECTED
  428. ,
  429. <<<'INPUT'
  430. <?php
  431. $foo = [
  432. [new \stdClass()],
  433. 'foo',
  434. ];
  435. INPUT
  436. ,
  437. ],
  438. [
  439. <<<'EXPECTED'
  440. <?php
  441. $foo = [
  442. $bar
  443. ? 'bar'
  444. : 'foo'
  445. ,
  446. ];
  447. EXPECTED
  448. ,
  449. <<<'INPUT'
  450. <?php
  451. $foo = [
  452. $bar
  453. ? 'bar'
  454. : 'foo'
  455. ,
  456. ];
  457. INPUT
  458. ,
  459. ],
  460. [
  461. <<<'EXPECTED'
  462. <?php
  463. $foo = [
  464. $bar ?
  465. 'bar' :
  466. 'foo'
  467. ,
  468. ];
  469. EXPECTED
  470. ,
  471. <<<'INPUT'
  472. <?php
  473. $foo = [
  474. $bar ?
  475. 'bar' :
  476. 'foo'
  477. ,
  478. ];
  479. INPUT
  480. ,
  481. ],
  482. [
  483. <<<'EXPECTED'
  484. <?php
  485. $foo = [
  486. [
  487. 'foo',
  488. ], [
  489. 'bar',
  490. ],
  491. ];
  492. EXPECTED
  493. ,
  494. <<<'INPUT'
  495. <?php
  496. $foo = [
  497. [
  498. 'foo',
  499. ], [
  500. 'bar',
  501. ],
  502. ];
  503. INPUT
  504. ,
  505. ],
  506. [
  507. <<<'EXPECTED'
  508. <?php
  509. $foo = [
  510. 'foo', // comment
  511. 'bar',
  512. ];
  513. EXPECTED
  514. ,
  515. <<<'INPUT'
  516. <?php
  517. $foo = [
  518. 'foo', // comment
  519. 'bar',
  520. ];
  521. INPUT
  522. ,
  523. ],
  524. [
  525. <<<'EXPECTED'
  526. <?php
  527. $foo = [[[
  528. 'foo',
  529. 'bar',
  530. ],
  531. ],
  532. ];
  533. EXPECTED
  534. ,
  535. <<<'INPUT'
  536. <?php
  537. $foo = [[[
  538. 'foo',
  539. 'bar',
  540. ],
  541. ],
  542. ];
  543. INPUT
  544. ,
  545. ],
  546. [
  547. <<<'EXPECTED'
  548. <?php
  549. $foo = [
  550. [
  551. [
  552. 'foo',
  553. 'bar',
  554. ]]];
  555. EXPECTED
  556. ,
  557. <<<'INPUT'
  558. <?php
  559. $foo = [
  560. [
  561. [
  562. 'foo',
  563. 'bar',
  564. ]]];
  565. INPUT
  566. ,
  567. ],
  568. [
  569. <<<'EXPECTED'
  570. <?php
  571. $foo = [
  572. [
  573. [[
  574. [[[
  575. 'foo',
  576. 'bar',
  577. ]
  578. ]]
  579. ]
  580. ]
  581. ]];
  582. EXPECTED
  583. ,
  584. <<<'INPUT'
  585. <?php
  586. $foo = [
  587. [
  588. [[
  589. [[[
  590. 'foo',
  591. 'bar',
  592. ]
  593. ]]
  594. ]
  595. ]
  596. ]];
  597. INPUT
  598. ,
  599. ],
  600. [
  601. <<<'EXPECTED'
  602. <?php
  603. $foo = [[
  604. [
  605. [[[],[[
  606. [[[
  607. 'foo',
  608. 'bar',
  609. ],[[],[]]]
  610. ]],[
  611. 'baz',
  612. ]]
  613. ],[]],[]]
  614. ]
  615. ];
  616. EXPECTED
  617. ,
  618. <<<'INPUT'
  619. <?php
  620. $foo = [[
  621. [
  622. [[[],[[
  623. [[[
  624. 'foo',
  625. 'bar',
  626. ],[[],[]]]
  627. ]],[
  628. 'baz',
  629. ]]
  630. ],[]],[]]
  631. ]
  632. ];
  633. INPUT
  634. ,
  635. ],
  636. [
  637. <<<'EXPECTED'
  638. <?php if ($foo): ?>
  639. <?php foo([
  640. 'bar',
  641. 'baz',
  642. ]) ?>
  643. <?php endif ?>
  644. EXPECTED
  645. ,
  646. <<<'INPUT'
  647. <?php if ($foo): ?>
  648. <?php foo([
  649. 'bar',
  650. 'baz',
  651. ]) ?>
  652. <?php endif ?>
  653. INPUT
  654. ,
  655. ],
  656. [
  657. <<<'EXPECTED'
  658. <div>
  659. <a
  660. class="link"
  661. href="<?= Url::to([
  662. '/site/page',
  663. 'id' => 123,
  664. ]); ?>"
  665. >
  666. Link text
  667. </a>
  668. </div>
  669. EXPECTED
  670. ,
  671. <<<'INPUT'
  672. <div>
  673. <a
  674. class="link"
  675. href="<?= Url::to([
  676. '/site/page',
  677. 'id' => 123,
  678. ]); ?>"
  679. >
  680. Link text
  681. </a>
  682. </div>
  683. INPUT
  684. ,
  685. ],
  686. [
  687. <<<'EXPECTED'
  688. <?php
  689. $arr = [
  690. 'a' => 'b',
  691. // 'c' => 'd',
  692. ];
  693. EXPECTED
  694. ,
  695. <<<'INPUT'
  696. <?php
  697. $arr = [
  698. 'a' => 'b',
  699. // 'c' => 'd',
  700. ];
  701. INPUT
  702. ,
  703. ],
  704. [
  705. '<?php
  706. '.'
  707. $foo = [
  708. "foo",
  709. "bar",
  710. ];',
  711. ],
  712. [
  713. <<<'EXPECTED'
  714. <?php
  715. $foo = [
  716. 'foo' =>
  717. 'Some'
  718. .' long'
  719. .' string',
  720. 'bar' =>
  721. 'Another'
  722. .' long'
  723. .' string'
  724. ];
  725. EXPECTED
  726. ,
  727. <<<'INPUT'
  728. <?php
  729. $foo = [
  730. 'foo' =>
  731. 'Some'
  732. .' long'
  733. .' string',
  734. 'bar' =>
  735. 'Another'
  736. .' long'
  737. .' string'
  738. ];
  739. INPUT
  740. ,
  741. ],
  742. [
  743. <<<'EXPECTED'
  744. <?php
  745. $foo = [
  746. $test
  747. ? [
  748. 123,
  749. ]
  750. : [
  751. 321,
  752. ],
  753. ];
  754. EXPECTED
  755. ,
  756. <<<'INPUT'
  757. <?php
  758. $foo = [
  759. $test
  760. ? [
  761. 123,
  762. ]
  763. : [
  764. 321,
  765. ],
  766. ];
  767. INPUT
  768. ,
  769. ],
  770. [
  771. <<<'EXPECTED'
  772. <?php
  773. $foo = [[
  774. new Foo(
  775. 'foo'
  776. ),
  777. ]];
  778. EXPECTED
  779. ,
  780. <<<'INPUT'
  781. <?php
  782. $foo = [[
  783. new Foo(
  784. 'foo'
  785. ),
  786. ]];
  787. INPUT
  788. ,
  789. ],
  790. [
  791. <<<'EXPECTED'
  792. <?php
  793. $array = [
  794. 'foo' => [
  795. 'bar' => [
  796. 'baz',
  797. ],
  798. ], // <- this one
  799. ];
  800. EXPECTED
  801. ,
  802. <<<'INPUT'
  803. <?php
  804. $array = [
  805. 'foo' => [
  806. 'bar' => [
  807. 'baz',
  808. ],
  809. ], // <- this one
  810. ];
  811. INPUT
  812. ,
  813. ],
  814. [
  815. <<<'EXPECTED'
  816. <?php
  817. $foo = [
  818. ...$foo,
  819. ...$bar,
  820. ];
  821. EXPECTED
  822. ,
  823. <<<'INPUT'
  824. <?php
  825. $foo = [
  826. ...$foo,
  827. ...$bar,
  828. ];
  829. INPUT
  830. ,
  831. ],
  832. ]);
  833. }
  834. /**
  835. * @dataProvider provideFixWithTabsCases
  836. */
  837. public function testFixWithTabs(string $expected, ?string $input = null): void
  838. {
  839. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t"));
  840. $this->doTest($expected, $input);
  841. }
  842. public static function provideFixWithTabsCases(): iterable
  843. {
  844. return self::withLongArraySyntaxCases([
  845. [
  846. <<<EXPECTED
  847. <?php
  848. \$foo = [
  849. \t'foo',
  850. \t'bar' => 'baz',
  851. ];
  852. EXPECTED
  853. ,
  854. <<<'INPUT'
  855. <?php
  856. $foo = [
  857. 'foo',
  858. 'bar' => 'baz',
  859. ];
  860. INPUT
  861. ,
  862. ],
  863. [
  864. <<<EXPECTED
  865. <?php
  866. \$foo = [
  867. \t'foo',
  868. \t'bar' => 'baz',
  869. ];
  870. EXPECTED
  871. ,
  872. <<<INPUT
  873. <?php
  874. \$foo = [
  875. \t\t\t'foo',
  876. \t\t'bar' => 'baz',
  877. ];
  878. INPUT
  879. ,
  880. ],
  881. ]);
  882. }
  883. /**
  884. * @dataProvider provideFixPhp80Cases
  885. *
  886. * @requires PHP 8.0
  887. */
  888. public function testFixPhp80(string $expected, ?string $input = null): void
  889. {
  890. $this->doTest($expected, $input);
  891. }
  892. public static function provideFixPhp80Cases(): iterable
  893. {
  894. yield 'attribute' => [
  895. '<?php
  896. class Foo {
  897. #[SimpleAttribute]
  898. #[ComplexAttribute(
  899. foo: true,
  900. bar: [
  901. 1,
  902. 2,
  903. 3,
  904. ]
  905. )]
  906. public function bar()
  907. {
  908. }
  909. }',
  910. '<?php
  911. class Foo {
  912. #[SimpleAttribute]
  913. #[ComplexAttribute(
  914. foo: true,
  915. bar: [
  916. 1,
  917. 2,
  918. 3,
  919. ]
  920. )]
  921. public function bar()
  922. {
  923. }
  924. }',
  925. ];
  926. }
  927. /**
  928. * @param list<array{0: string, 1?: string}> $cases
  929. *
  930. * @return list<array{0: string, 1?: string}>
  931. */
  932. private static function withLongArraySyntaxCases(array $cases): array
  933. {
  934. $longSyntaxCases = [];
  935. foreach ($cases as $case) {
  936. $case[0] = self::toLongArraySyntax($case[0]);
  937. if (isset($case[1])) {
  938. $case[1] = self::toLongArraySyntax($case[1]);
  939. }
  940. $longSyntaxCases[] = $case;
  941. }
  942. return [...$cases, ...$longSyntaxCases];
  943. }
  944. private static function toLongArraySyntax(string $php): string
  945. {
  946. return strtr($php, [
  947. '[' => 'array(',
  948. ']' => ')',
  949. ]);
  950. }
  951. }