NoNullPropertyInitializationFixerTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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\ClassNotation;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. /**
  15. * @author ntzm
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\NoNullPropertyInitializationFixer
  20. */
  21. final class NoNullPropertyInitializationFixerTest 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 static function provideFixCases(): iterable
  31. {
  32. yield [
  33. '<?php class Foo { public $bar; }',
  34. '<?php class Foo { public $bar = null; }',
  35. ];
  36. yield [
  37. '<?php class Foo { protected $bar; }',
  38. '<?php class Foo { protected $bar = null; }',
  39. ];
  40. yield [
  41. '<?php class Foo { private $bar; }',
  42. '<?php class Foo { private $bar = null; }',
  43. ];
  44. yield [
  45. '<?php class Foo { var $bar; }',
  46. '<?php class Foo { var $bar = null; }',
  47. ];
  48. yield [
  49. '<?php class Foo { VAR $bar; }',
  50. '<?php class Foo { VAR $bar = null; }',
  51. ];
  52. yield [
  53. '<?php class Foo { public $bar; }',
  54. '<?php class Foo { public $bar = NULL; }',
  55. ];
  56. yield [
  57. '<?php class Foo { PUblic $bar; }',
  58. '<?php class Foo { PUblic $bar = nuLL; }',
  59. ];
  60. yield [
  61. '<?php trait Foo { public $bar; }',
  62. '<?php trait Foo { public $bar = nuLL; }',
  63. ];
  64. yield [
  65. '<?php class Foo { public $bar; }',
  66. '<?php class Foo { public $bar = \null; }',
  67. ];
  68. yield [
  69. '<?php class Foo {/* */public/* A */$bar/* B *//** C */;/* D */}',
  70. '<?php class Foo {/* */public/* A */$bar/* B */=/** C */null;/* D */}',
  71. ];
  72. yield [
  73. '<?php class Foo { public $bar; protected $baz; }',
  74. '<?php class Foo { public $bar = null; protected $baz = null; }',
  75. ];
  76. yield [
  77. '<?php class Foo { public $bar = \'null\'; }',
  78. ];
  79. yield [
  80. '<?php class Foo { public function bar() { return null; } }',
  81. ];
  82. yield [
  83. '<?php class Foo { protected $bar, $baz, $qux; }',
  84. '<?php class Foo { protected $bar = null, $baz = null, $qux = null; }',
  85. ];
  86. yield [
  87. '<?php class Foo { protected $bar, $baz = \'baz\', $qux; }',
  88. '<?php class Foo { protected $bar, $baz = \'baz\', $qux = null; }',
  89. ];
  90. yield [
  91. '<?php trait Foo { public $bar; } abstract class Bar { protected $bar, $baz = \'baz\', $qux; }',
  92. '<?php trait Foo { public $bar = null; } abstract class Bar { protected $bar, $baz = \'baz\', $qux = null; }',
  93. ];
  94. yield [
  95. '<?php class Foo { public function foo() { return null; } public $bar; public function baz() { return null; } }',
  96. '<?php class Foo { public function foo() { return null; } public $bar = null; public function baz() { return null; } }',
  97. ];
  98. yield [
  99. '<?php class#1
  100. Foo#2
  101. {#3
  102. protected#4
  103. $bar#5
  104. #6
  105. ,#7
  106. $baz#8
  107. #9
  108. ,#10
  109. $qux#11
  110. #12
  111. ;#13
  112. }
  113. ',
  114. '<?php class#1
  115. Foo#2
  116. {#3
  117. protected#4
  118. $bar#5
  119. =#6
  120. null,#7
  121. $baz#8
  122. =#9
  123. null,#10
  124. $qux#11
  125. =#12
  126. null;#13
  127. }
  128. ',
  129. ];
  130. yield [
  131. '<?php class Foo { public static $bar; }',
  132. '<?php class Foo { public static $bar = null; }',
  133. ];
  134. yield [
  135. '<?php class Foo { protected static $bar; }',
  136. '<?php class Foo { protected static $bar = null; }',
  137. ];
  138. yield [
  139. '<?php class Foo { private static $bar; }',
  140. '<?php class Foo { private static $bar = null; }',
  141. ];
  142. yield [
  143. '<?php class Foo { static $bar; }',
  144. '<?php class Foo { static $bar = null; }',
  145. ];
  146. yield [
  147. '<?php class Foo { STATIC $bar; }',
  148. '<?php class Foo { STATIC $bar = null; }',
  149. ];
  150. yield [
  151. '<?php class Foo { public static $bar; }',
  152. '<?php class Foo { public static $bar = NULL; }',
  153. ];
  154. yield [
  155. '<?php class Foo { PUblic STatic $bar; }',
  156. '<?php class Foo { PUblic STatic $bar = nuLL; }',
  157. ];
  158. yield [
  159. '<?php trait Foo { public static $bar; }',
  160. '<?php trait Foo { public static $bar = nuLL; }',
  161. ];
  162. yield [
  163. '<?php class Foo { public static $bar; }',
  164. '<?php class Foo { public static $bar = \null; }',
  165. ];
  166. yield [
  167. '<?php class Foo {/* */public/* */static/* A */$bar/* B *//** C */;/* D */}',
  168. '<?php class Foo {/* */public/* */static/* A */$bar/* B */=/** C */null;/* D */}',
  169. ];
  170. yield [
  171. '<?php class Foo { public static $bar; protected static $baz; }',
  172. '<?php class Foo { public static $bar = null; protected static $baz = null; }',
  173. ];
  174. yield [
  175. '<?php class Foo { public static $bar = \'null\'; }',
  176. ];
  177. yield [
  178. '<?php class Foo { public static function bar() { return null; } }',
  179. ];
  180. yield [
  181. '<?php class Foo { protected static $bar, $baz, $qux; }',
  182. '<?php class Foo { protected static $bar = null, $baz = null, $qux = null; }',
  183. ];
  184. yield [
  185. '<?php class Foo { protected static $bar, $baz = \'baz\', $qux; }',
  186. '<?php class Foo { protected static $bar, $baz = \'baz\', $qux = null; }',
  187. ];
  188. yield [
  189. '<?php trait Foo { public static $bar; } abstract class Bar { protected static $bar, $baz = \'baz\', $qux; }',
  190. '<?php trait Foo { public static $bar = null; } abstract class Bar { protected static $bar, $baz = \'baz\', $qux = null; }',
  191. ];
  192. yield [
  193. '<?php class Foo { public function foo() { return null; } public static $bar; public function baz() { return null; } }',
  194. '<?php class Foo { public function foo() { return null; } public static $bar = null; public function baz() { return null; } }',
  195. ];
  196. yield [
  197. '<?php class#1
  198. Foo#2
  199. {#3
  200. protected#4
  201. static#4.5
  202. $bar#5
  203. #6
  204. ,#7
  205. $baz#8
  206. #9
  207. ,#10
  208. $qux#11
  209. #12
  210. ;#13
  211. }
  212. ',
  213. '<?php class#1
  214. Foo#2
  215. {#3
  216. protected#4
  217. static#4.5
  218. $bar#5
  219. =#6
  220. null,#7
  221. $baz#8
  222. =#9
  223. null,#10
  224. $qux#11
  225. =#12
  226. null;#13
  227. }
  228. ',
  229. ];
  230. yield [
  231. '<?php class Foo { const FOO = null; }',
  232. ];
  233. yield [
  234. '<?php class Foo { public function foo() { static $foo = null; } }',
  235. ];
  236. yield [
  237. '<?php function foo() { static $foo = null; }',
  238. ];
  239. yield [
  240. '<?php new class () { public $bar; };',
  241. '<?php new class () { public $bar = null; };',
  242. ];
  243. yield [
  244. '<?php class Foo { public function foo() { return new class() { private $bar; }; } }',
  245. '<?php class Foo { public function foo() { return new class() { private $bar = null; }; } }',
  246. ];
  247. yield [
  248. '<?php class Foo { public function foo() { return new class() { private $bar; }; } } trait Baz { public $baz; }',
  249. '<?php class Foo { public function foo() { return new class() { private $bar = null; }; } } trait Baz { public $baz = null; }',
  250. ];
  251. yield [
  252. '<?php new class () { public static $bar; };',
  253. '<?php new class () { public static $bar = null; };',
  254. ];
  255. yield [
  256. '<?php class Foo { public function foo() { return new class() { private static $bar; }; } }',
  257. '<?php class Foo { public function foo() { return new class() { private static $bar = null; }; } }',
  258. ];
  259. yield [
  260. '<?php class Foo { public function foo() { return new class() { private static $bar; }; } } trait Baz { public static $baz; }',
  261. '<?php class Foo { public function foo() { return new class() { private static $bar = null; }; } } trait Baz { public static $baz = null; }',
  262. ];
  263. yield [
  264. '<?php class Foo { public function foo() { return new class() { public function foo() { static $foo = null; } }; } }',
  265. ];
  266. yield [
  267. '<?php function foo() { return new class() { public function foo() { static $foo = null; } }; }',
  268. ];
  269. yield [
  270. '<?php class Foo { public const FOO = null; }',
  271. ];
  272. yield [
  273. '<?php class Foo { protected ?int $bar = null; }',
  274. ];
  275. yield [
  276. '<?php class Foo { protected ? string $bar = null; }',
  277. ];
  278. yield [
  279. '<?php class Foo { protected ? array $bar = null; }',
  280. ];
  281. yield [
  282. '<?php class Foo { protected static ?int $bar = null; }',
  283. ];
  284. yield [
  285. '<?php class Foo { protected static ? string $bar = null; }',
  286. ];
  287. yield [
  288. '<?php class Foo { protected static ? array $bar = null; }',
  289. ];
  290. }
  291. /**
  292. * @dataProvider provideFixPrePHP80Cases
  293. *
  294. * @requires PHP <8.0
  295. */
  296. public function testFixPrePHP80(string $expected, ?string $input = null): void
  297. {
  298. $this->doTest($expected, $input);
  299. }
  300. public static function provideFixPrePHP80Cases(): iterable
  301. {
  302. yield [
  303. '<?php class Foo { public $bar; }',
  304. '<?php class Foo { public $bar = \ null; }',
  305. ];
  306. yield [
  307. '<?php class Foo { public $bar/* oh hai! */; }',
  308. '<?php class Foo { public $bar = \/* oh hai! */null; }',
  309. ];
  310. yield [
  311. '<?php class Foo { public static $bar; }',
  312. '<?php class Foo { public static $bar = \ null; }',
  313. ];
  314. yield [
  315. '<?php class Foo { public static $bar/* oh hai! */; }',
  316. '<?php class Foo { public static $bar = \/* oh hai! */null; }',
  317. ];
  318. }
  319. /**
  320. * @requires PHP 8.0
  321. */
  322. public function testFixPhp80(): void
  323. {
  324. $this->doTest('<?php
  325. class Point {
  326. public function __construct(
  327. public ?float $x = null,
  328. protected ?float $y = null,
  329. private ?float $z = null,
  330. ) {}
  331. }
  332. ');
  333. }
  334. /**
  335. * @dataProvider provideFix81Cases
  336. *
  337. * @requires PHP 8.1
  338. */
  339. public function testFix81(string $expected, ?string $input = null): void
  340. {
  341. $this->doTest($expected, $input);
  342. }
  343. public static function provideFix81Cases(): iterable
  344. {
  345. yield 'readonly - cannot have default value, fixer should not crash' => [
  346. '<?php
  347. final class Foo
  348. {
  349. public readonly string $prop;
  350. }',
  351. ];
  352. }
  353. }