NoUnsetOnPropertyFixerTest.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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\LanguageConstruct;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author Gert de Pagter <BackEndTea@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\LanguageConstruct\NoUnsetOnPropertyFixer
  20. */
  21. final class NoUnsetOnPropertyFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideFixCases
  25. */
  26. public function testFix(string $expected, ?string $input = null): void
  27. {
  28. $this->doTest($expected, $input);
  29. }
  30. public function provideFixCases(): \Generator
  31. {
  32. yield from [
  33. 'It replaces an unset on a property with = null' => [
  34. '<?php $foo->bar = null;',
  35. '<?php unset($foo->bar);',
  36. ],
  37. 'It replaces an unset on a property with = null II' => [
  38. '<?php $foo->bar = null ;',
  39. '<?php unset($foo->bar );',
  40. ],
  41. 'It replaces an unset on a static property with = null' => [
  42. '<?php TestClass::$bar = null;',
  43. '<?php unset(TestClass::$bar);',
  44. ],
  45. 'It does not replace unset on a variable with = null' => [
  46. '<?php $b->a; unset($foo);',
  47. ],
  48. 'It replaces multiple unsets on variables with = null' => [
  49. '<?php $foo->bar = null; $bar->foo = null; $bar->baz = null; $a->ba = null;',
  50. '<?php unset($foo->bar, $bar->foo, $bar->baz, $a->ba);',
  51. ],
  52. 'It replaces multiple unsets, but not those that arent properties' => [
  53. '<?php $foo->bar = null; $bar->foo = null; unset($bar);',
  54. '<?php unset($foo->bar, $bar->foo, $bar);',
  55. ],
  56. 'It replaces multiple unsets, but not those that arent properties in multiple places' => [
  57. '<?php unset($foo); $bar->foo = null; unset($bar);',
  58. '<?php unset($foo, $bar->foo, $bar);',
  59. ],
  60. 'It replaces $this -> and self:: replacements' => [
  61. '<?php $this->bar = null; self::$foo = null; unset($bar);',
  62. '<?php unset($this->bar, self::$foo, $bar);',
  63. ],
  64. 'It does not replace unsets on arrays' => [
  65. '<?php unset($bar->foo[0]);',
  66. ],
  67. 'It works in a more complex unset' => [
  68. '<?php unset($bar->foo[0]); self::$foo = null; \Test\Baz::$fooBar = null; unset($bar->foo[0]); $this->foo = null; unset($a); unset($b);',
  69. '<?php unset($bar->foo[0], self::$foo, \Test\Baz::$fooBar, $bar->foo[0], $this->foo, $a, $b);',
  70. ],
  71. 'It works with consecutive unsets' => [
  72. '<?php $foo->bar = null; unset($foo); unset($bar); unset($baz); $this->ab = null;',
  73. '<?php unset($foo->bar, $foo, $bar, $baz, $this->ab);',
  74. ],
  75. 'It works when around messy whitespace' => [
  76. '<?php
  77. unset($a); $this->b = null;
  78. $this->a = null; unset($b);
  79. ',
  80. '<?php
  81. unset($a, $this->b);
  82. unset($this->a, $b);
  83. ',
  84. ],
  85. 'It works with weirdly placed comments' => [
  86. '<?php unset/*foo*/(/*bar*/$bar->foo[0]); self::$foo = null/*baz*/; /*ello*/\Test\Baz::$fooBar = null/*comment*/; unset($bar->foo[0]); $this->foo = null; unset($a); unset($b);
  87. unset/*foo*/(/*bar*/$bar);',
  88. '<?php unset/*foo*/(/*bar*/$bar->foo[0], self::$foo/*baz*/, /*ello*/\Test\Baz::$fooBar/*comment*/, $bar->foo[0], $this->foo, $a, $b);
  89. unset/*foo*/(/*bar*/$bar);',
  90. ],
  91. 'It does not mess with consecutive unsets' => [
  92. '<?php unset($a, $b, $c);
  93. $this->a = null;',
  94. '<?php unset($a, $b, $c);
  95. unset($this->a);',
  96. ],
  97. 'It does not replace function call with class constant inside' => [
  98. '<?php unset($foos[array_search(BadFoo::NAME, $foos)]);',
  99. ],
  100. 'It does not replace function call with class constant and property inside' => [
  101. '<?php unset($this->property[array_search(\Types::TYPE_RANDOM, $this->property)]);',
  102. ],
  103. ];
  104. if (\PHP_VERSION_ID < 80000) {
  105. yield 'It does not replace unsets on arrays with special notation' => [
  106. '<?php unset($bar->foo{0});',
  107. ];
  108. }
  109. yield 'It does not break complex expressions' => [
  110. '<?php
  111. unset(a()[b()["a"]]);
  112. unset(a()[b()]);
  113. unset(a()["a"]);
  114. unset(c($a)->a);
  115. ',
  116. ];
  117. }
  118. /**
  119. * @dataProvider provideFixPre80Cases
  120. * @requires PHP <8.0
  121. */
  122. public function testFixPre80(string $expected, string $input = null): void
  123. {
  124. $this->doTest($expected, $input);
  125. }
  126. public function provideFixPre80Cases(): \Generator
  127. {
  128. yield 'It does not break curly access expressions' => [
  129. '<?php unset(a(){"a"});',
  130. ];
  131. }
  132. /**
  133. * @requires PHP 7.3
  134. * @dataProvider provideFix73Cases
  135. */
  136. public function testFix73(string $expected, ?string $input = null): void
  137. {
  138. $this->doTest($expected, $input);
  139. }
  140. public function provideFix73Cases(): \Generator
  141. {
  142. yield from [
  143. 'It replaces an unset on a property with = null' => [
  144. '<?php $foo->bar = null;',
  145. '<?php unset($foo->bar,);',
  146. ],
  147. 'It replaces multiple unsets, but not those that arent properties' => [
  148. '<?php $foo->bar = null; $bar->foo = null; unset($bar,);',
  149. '<?php unset($foo->bar, $bar->foo, $bar,);',
  150. ],
  151. 'It replaces an unset on a static property with = null' => [
  152. '<?php TestClass::$bar = null;',
  153. '<?php unset(TestClass::$bar,);',
  154. ],
  155. 'It does not replace unset on a variable with = null' => [
  156. '<?php $b->a; unset($foo,);',
  157. ],
  158. 'It replaces multiple unsets on variables with = null' => [
  159. '<?php $foo->bar = null; $bar->foo = null; $bar->baz = null; $a->ba = null;',
  160. '<?php unset($foo->bar, $bar->foo, $bar->baz, $a->ba,);',
  161. ],
  162. 'It replaces multiple unsets, but not those that arent properties in multiple places' => [
  163. '<?php unset($foo); $bar->foo = null; unset($bar,);',
  164. '<?php unset($foo, $bar->foo, $bar,);',
  165. ],
  166. 'It replaces $this -> and self:: replacements' => [
  167. '<?php $this->bar = null; self::$foo = null; unset($bar,);',
  168. '<?php unset($this->bar, self::$foo, $bar,);',
  169. ],
  170. 'It does not replace unsets on arrays' => [
  171. '<?php unset($bar->foo[0],);',
  172. ],
  173. 'It works in a more complex unset' => [
  174. '<?php unset($bar->foo[0]); self::$foo = null; \Test\Baz::$fooBar = null; unset($bar->foo[0]); $this->foo = null; unset($a); unset($b,);',
  175. '<?php unset($bar->foo[0], self::$foo, \Test\Baz::$fooBar, $bar->foo[0], $this->foo, $a, $b,);',
  176. ],
  177. 'It works with consecutive unsets' => [
  178. '<?php $foo->bar = null; unset($foo); unset($bar); unset($baz); $this->ab = null;',
  179. '<?php unset($foo->bar, $foo, $bar, $baz, $this->ab,);',
  180. ],
  181. 'It works when around messy whitespace' => [
  182. '<?php
  183. unset($a); $this->b = null;
  184. $this->a = null; unset($b,);
  185. ',
  186. '<?php
  187. unset($a, $this->b,);
  188. unset($this->a, $b,);
  189. ',
  190. ],
  191. 'It works with weirdly placed comments' => [
  192. '<?php unset/*foo*/(/*bar*/$bar->foo[0]); self::$foo = null/*baz*/; /*ello*/\Test\Baz::$fooBar = null/*comment*/; unset($bar->foo[0]); $this->foo = null; unset($a); unset($b,);
  193. unset/*foo*/(/*bar*/$bar,);',
  194. '<?php unset/*foo*/(/*bar*/$bar->foo[0], self::$foo/*baz*/, /*ello*/\Test\Baz::$fooBar/*comment*/, $bar->foo[0], $this->foo, $a, $b,);
  195. unset/*foo*/(/*bar*/$bar,);',
  196. ],
  197. 'It does not mess with consecutive unsets' => [
  198. '<?php unset($a, $b, $c,);
  199. $this->a = null;',
  200. '<?php unset($a, $b, $c,);
  201. unset($this->a,);',
  202. ],
  203. 'It does not replace function call with class constant inside' => [
  204. '<?php unset($foos[array_search(BadFoo::NAME, $foos)],);',
  205. ],
  206. 'It does not replace function call with class constant and property inside' => [
  207. '<?php unset($this->property[array_search(\Types::TYPE_RANDOM, $this->property)],);',
  208. ],
  209. [
  210. '<?php $foo->bar = null ;',
  211. '<?php unset($foo->bar, );',
  212. ],
  213. [
  214. '<?php $foo->bar = null ;',
  215. '<?php unset($foo->bar ,);',
  216. ],
  217. [
  218. '<?php $foo->bar = null ;',
  219. '<?php unset($foo->bar , );',
  220. ],
  221. ];
  222. if (\PHP_VERSION_ID < 80000) {
  223. yield 'It does not replace unsets on arrays with special notation' => [
  224. '<?php unset($bar->foo{0},);',
  225. ];
  226. }
  227. }
  228. }