NoNullPropertyInitializationFixerTest.php 11 KB

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