BracesPositionFixerTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  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\BracesPositionFixer
  18. *
  19. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Basic\BracesPositionFixer>
  20. *
  21. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Basic\BracesPositionFixer
  22. */
  23. final class BracesPositionFixerTest extends AbstractFixerTestCase
  24. {
  25. /**
  26. * @param _AutogeneratedInputConfiguration $configuration
  27. *
  28. * @dataProvider provideFixCases
  29. */
  30. public function testFix(string $expected, ?string $input = null, array $configuration = []): void
  31. {
  32. $this->fixer->configure($configuration);
  33. $this->doTest($expected, $input);
  34. }
  35. public static function provideFixCases(): iterable
  36. {
  37. yield 'if (default)' => [
  38. '<?php
  39. if ($foo) {
  40. foo();
  41. }',
  42. '<?php
  43. if ($foo)
  44. {
  45. foo();
  46. }',
  47. ];
  48. yield 'if (next line)' => [
  49. '<?php
  50. if ($foo)
  51. {
  52. foo();
  53. }',
  54. '<?php
  55. if ($foo) {
  56. foo();
  57. }',
  58. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  59. ];
  60. yield 'else (default)' => [
  61. '<?php
  62. if ($foo) {
  63. foo();
  64. }
  65. else {
  66. bar();
  67. }',
  68. '<?php
  69. if ($foo)
  70. {
  71. foo();
  72. }
  73. else
  74. {
  75. bar();
  76. }',
  77. ];
  78. yield 'else (next line)' => [
  79. '<?php
  80. if ($foo)
  81. {
  82. foo();
  83. }
  84. else
  85. {
  86. bar();
  87. }',
  88. '<?php
  89. if ($foo) {
  90. foo();
  91. }
  92. else {
  93. bar();
  94. }',
  95. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  96. ];
  97. yield 'elseif (default)' => [
  98. '<?php
  99. if ($foo) {
  100. foo();
  101. }
  102. elseif ($bar) {
  103. bar();
  104. }',
  105. '<?php
  106. if ($foo)
  107. {
  108. foo();
  109. }
  110. elseif ($bar)
  111. {
  112. bar();
  113. }',
  114. ];
  115. yield 'elseif (next line)' => [
  116. '<?php
  117. if ($foo)
  118. {
  119. foo();
  120. }
  121. elseif ($bar)
  122. {
  123. bar();
  124. }',
  125. '<?php
  126. if ($foo) {
  127. foo();
  128. }
  129. elseif ($bar) {
  130. bar();
  131. }',
  132. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  133. ];
  134. yield 'else if (default)' => [
  135. '<?php
  136. if ($foo) {
  137. foo();
  138. }
  139. else if ($bar) {
  140. bar();
  141. }',
  142. '<?php
  143. if ($foo)
  144. {
  145. foo();
  146. }
  147. else if ($bar)
  148. {
  149. bar();
  150. }',
  151. ];
  152. yield 'else if (next line)' => [
  153. '<?php
  154. if ($foo)
  155. {
  156. foo();
  157. }
  158. else if ($bar)
  159. {
  160. bar();
  161. }',
  162. '<?php
  163. if ($foo) {
  164. foo();
  165. }
  166. else if ($bar) {
  167. bar();
  168. }',
  169. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  170. ];
  171. yield 'for (default)' => [
  172. '<?php
  173. for (;;) {
  174. foo();
  175. }',
  176. '<?php
  177. for (;;)
  178. {
  179. foo();
  180. }',
  181. ];
  182. yield 'for (next line)' => [
  183. '<?php
  184. for (;;)
  185. {
  186. foo();
  187. }',
  188. '<?php
  189. for (;;) {
  190. foo();
  191. }',
  192. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  193. ];
  194. yield 'foreach (default)' => [
  195. '<?php
  196. foreach ($foo as $bar) {
  197. foo();
  198. }',
  199. '<?php
  200. foreach ($foo as $bar)
  201. {
  202. foo();
  203. }',
  204. ];
  205. yield 'foreach (next line)' => [
  206. '<?php
  207. foreach ($foo as $bar)
  208. {
  209. foo();
  210. }',
  211. '<?php
  212. foreach ($foo as $bar) {
  213. foo();
  214. }',
  215. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  216. ];
  217. yield 'while (default)' => [
  218. '<?php
  219. while ($foo) {
  220. foo();
  221. }',
  222. '<?php
  223. while ($foo)
  224. {
  225. foo();
  226. }',
  227. ];
  228. yield 'while (next line)' => [
  229. '<?php
  230. while ($foo)
  231. {
  232. foo();
  233. }',
  234. '<?php
  235. while ($foo) {
  236. foo();
  237. }',
  238. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  239. ];
  240. yield 'do while (default)' => [
  241. '<?php
  242. do {
  243. foo();
  244. } while ($foo);',
  245. '<?php
  246. do
  247. {
  248. foo();
  249. } while ($foo);',
  250. ];
  251. yield 'do while (next line)' => [
  252. '<?php
  253. do
  254. {
  255. foo();
  256. } while ($foo);',
  257. '<?php
  258. do {
  259. foo();
  260. } while ($foo);',
  261. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  262. ];
  263. yield 'switch (default)' => [
  264. '<?php
  265. switch ($foo) {
  266. case 1:
  267. foo();
  268. }',
  269. '<?php
  270. switch ($foo)
  271. {
  272. case 1:
  273. foo();
  274. }',
  275. ];
  276. yield 'switch (next line)' => [
  277. '<?php
  278. switch ($foo)
  279. {
  280. case 1:
  281. foo();
  282. }',
  283. '<?php
  284. switch ($foo) {
  285. case 1:
  286. foo();
  287. }',
  288. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  289. ];
  290. yield 'try catch finally (open brace on the same line)' => [
  291. '<?php
  292. try {
  293. foo();
  294. }
  295. catch (Exception $e) {
  296. bar();
  297. }
  298. finally {
  299. baz();
  300. }',
  301. '<?php
  302. try
  303. {
  304. foo();
  305. }
  306. catch (Exception $e)
  307. {
  308. bar();
  309. }
  310. finally
  311. {
  312. baz();
  313. }',
  314. ];
  315. yield 'try catch finally (open brace on the next line)' => [
  316. '<?php
  317. try
  318. {
  319. foo();
  320. }
  321. catch (Exception $e)
  322. {
  323. bar();
  324. }
  325. finally
  326. {
  327. baz();
  328. }',
  329. '<?php
  330. try {
  331. foo();
  332. }
  333. catch (Exception $e) {
  334. bar();
  335. }
  336. finally {
  337. baz();
  338. }',
  339. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  340. ];
  341. yield 'class (default)' => [
  342. '<?php
  343. class Foo
  344. {
  345. }',
  346. '<?php
  347. class Foo {
  348. }',
  349. ];
  350. yield 'class (same line)' => [
  351. '<?php
  352. class Foo {
  353. }',
  354. '<?php
  355. class Foo
  356. {
  357. }',
  358. ['classes_opening_brace' => 'same_line'],
  359. ];
  360. yield 'function (default)' => [
  361. '<?php
  362. function foo()
  363. {
  364. }',
  365. '<?php
  366. function foo() {
  367. }',
  368. ];
  369. yield 'function (same line)' => [
  370. '<?php
  371. function foo() {
  372. }',
  373. '<?php
  374. function foo()
  375. {
  376. }',
  377. ['functions_opening_brace' => 'same_line'],
  378. ];
  379. yield 'anonymous function (default)' => [
  380. '<?php
  381. $foo = function () {
  382. };',
  383. '<?php
  384. $foo = function ()
  385. {
  386. };',
  387. ];
  388. yield 'anonymous function (next line)' => [
  389. '<?php
  390. $foo = function ()
  391. {
  392. };',
  393. '<?php
  394. $foo = function () {
  395. };',
  396. ['anonymous_functions_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  397. ];
  398. yield 'with blank lines inside braces' => [
  399. '<?php
  400. class Foo
  401. {
  402. public function foo()
  403. {
  404. if (true) {
  405. echo "foo";
  406. }
  407. }
  408. }',
  409. '<?php
  410. class Foo {
  411. public function foo() {
  412. if (true)
  413. {
  414. echo "foo";
  415. }
  416. }
  417. }',
  418. ];
  419. yield 'with comment after opening brace (default)' => [
  420. '<?php
  421. function foo() /* foo */ // foo
  422. {
  423. }',
  424. '<?php
  425. function foo() /* foo */ { // foo
  426. }',
  427. ];
  428. yield 'with comment after opening brace (same line)' => [
  429. '<?php
  430. function foo() { // foo
  431. /* foo */
  432. }',
  433. '<?php
  434. function foo() // foo
  435. { /* foo */
  436. }',
  437. ['functions_opening_brace' => 'same_line'],
  438. ];
  439. yield 'next line with multiline signature' => [
  440. '<?php
  441. if (
  442. $foo
  443. ) {
  444. foo();
  445. }',
  446. '<?php
  447. if (
  448. $foo
  449. )
  450. {
  451. foo();
  452. }',
  453. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  454. ];
  455. yield 'next line with newline before closing parenthesis' => [
  456. '<?php
  457. if ($foo
  458. ) {
  459. foo();
  460. }',
  461. '<?php
  462. if ($foo
  463. )
  464. {
  465. foo();
  466. }',
  467. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  468. ];
  469. yield 'next line with newline in signature but not before closing parenthesis' => [
  470. '<?php
  471. if (
  472. $foo)
  473. {
  474. foo();
  475. }',
  476. '<?php
  477. if (
  478. $foo) {
  479. foo();
  480. }',
  481. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  482. ];
  483. yield 'anonymous class (same line)' => [
  484. '<?php
  485. $foo = new class() {
  486. };',
  487. '<?php
  488. $foo = new class()
  489. {
  490. };',
  491. ];
  492. yield 'anonymous class (next line)' => [
  493. '<?php
  494. $foo = new class()
  495. {
  496. };',
  497. '<?php
  498. $foo = new class() {
  499. };',
  500. ['anonymous_classes_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  501. ];
  502. yield 'next line with multiline signature and return type' => [
  503. '<?php
  504. function foo(
  505. $foo
  506. ): int {
  507. foo();
  508. }',
  509. '<?php
  510. function foo(
  511. $foo
  512. ): int
  513. {
  514. foo();
  515. }',
  516. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  517. ];
  518. yield 'next line with multiline signature and return type (nullable)' => [
  519. '<?php
  520. function foo(
  521. $foo
  522. ): ?int {
  523. foo();
  524. }',
  525. '<?php
  526. function foo(
  527. $foo
  528. ): ?int
  529. {
  530. foo();
  531. }',
  532. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  533. ];
  534. yield 'next line with multiline signature and return type (array)' => [
  535. '<?php
  536. function foo(
  537. $foo
  538. ): array {
  539. foo();
  540. }',
  541. '<?php
  542. function foo(
  543. $foo
  544. ): array
  545. {
  546. foo();
  547. }',
  548. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  549. ];
  550. yield 'next line with multiline signature and return type (class name)' => [
  551. '<?php
  552. function foo(
  553. $foo
  554. ): \Foo\Bar {
  555. foo();
  556. }',
  557. '<?php
  558. function foo(
  559. $foo
  560. ): \Foo\Bar
  561. {
  562. foo();
  563. }',
  564. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  565. ];
  566. yield 'next line with newline before closing parenthesis and return type' => [
  567. '<?php
  568. function foo($foo
  569. ): int {
  570. foo();
  571. }',
  572. '<?php
  573. function foo($foo
  574. ): int
  575. {
  576. foo();
  577. }',
  578. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  579. ];
  580. yield 'next line with newline before closing parenthesis and callable type' => [
  581. '<?php
  582. function foo($foo
  583. ): callable {
  584. return function (): void {};
  585. }',
  586. '<?php
  587. function foo($foo
  588. ): callable
  589. {
  590. return function (): void {};
  591. }',
  592. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  593. ];
  594. yield 'next line with newline in signature but not before closing parenthesis and return type' => [
  595. '<?php
  596. function foo(
  597. $foo): int
  598. {
  599. foo();
  600. }',
  601. '<?php
  602. function foo(
  603. $foo): int {
  604. foo();
  605. }',
  606. ['control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end'],
  607. ];
  608. yield 'multiple elseifs' => [
  609. '<?php if ($foo) {
  610. } elseif ($foo) {
  611. } elseif ($foo) {
  612. } elseif ($foo) {
  613. } elseif ($foo) {
  614. } elseif ($foo) {
  615. } elseif ($foo) {
  616. } elseif ($foo) {
  617. } elseif ($foo) {
  618. }',
  619. '<?php if ($foo){
  620. } elseif ($foo){
  621. } elseif ($foo){
  622. } elseif ($foo){
  623. } elseif ($foo){
  624. } elseif ($foo){
  625. } elseif ($foo){
  626. } elseif ($foo){
  627. } elseif ($foo){
  628. }',
  629. ];
  630. yield 'open brace preceded by comment and whitespace' => [
  631. '<?php
  632. if (true) { /* foo */
  633. foo();
  634. }',
  635. '<?php
  636. if (true) /* foo */ {
  637. foo();
  638. }',
  639. ];
  640. yield 'open brace surrounded by comment and whitespace' => [
  641. '<?php
  642. if (true) { /* foo */ /* bar */
  643. foo();
  644. }',
  645. '<?php
  646. if (true) /* foo */ { /* bar */
  647. foo();
  648. }',
  649. ];
  650. yield 'open brace not preceded by space and followed by a comment' => [
  651. '<?php class test
  652. {
  653. public function example()// example
  654. {
  655. }
  656. }
  657. ',
  658. '<?php class test
  659. {
  660. public function example(){// example
  661. }
  662. }
  663. ',
  664. ];
  665. yield 'open brace not preceded by space and followed by a space and comment' => [
  666. '<?php class test
  667. {
  668. public function example() // example
  669. {
  670. }
  671. }
  672. ',
  673. '<?php class test
  674. {
  675. public function example(){ // example
  676. }
  677. }
  678. ',
  679. ];
  680. }
  681. /**
  682. * @dataProvider provideFix80Cases
  683. *
  684. * @requires PHP 8.0
  685. */
  686. public function testFix80(string $expected, ?string $input = null): void
  687. {
  688. $this->doTest($expected, $input);
  689. }
  690. /**
  691. * @return iterable<string, array{string, string}>
  692. */
  693. public static function provideFix80Cases(): iterable
  694. {
  695. yield 'function (multiline + union return)' => [
  696. '<?php
  697. function sum(
  698. int|float $first,
  699. int|float $second,
  700. ): int|float {
  701. }',
  702. '<?php
  703. function sum(
  704. int|float $first,
  705. int|float $second,
  706. ): int|float
  707. {
  708. }',
  709. ];
  710. yield 'function (multiline + union return with whitespace)' => [
  711. '<?php
  712. function sum(
  713. int|float $first,
  714. int|float $second,
  715. ): int | float {
  716. }',
  717. '<?php
  718. function sum(
  719. int|float $first,
  720. int|float $second,
  721. ): int | float
  722. {
  723. }',
  724. ];
  725. yield 'method with static return type' => [
  726. '<?php
  727. class Foo
  728. {
  729. function sum(
  730. $foo
  731. ): static {
  732. }
  733. }',
  734. '<?php
  735. class Foo
  736. {
  737. function sum(
  738. $foo
  739. ): static
  740. {
  741. }
  742. }',
  743. ];
  744. }
  745. /**
  746. * @dataProvider provideFix81Cases
  747. *
  748. * @requires PHP 8.1
  749. */
  750. public function testFix81(string $expected, ?string $input = null): void
  751. {
  752. $this->doTest($expected, $input);
  753. }
  754. /**
  755. * @return iterable<string, array{string}>
  756. */
  757. public static function provideFix81Cases(): iterable
  758. {
  759. yield 'function (multiline + intersection return)' => [
  760. '<?php
  761. function foo(
  762. mixed $bar,
  763. mixed $baz,
  764. ): Foo&Bar {
  765. }',
  766. ];
  767. }
  768. /**
  769. * @dataProvider provideFix82Cases
  770. *
  771. * @requires PHP 8.2
  772. */
  773. public function testFix82(string $expected, ?string $input = null): void
  774. {
  775. $this->doTest($expected, $input);
  776. }
  777. /**
  778. * @return iterable<string, array{string}>
  779. */
  780. public static function provideFix82Cases(): iterable
  781. {
  782. yield 'function (multiline + DNF return)' => [
  783. '<?php
  784. function foo(
  785. mixed $bar,
  786. mixed $baz,
  787. ): (Foo&Bar)|int|null {
  788. }',
  789. ];
  790. }
  791. }