NumericLiteralSeparatorFixerTest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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\Fixer\Basic\NumericLiteralSeparatorFixer;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. /**
  16. * @author Marvin Heilemann <marvin.heilemann+github@googlemail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\Basic\NumericLiteralSeparatorFixer
  21. */
  22. final class NumericLiteralSeparatorFixerTest extends AbstractFixerTestCase
  23. {
  24. /**
  25. * @param array<string, mixed> $config
  26. *
  27. * @dataProvider provideFixCases
  28. */
  29. public function testFix(string $expected, ?string $input = null, ?array $config = []): void
  30. {
  31. $this->fixer->configure($config);
  32. $this->doTest($expected, $input);
  33. }
  34. /**
  35. * @return iterable<string, array{0: string, 1?: null|string, 2?: array<string, mixed>}>
  36. */
  37. public static function provideFixCases(): iterable
  38. {
  39. yield 'do not override existing separator' => [
  40. <<<'PHP'
  41. <?php
  42. echo 0B01010100_01101000;
  43. echo 70_10_00;
  44. PHP,
  45. null,
  46. [
  47. 'override_existing' => false,
  48. 'strategy' => NumericLiteralSeparatorFixer::STRATEGY_USE_SEPARATOR,
  49. ],
  50. ];
  51. yield 'override existing separator' => [
  52. <<<'PHP'
  53. <?php
  54. echo 1_234.5;
  55. echo 701_000;
  56. PHP,
  57. <<<'PHP'
  58. <?php
  59. echo 123_4.5;
  60. echo 70_10_00;
  61. PHP,
  62. [
  63. 'override_existing' => true,
  64. 'strategy' => NumericLiteralSeparatorFixer::STRATEGY_USE_SEPARATOR,
  65. ],
  66. ];
  67. yield from self::yieldCases([
  68. 'decimal' => [
  69. '1234' => '1_234',
  70. '-1234' => '-1_234',
  71. '12345' => '12_345',
  72. '123456' => '123_456',
  73. ],
  74. 'binary' => [
  75. '0b0101010001101000' => '0b01010100_01101000',
  76. '0b01010100011010000110010101101111' => '0b01010100_01101000_01100101_01101111',
  77. '0b110001000' => '0b1_10001000',
  78. ],
  79. 'float' => [
  80. '1234.5' => '1_234.5',
  81. '1.2345' => '1.234_5',
  82. '1234e5' => '1_234e5',
  83. '1234E5' => '1_234E5',
  84. '1e2345' => '1e2_345',
  85. '1234.5678e1234' => '1_234.567_8e1_234',
  86. '1.1e-1234' => '1.1e-1_234',
  87. '1.1e-12345' => '1.1e-12_345',
  88. '1.1e-123456' => '1.1e-123_456',
  89. ],
  90. 'hexadecimal' => [
  91. '0x42726F776E' => '0x42_72_6F_77_6E',
  92. '0X42726F776E' => '0X42_72_6F_77_6E',
  93. '0x2726F776E' => '0x2_72_6F_77_6E',
  94. '0x1234567890abcdef' => '0x12_34_56_78_90_ab_cd_ef',
  95. '0X1234567890ABCDEF' => '0X12_34_56_78_90_AB_CD_EF',
  96. '0x1234e5' => '0x12_34_e5',
  97. ],
  98. 'octal' => [
  99. '012345' => '012_345',
  100. '0123456' => '0123_456',
  101. '01234567' => '01_234_567',
  102. ],
  103. ]);
  104. }
  105. /**
  106. * @param array<string, mixed> $config
  107. *
  108. * @requires PHP 8.1
  109. *
  110. * @dataProvider provideFix81Cases
  111. */
  112. public function testFix81(string $expected, ?string $input = null, ?array $config = []): void
  113. {
  114. $this->fixer->configure($config);
  115. $this->doTest($expected, $input);
  116. }
  117. /**
  118. * @return iterable<string, array{0: string, 1?: null|string, 2?: array<string, mixed>}>
  119. */
  120. public static function provideFix81Cases(): iterable
  121. {
  122. yield 'do not override existing separator' => [
  123. '<?php echo 0o123_45;',
  124. null,
  125. [
  126. 'override_existing' => false,
  127. 'strategy' => NumericLiteralSeparatorFixer::STRATEGY_USE_SEPARATOR,
  128. ],
  129. ];
  130. yield 'override existing separator' => [
  131. '<?php echo 1_234.5;',
  132. '<?php echo 123_4.5;',
  133. [
  134. 'override_existing' => true,
  135. 'strategy' => NumericLiteralSeparatorFixer::STRATEGY_USE_SEPARATOR,
  136. ],
  137. ];
  138. yield from self::yieldCases([
  139. 'octal' => [
  140. '0o12345' => '0o12_345',
  141. '0o123456' => '0o123_456',
  142. ],
  143. ]);
  144. }
  145. /**
  146. * @param array<string, array<mixed, mixed>> $cases
  147. *
  148. * @return iterable<string, array{0: string, 1?: null|string, 2?: array<string, mixed>}>
  149. */
  150. private static function yieldCases(array $cases): iterable
  151. {
  152. foreach ($cases as $pairsType => $pairs) {
  153. foreach ($pairs as $withoutSeparator => $withSeparator) {
  154. yield "add separator to {$pairsType} {$withoutSeparator}" => [
  155. sprintf('<?php echo %s;', $withSeparator),
  156. sprintf('<?php echo %s;', $withoutSeparator),
  157. ['strategy' => NumericLiteralSeparatorFixer::STRATEGY_USE_SEPARATOR],
  158. ];
  159. }
  160. foreach ($pairs as $withoutSeparator => $withSeparator) {
  161. yield "remove separator from {$pairsType} {$withoutSeparator}" => [
  162. sprintf('<?php echo %s;', $withoutSeparator),
  163. sprintf('<?php echo %s;', $withSeparator),
  164. ['strategy' => NumericLiteralSeparatorFixer::STRATEGY_NO_SEPARATOR],
  165. ];
  166. }
  167. }
  168. }
  169. }