ConstantCaseFixerTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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\Casing;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Casing\ConstantCaseFixer
  20. *
  21. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Casing\ConstantCaseFixer>
  22. *
  23. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Casing\ConstantCaseFixer
  24. */
  25. final class ConstantCaseFixerTest extends AbstractFixerTestCase
  26. {
  27. /**
  28. * @param _AutogeneratedInputConfiguration $configuration
  29. *
  30. * @dataProvider provideFixCases
  31. */
  32. public function testFix(string $expected, ?string $input = null, array $configuration = []): void
  33. {
  34. $this->fixer->configure($configuration);
  35. $this->doTest($expected, $input);
  36. }
  37. /**
  38. * @return iterable<array{string, 1?: null|string, 2?: array{syntax?: string}}>
  39. */
  40. public static function provideFixCases(): iterable
  41. {
  42. yield [
  43. '<?php if (true) if (false) if (null) {}',
  44. '<?php if (TRUE) if (FALSE) if (NULL) {}',
  45. ];
  46. yield [
  47. '<?php if (!true) if (!false) if (!null) {}',
  48. '<?php if (!TRUE) if (!FALSE) if (!NULL) {}',
  49. ];
  50. yield [
  51. '<?php if ($a == true) if ($a == false) if ($a == null) {}',
  52. '<?php if ($a == TRUE) if ($a == FALSE) if ($a == NULL) {}',
  53. ];
  54. yield [
  55. '<?php if ($a === true) if ($a === false) if ($a === null) {}',
  56. '<?php if ($a === TRUE) if ($a === FALSE) if ($a === NULL) {}',
  57. ];
  58. yield [
  59. '<?php if ($a != true) if ($a != false) if ($a != null) {}',
  60. '<?php if ($a != TRUE) if ($a != FALSE) if ($a != NULL) {}',
  61. ];
  62. yield [
  63. '<?php if ($a !== true) if ($a !== false) if ($a !== null) {}',
  64. '<?php if ($a !== TRUE) if ($a !== FALSE) if ($a !== NULL) {}',
  65. ];
  66. yield [
  67. '<?php if (true && true and true AND true || false or false OR false xor null XOR null) {}',
  68. '<?php if (TRUE && TRUE and TRUE AND TRUE || FALSE or FALSE OR FALSE xor NULL XOR NULL) {}',
  69. ];
  70. yield [
  71. '<?php /* foo */ true; /** bar */ false;',
  72. '<?php /* foo */ TRUE; /** bar */ FALSE;',
  73. ];
  74. yield ['<?php echo $null;'];
  75. yield ['<?php $x = False::foo();'];
  76. yield ['<?php $x = Foo::NULL;'];
  77. yield ['<?php namespace Null;'];
  78. yield ['<?php namespace Foo\Null;'];
  79. yield ['<?php class Foo extends True {}'];
  80. yield ['<?php class Foo implements False {}'];
  81. yield ['<?php $foo instanceof True; $foo instanceof False; $foo instanceof Null;'];
  82. yield [
  83. '<?php
  84. class Foo
  85. {
  86. const TRUE = 1;
  87. const FALSE = true;
  88. const NULL = null;
  89. }',
  90. '<?php
  91. class Foo
  92. {
  93. const TRUE = 1;
  94. const FALSE = TRUE;
  95. const NULL = NULL;
  96. }',
  97. ];
  98. yield ['<?php $x = new /**/False?>'];
  99. yield ['<?php Null/**/::test();'];
  100. yield ['<?php True//
  101. ::test();'];
  102. yield ['<?php class Foo { public function Bar() { $this->False = 1; $this->True = 2; $this->Null = 3; } }'];
  103. foreach (['true', 'false', 'null'] as $case) {
  104. yield [
  105. \sprintf('<?php $x = %s;', $case),
  106. \sprintf('<?php $x = %s;', strtoupper($case)),
  107. ['case' => 'lower'],
  108. ];
  109. yield [
  110. \sprintf('<?php $x = %s;', $case),
  111. \sprintf('<?php $x = %s;', ucfirst($case)),
  112. ['case' => 'lower'],
  113. ];
  114. yield [
  115. \sprintf('<?php $x = new %s;', ucfirst($case)),
  116. null,
  117. ['case' => 'lower'],
  118. ];
  119. yield [
  120. \sprintf('<?php $x = new %s;', strtoupper($case)),
  121. null,
  122. ['case' => 'lower'],
  123. ];
  124. yield [
  125. \sprintf('<?php $x = "%s story";', $case),
  126. null,
  127. ['case' => 'lower'],
  128. ];
  129. yield [
  130. \sprintf('<?php $x = "%s";', $case),
  131. null,
  132. ['case' => 'lower'],
  133. ];
  134. }
  135. foreach (['true', 'false', 'null'] as $case) {
  136. yield [
  137. \sprintf('<?php $x = %s;', strtoupper($case)),
  138. \sprintf('<?php $x = %s;', $case),
  139. ['case' => 'upper'],
  140. ];
  141. yield [
  142. \sprintf('<?php $x = %s;', strtoupper($case)),
  143. \sprintf('<?php $x = %s;', ucfirst($case)),
  144. ['case' => 'upper'],
  145. ];
  146. yield [
  147. \sprintf('<?php $x = new %s;', ucfirst($case)),
  148. null,
  149. ['case' => 'upper'],
  150. ];
  151. yield [
  152. \sprintf('<?php $x = new %s;', strtoupper($case)),
  153. null,
  154. ['case' => 'upper'],
  155. ];
  156. yield [
  157. \sprintf('<?php $x = "%s story";', $case),
  158. null,
  159. ['case' => 'upper'],
  160. ];
  161. yield [
  162. \sprintf('<?php $x = "%s";', $case),
  163. null,
  164. ['case' => 'upper'],
  165. ];
  166. }
  167. }
  168. /**
  169. * @dataProvider provideFix80Cases
  170. *
  171. * @requires PHP 8.0
  172. */
  173. public function testFix80(string $expected, ?string $input = null): void
  174. {
  175. $this->doTest($expected, $input);
  176. }
  177. /**
  178. * @return iterable<string, array{string}>
  179. */
  180. public static function provideFix80Cases(): iterable
  181. {
  182. yield ' nullsafe operator' => ['<?php class Foo { public function Bar() { return $this?->False; } }'];
  183. }
  184. /**
  185. * @dataProvider provideFix81Cases
  186. *
  187. * @requires PHP 8.1
  188. */
  189. public function testFix81(string $expected, ?string $input = null): void
  190. {
  191. $this->doTest($expected, $input);
  192. }
  193. /**
  194. * @return iterable<string, array{string, string}>
  195. */
  196. public static function provideFix81Cases(): iterable
  197. {
  198. yield 'final class const' => [
  199. '<?php
  200. class Foo
  201. {
  202. final const TRUE = 1;
  203. public final const FALSE = true;
  204. final public const NULL = null;
  205. }
  206. ',
  207. '<?php
  208. class Foo
  209. {
  210. final const TRUE = 1;
  211. public final const FALSE = TRUE;
  212. final public const NULL = NULL;
  213. }
  214. ',
  215. ];
  216. yield 'enum and switch' => [
  217. '<?php
  218. enum Foo
  219. {
  220. case True;
  221. case False;
  222. case Null;
  223. public function methodWithSwitch(mixed $value): void
  224. {
  225. switch ($value) {
  226. case true:
  227. case false:
  228. case null:
  229. break;
  230. }
  231. }
  232. }
  233. ',
  234. '<?php
  235. enum Foo
  236. {
  237. case True;
  238. case False;
  239. case Null;
  240. public function methodWithSwitch(mixed $value): void
  241. {
  242. switch ($value) {
  243. case TRUE:
  244. case FALSE:
  245. case NULL:
  246. break;
  247. }
  248. }
  249. }
  250. ',
  251. ];
  252. yield 'enum' => [
  253. '<?php
  254. $y = false;
  255. enum Foo: string { case FALSE = "false"; }
  256. $x = true;
  257. ',
  258. '<?php
  259. $y = FALSE;
  260. enum Foo: string { case FALSE = "false"; }
  261. $x = TRUE;
  262. ',
  263. ];
  264. }
  265. /**
  266. * @dataProvider provideFix83Cases
  267. *
  268. * @requires PHP 8.3
  269. */
  270. public function testFix83(string $expected, ?string $input = null): void
  271. {
  272. $this->doTest($expected, $input);
  273. }
  274. /**
  275. * @return iterable<array{string, string}>
  276. */
  277. public static function provideFix83Cases(): iterable
  278. {
  279. yield 'typed constant' => [
  280. <<<'PHP'
  281. <?php
  282. class Foo1 { const array NULL = []; }
  283. class Foo2 { const int NULL = 0; }
  284. class Foo3 { const mixed NULL = 0; }
  285. class Foo4 { const string NULL = ''; }
  286. class Foo5 { const Foo|null NULL = null; }
  287. class Foo6 { const null|Foo NULL = null; }
  288. class Foo7 { const null|(Foo&Bar) NULL = null; }
  289. class Foo8 { const bool TRUE = true; }
  290. class Foo9 { const false FALSE = false; }
  291. class Foo10 { const true TRUE = true; }
  292. PHP,
  293. <<<'PHP'
  294. <?php
  295. class Foo1 { const array NULL = []; }
  296. class Foo2 { const int NULL = 0; }
  297. class Foo3 { const mixed NULL = 0; }
  298. class Foo4 { const string NULL = ''; }
  299. class Foo5 { const Foo|NULL NULL = NULL; }
  300. class Foo6 { const NULL|Foo NULL = NULL; }
  301. class Foo7 { const NULL|(Foo&Bar) NULL = NULL; }
  302. class Foo8 { const bool TRUE = TRUE; }
  303. class Foo9 { const FALSE FALSE = FALSE; }
  304. class Foo10 { const TRUE TRUE = TRUE; }
  305. PHP,
  306. ];
  307. }
  308. }