AssignNullCoalescingToCoalesceEqualFixerTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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\Operator;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @internal
  16. *
  17. * @covers \PhpCsFixer\Fixer\AbstractShortOperatorFixer
  18. * @covers \PhpCsFixer\Fixer\Operator\AssignNullCoalescingToCoalesceEqualFixer
  19. */
  20. final class AssignNullCoalescingToCoalesceEqualFixerTest 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. yield 'simple' => [
  32. '<?php $a ??= 1;',
  33. '<?php $a = $a ?? 1;',
  34. ];
  35. yield 'minimal' => [
  36. '<?php $a ??= 1;',
  37. '<?php $a=$a??1;',
  38. ];
  39. yield 'simple array' => [
  40. '<?php $a[1] ??= 1;',
  41. '<?php $a[1] = $a[1] ?? 1;',
  42. ];
  43. yield 'simple array [0]' => [
  44. '<?php $a[1][0] ??= 1;',
  45. '<?php $a[1][0] = $a[1][0] ?? 1;',
  46. ];
  47. yield 'simple array ([0])' => [
  48. '<?php $a[1][0] ??= 1;',
  49. '<?php $a[1][0] = ($a[1][0]) ?? 1;',
  50. ];
  51. yield 'simple array, comment' => [
  52. '<?php $a[1] /* 1 */ ??= /* 2 */ /* 3 */ /* 4 */ /* 5 */ 1;',
  53. '<?php $a[1]/* 1 */ = /* 2 */ $a[1/* 3 */] /* 4 */ ??/* 5 */ 1;',
  54. ];
  55. yield 'simple in call' => [
  56. '<?php a(1, $a ??= 1);',
  57. '<?php a(1, $a = $a ?? 1);',
  58. ];
  59. yield [
  60. '<?php \A\B::$foo ??= 1;',
  61. '<?php \A\B::$foo = \A\B::$foo ?? 1;',
  62. ];
  63. yield 'same' => [
  64. '<?php $a ??= 1;',
  65. '<?php $a = ($a) ?? 1;',
  66. ];
  67. yield 'object' => [
  68. '<?php $a->b ??= 1;',
  69. '<?php $a->b = $a->b ?? 1;',
  70. ];
  71. yield 'object II' => [
  72. '<?php $a->b[0]->{1} ??= 1;',
  73. '<?php $a->b[0]->{1} = $a->b[0]->{1} ?? 1;',
  74. ];
  75. yield 'simple, before ;' => [
  76. '<?php ; $a ??= 1;',
  77. '<?php ; $a = $a ?? 1;',
  78. ];
  79. yield 'simple, before {' => [
  80. '<?php { $a ??= 1; }',
  81. '<?php { $a = $a ?? 1; }',
  82. ];
  83. yield 'simple, before }' => [
  84. '<?php if ($a){} $a ??= 1;',
  85. '<?php if ($a){} $a = $a ?? 1;',
  86. ];
  87. yield 'in call' => [
  88. '<?php foo($a ??= 1);',
  89. '<?php foo($a = $a ?? 1);',
  90. ];
  91. yield 'in call followed by end tag and ternary' => [
  92. '<?php foo( $a ??= 1 ) ?><?php $b = $b ? $c : $d ?>',
  93. '<?php foo( $a = $a ?? 1 ) ?><?php $b = $b ? $c : $d ?>',
  94. ];
  95. yield 'simple, before ) I' => [
  96. '<?php if ($a) $a ??= 1;',
  97. '<?php if ($a) $a = $a ?? 1;',
  98. ];
  99. yield 'simple, before ) II' => [
  100. '<?php
  101. if ($a) $a ??= 1;
  102. foreach ($d as $i) $a ??= 1;
  103. while (foo()) $a ??= 1;
  104. ',
  105. '<?php
  106. if ($a) $a = $a ?? 1;
  107. foreach ($d as $i) $a = $a ?? 1;
  108. while (foo()) $a = $a ?? 1;
  109. ',
  110. ];
  111. yield 'simple, end' => [
  112. '<?php $a ??= 1 ?>',
  113. '<?php $a = $a ?? 1 ?>',
  114. ];
  115. yield 'simple, 10x' => [
  116. '<?php'.str_repeat(' $a ??= 1;', 10),
  117. '<?php'.str_repeat(' $a = $a ?? 1;', 10),
  118. ];
  119. yield 'simple, multi line' => [
  120. '<?php
  121. $a
  122. ??=
  123. '.'
  124. '.'
  125. 1;',
  126. '<?php
  127. $a
  128. =
  129. $a
  130. ??
  131. 1;',
  132. ];
  133. yield 'dynamic var' => [
  134. '<?php ${beers::$ale} ??= 1;',
  135. '<?php ${beers::$ale} = ${beers::$ale} ?? 1;',
  136. ];
  137. yield [
  138. '<?php $argv ??= $_SERVER[\'argv\'] ?? [];',
  139. '<?php $argv = $argv ?? $_SERVER[\'argv\'] ?? [];',
  140. ];
  141. yield 'do not fix' => [
  142. '<?php
  143. $a = 1 + $a ?? $b;
  144. $b + $a = $a ?? 1;
  145. $b = $a ?? 1;
  146. $b = $a ?? $b;
  147. $d = $a + $c ; $c ?? $c;
  148. $a = ($a ?? $b) && $c; // just to be sure
  149. $a = (string) $a ?? 1;
  150. $a = 1 ?? $a;
  151. ',
  152. ];
  153. yield 'do not fix because of precedence 1' => [
  154. '<?php $a = $a ?? $b ? $c : $d;',
  155. ];
  156. yield 'do not fix because of precedence 2' => [
  157. '<?php $a = $a ?? $b ? $c : $d ?>',
  158. ];
  159. if (\PHP_VERSION_ID < 8_00_00) {
  160. yield 'mixed array' => [
  161. '<?php
  162. $a[1] ??= 1;
  163. $a{2} ??= 1;
  164. $a{2}[$f] ??= 1;
  165. ',
  166. '<?php
  167. $a[1] = $a[1] ?? 1;
  168. $a{2} = $a{2} ?? 1;
  169. $a{2}[$f] = $a{2}[$f] ?? 1;
  170. ',
  171. ];
  172. yield 'same II' => [
  173. '<?php $a[1] ??= 1;',
  174. '<?php $a[1] = $a{1} ?? 1;',
  175. ];
  176. yield 'same III' => [
  177. '<?php $a[1] ??= 1;',
  178. '<?php $a[1] = (($a{1})) ?? 1;',
  179. ];
  180. }
  181. yield ['<?php $a[1][0] = $a ?? $a[1][0];'];
  182. yield 'switch case & default' => [
  183. '<?php
  184. switch(foo()) {
  185. case 1:
  186. $a ??= 1;
  187. break;
  188. default:
  189. $b ??= 1;
  190. break;
  191. }
  192. ',
  193. '<?php
  194. switch(foo()) {
  195. case 1:
  196. $a = $a ?? 1;
  197. break;
  198. default:
  199. $b = $b ?? 1;
  200. break;
  201. }
  202. ',
  203. ];
  204. yield 'operator precedence' => [
  205. '<?php $x = $z ? $b : $a = $a ?? 123;',
  206. ];
  207. yield 'alternative syntax' => [
  208. '<?php foreach([1, 2, 3] as $i): $a ??= 1; endforeach;',
  209. '<?php foreach([1, 2, 3] as $i): $a = $a ?? 1; endforeach;',
  210. ];
  211. yield 'assign and return' => [
  212. '<?php
  213. class Foo
  214. {
  215. private $test;
  216. public function bar($i)
  217. {
  218. return $this->test ??= $i;
  219. }
  220. }',
  221. '<?php
  222. class Foo
  223. {
  224. private $test;
  225. public function bar($i)
  226. {
  227. return $this->test = $this->test ?? $i;
  228. }
  229. }',
  230. ];
  231. }
  232. }