OrderedTypesFixerTest.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  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 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\OrderedTypesFixer
  20. */
  21. final class OrderedTypesFixerTest extends AbstractFixerTestCase
  22. {
  23. /**
  24. * @dataProvider provideFixCases
  25. *
  26. * @param null|array<string, string> $config
  27. */
  28. public function testFix(string $expected, ?string $input = null, ?array $config = null): void
  29. {
  30. if (null !== $config) {
  31. $this->fixer->configure($config);
  32. }
  33. $this->doTest($expected, $input);
  34. }
  35. /**
  36. * @return iterable<string, array{string, 1?: ?string, 2?: array<string, mixed>}>
  37. */
  38. public static function provideFixCases(): iterable
  39. {
  40. yield 'catch with default, no spaces, with both leading slash' => [
  41. '<?php
  42. try {
  43. $this->foo();
  44. } catch (\LogicException|\RuntimeException $e) {
  45. // $e
  46. }
  47. ',
  48. '<?php
  49. try {
  50. $this->foo();
  51. } catch (\RuntimeException|\LogicException $e) {
  52. // $e
  53. }
  54. ',
  55. ];
  56. yield 'catch with default, with spaces, with both leading slash' => [
  57. '<?php
  58. try {
  59. $this->foo();
  60. } catch (\LogicException|\RuntimeException $e) {
  61. // $e
  62. }
  63. ',
  64. '<?php
  65. try {
  66. $this->foo();
  67. } catch (\RuntimeException | \LogicException $e) {
  68. // $e
  69. }
  70. ',
  71. ];
  72. yield 'catch with default, no spaces, with no leading slash' => [
  73. '<?php
  74. try {
  75. cache()->save();
  76. } catch (CacheException|SimpleCacheException $e) {
  77. // $e
  78. }
  79. ',
  80. '<?php
  81. try {
  82. cache()->save();
  83. } catch (SimpleCacheException|CacheException $e) {
  84. // $e
  85. }
  86. ',
  87. ];
  88. yield 'catch with default, with spaces, with one leading slash' => [
  89. '<?php
  90. try {
  91. cache()->save();
  92. } catch (CacheException|\RuntimeException $e) {
  93. // $e
  94. }
  95. ',
  96. '<?php
  97. try {
  98. cache()->save();
  99. } catch (\RuntimeException | CacheException $e) {
  100. // $e
  101. }
  102. ',
  103. ];
  104. yield 'catch with no sorting' => [
  105. '<?php
  106. try {
  107. $this->foo();
  108. } catch (\RuntimeException|\LogicException $e) {
  109. // $e
  110. }
  111. ',
  112. null,
  113. ['sort_algorithm' => 'none'],
  114. ];
  115. yield 'nothing to fix' => [
  116. '<?php
  117. try {
  118. $this->foo();
  119. } catch (\LogicException $e) {
  120. // $e
  121. }
  122. ',
  123. ];
  124. yield 'already fixed' => [
  125. '<?php
  126. try {
  127. $this->foo();
  128. } catch (LogicException|RuntimeException $e) {
  129. // $e
  130. }
  131. ',
  132. ];
  133. }
  134. /**
  135. * @dataProvider provideFix80Cases
  136. *
  137. * @param null|array<string, string> $config
  138. *
  139. * @requires PHP 8.0
  140. */
  141. public function testFix80(string $expected, ?string $input = null, ?array $config = null): void
  142. {
  143. if (null !== $config) {
  144. $this->fixer->configure($config);
  145. }
  146. $this->doTest($expected, $input);
  147. }
  148. /**
  149. * @return iterable<int|string, array{string, 1?: ?string, 2?: array<string, mixed>}>
  150. */
  151. public static function provideFix80Cases(): iterable
  152. {
  153. yield 'sort alpha, null none' => [
  154. "<?php\nclass Foo\n{\n public A|null|Z \$bar;\n}\n",
  155. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  156. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  157. ];
  158. yield 'sort alpha, null first' => [
  159. "<?php\nclass Foo\n{\n public null|A|Z \$bar;\n}\n",
  160. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  161. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_first'],
  162. ];
  163. yield 'sort alpha, null last' => [
  164. "<?php\nclass Foo\n{\n public A|Z|null \$bar;\n}\n",
  165. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  166. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  167. ];
  168. yield 'sort none, null first' => [
  169. "<?php\nclass Foo\n{\n public null|Z|A \$bar;\n}\n",
  170. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  171. ['sort_algorithm' => 'none', 'null_adjustment' => 'always_first'],
  172. ];
  173. yield 'sort none, null last' => [
  174. "<?php\nclass Foo\n{\n public Z|A|null \$bar;\n}\n",
  175. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  176. ['sort_algorithm' => 'none', 'null_adjustment' => 'always_last'],
  177. ];
  178. yield 'sort none, null none' => [
  179. "<?php\nclass Foo\n{\n public Z|null|A \$bar;\n}\n",
  180. null,
  181. ['sort_algorithm' => 'none', 'null_adjustment' => 'none'],
  182. ];
  183. yield [
  184. "<?php\nclass Foo\n{\n public null|int|string \$bar = null;\n}\n",
  185. "<?php\nclass Foo\n{\n public string|null|int \$bar = null;\n}\n",
  186. ];
  187. yield [
  188. "<?php\nclass Foo\n{\n public null|A|B \$foo = null;\n}\n",
  189. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  190. ];
  191. yield [
  192. "<?php\nclass Foo\n{\n public null|\\A|B \$foo = null;\n}\n",
  193. "<?php\nclass Foo\n{\n public B|\\A|null \$foo = null;\n}\n",
  194. ];
  195. yield [
  196. "<?php\nclass Foo\n{\n public null|\\A|\\B \$foo = null;\n}\n",
  197. "<?php\nclass Foo\n{\n public \\B|\\A|null \$foo = null;\n}\n",
  198. ];
  199. yield [
  200. "<?php\nclass Foo\n{\n public null|int|string/* array */ \$bar = null;\n}\n",
  201. "<?php\nclass Foo\n{\n public string|null|int/* array */ \$bar = null;\n}\n",
  202. ];
  203. yield [
  204. "<?php\nclass Foo\n{\n public /* int */null|A|B \$foo = null;\n}\n",
  205. "<?php\nclass Foo\n{\n public /* int */B|A|null \$foo = null;\n}\n",
  206. ];
  207. yield [
  208. "<?php\nclass Foo\n{\n public null|A|B \$foo = null;\n}\n",
  209. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  210. ];
  211. yield [
  212. "<?php\nclass Foo\n{\n private function bar(null|array|callable|int \$cb) {}\n}\n",
  213. "<?php\nclass Foo\n{\n private function bar(array|int|callable|null \$cb) {}\n}\n",
  214. ];
  215. yield [
  216. "<?php\nclass Foo\n{\n private function bar(\$cb): null|array|callable|int {}\n}\n",
  217. "<?php\nclass Foo\n{\n private function bar(\$cb): array|int|callable|null {}\n}\n",
  218. ];
  219. yield [
  220. "<?php\nclass Foo\n{\n private function bar(\$cb): null|static {}\n}\n",
  221. "<?php\nclass Foo\n{\n private function bar(\$cb): static|null {}\n}\n",
  222. ];
  223. yield [
  224. "<?php\nclass Foo\n{\n public function bar(null|string \$str, null|array|int \$arr) {}\n}\n",
  225. "<?php\nclass Foo\n{\n public function bar(string|null \$str, int|array|null \$arr) {}\n}\n",
  226. ];
  227. yield [
  228. "<?php\nclass Foo\n{\n public function bar(\\JsonSerializable|\\Stringable \$obj): array|int {}\n}\n",
  229. "<?php\nclass Foo\n{\n public function bar(\\Stringable|\\JsonSerializable \$obj): int|array {}\n}\n",
  230. ];
  231. yield [
  232. '<?php function foo(null|int|string $bar): null|\Stringable {}',
  233. '<?php function foo(string|int|null $bar): \Stringable|null {}',
  234. ];
  235. yield [
  236. '<?php fn (null|\Countable|int $number): null|int => $number;',
  237. '<?php fn (int|\Countable|null $number): int|null => $number;',
  238. ];
  239. yield [
  240. "<?php\ntry {\n foo();\n} catch (\\Error|\\TypeError) {\n}\n",
  241. "<?php\ntry {\n foo();\n} catch (\\TypeError|\\Error) {\n}\n",
  242. ];
  243. yield [
  244. '<?php
  245. class Foo
  246. {
  247. public ?string $foo = null;
  248. public /* int|string */ $bar;
  249. private null|array $baz = null;
  250. public function baz(): null|string {}
  251. protected function bar(string $str, ?array $config = null): callable {}
  252. }
  253. try {
  254. (new Foo)->baz();
  255. } catch (Exception $e) {
  256. return $e;
  257. }
  258. ',
  259. ];
  260. yield [
  261. "<?php\nclass Foo\n{\n public int|string|null \$bar = null;\n}\n",
  262. "<?php\nclass Foo\n{\n public string|null|int \$bar = null;\n}\n",
  263. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  264. ];
  265. yield [
  266. "<?php\nclass Foo\n{\n public A|B|null \$foo = null;\n}\n",
  267. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  268. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  269. ];
  270. yield [
  271. "<?php\nclass Foo\n{\n public \\A|B|null \$foo = null;\n}\n",
  272. "<?php\nclass Foo\n{\n public B|\\A|null \$foo = null;\n}\n",
  273. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  274. ];
  275. yield [
  276. "<?php\nclass Foo\n{\n public \\A|\\B|null \$foo = null;\n}\n",
  277. "<?php\nclass Foo\n{\n public \\B|\\A|null \$foo = null;\n}\n",
  278. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  279. ];
  280. yield [
  281. "<?php\nclass Foo\n{\n public int|string|null/* array */ \$bar = null;\n}\n",
  282. "<?php\nclass Foo\n{\n public string|null|int/* array */ \$bar = null;\n}\n",
  283. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  284. ];
  285. yield [
  286. "<?php\nclass Foo\n{\n public /* int */A|B|null \$foo = null;\n}\n",
  287. "<?php\nclass Foo\n{\n public /* int */B|A|null \$foo = null;\n}\n",
  288. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  289. ];
  290. yield [
  291. "<?php\nclass Foo\n{\n public A|B|null \$foo = null;\n}\n",
  292. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  293. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  294. ];
  295. yield [
  296. "<?php\nclass Foo\n{\n private function bar(array|callable|int|null \$cb) {}\n}\n",
  297. "<?php\nclass Foo\n{\n private function bar(array|int|callable|null \$cb) {}\n}\n",
  298. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  299. ];
  300. yield [
  301. "<?php\nclass Foo\n{\n private function bar(\$cb): array|callable|int|null {}\n}\n",
  302. "<?php\nclass Foo\n{\n private function bar(\$cb): array|int|callable|null {}\n}\n",
  303. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  304. ];
  305. yield [
  306. "<?php\nclass Foo\n{\n private function bar(\$cb): static|null {}\n}\n",
  307. "<?php\nclass Foo\n{\n private function bar(\$cb): null|static {}\n}\n",
  308. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  309. ];
  310. yield [
  311. "<?php\nclass Foo\n{\n public function bar(string|null \$str, array|int|null \$arr) {}\n}\n",
  312. "<?php\nclass Foo\n{\n public function bar(string|null \$str, int|array|null \$arr) {}\n}\n",
  313. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  314. ];
  315. yield [
  316. "<?php\nclass Foo\n{\n public function bar(\\JsonSerializable|\\Stringable \$obj): array|int {}\n}\n",
  317. "<?php\nclass Foo\n{\n public function bar(\\Stringable|\\JsonSerializable \$obj): int|array {}\n}\n",
  318. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  319. ];
  320. yield [
  321. '<?php function foo(int|string|null $bar): \Stringable|null {}',
  322. '<?php function foo(string|int|null $bar): \Stringable|null {}',
  323. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  324. ];
  325. yield [
  326. '<?php fn (\Countable|int|null $number): int|null => $number;',
  327. '<?php fn (int|\Countable|null $number): int|null => $number;',
  328. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  329. ];
  330. yield [
  331. "<?php\ntry {\n foo();\n} catch (\\Error|\\TypeError) {\n}\n",
  332. "<?php\ntry {\n foo();\n} catch (\\TypeError|\\Error) {\n}\n",
  333. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  334. ];
  335. yield [
  336. '<?php
  337. class Foo
  338. {
  339. public ?string $foo = null;
  340. public /* int|string */ $bar;
  341. private array|null $baz = null;
  342. public function baz(): string|null {}
  343. protected function bar(string $str, ?array $config = null): callable {}
  344. }
  345. try {
  346. (new Foo)->baz();
  347. } catch (Exception $e) {
  348. return $e;
  349. }
  350. ',
  351. null,
  352. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'always_last'],
  353. ];
  354. yield [
  355. "<?php\nclass Foo\n{\n public int|null|string \$bar = null;\n}\n",
  356. "<?php\nclass Foo\n{\n public string|null|int \$bar = null;\n}\n",
  357. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  358. ];
  359. yield [
  360. "<?php\nclass Foo\n{\n public A|B|null \$foo = null;\n}\n",
  361. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  362. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  363. ];
  364. yield [
  365. "<?php\nclass Foo\n{\n public \\A|B|null \$foo = null;\n}\n",
  366. "<?php\nclass Foo\n{\n public B|\\A|null \$foo = null;\n}\n",
  367. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  368. ];
  369. yield [
  370. "<?php\nclass Foo\n{\n public \\A|\\B|null \$foo = null;\n}\n",
  371. "<?php\nclass Foo\n{\n public \\B|\\A|null \$foo = null;\n}\n",
  372. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  373. ];
  374. yield [
  375. "<?php\nclass Foo\n{\n public int|null|string/* array */ \$bar = null;\n}\n",
  376. "<?php\nclass Foo\n{\n public string|null|int/* array */ \$bar = null;\n}\n",
  377. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  378. ];
  379. yield [
  380. "<?php\nclass Foo\n{\n public /* int */A|B|null \$foo = null;\n}\n",
  381. "<?php\nclass Foo\n{\n public /* int */B|A|null \$foo = null;\n}\n",
  382. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  383. ];
  384. yield [
  385. "<?php\nclass Foo\n{\n public A|B|null \$foo = null;\n}\n",
  386. "<?php\nclass Foo\n{\n public B|A|null \$foo = null;\n}\n",
  387. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  388. ];
  389. yield [
  390. "<?php\nclass Foo\n{\n private function bar(array|callable|int|null \$cb) {}\n}\n",
  391. "<?php\nclass Foo\n{\n private function bar(array|int|callable|null \$cb) {}\n}\n",
  392. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  393. ];
  394. yield [
  395. "<?php\nclass Foo\n{\n private function bar(\$cb): array|callable|int|null {}\n}\n",
  396. "<?php\nclass Foo\n{\n private function bar(\$cb): array|int|callable|null {}\n}\n",
  397. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  398. ];
  399. yield [
  400. "<?php\nclass Foo\n{\n private function bar(\$cb): null|static {}\n}\n",
  401. "<?php\nclass Foo\n{\n private function bar(\$cb): static|null {}\n}\n",
  402. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  403. ];
  404. yield [
  405. "<?php\nclass Foo\n{\n public function bar(null|string \$str, array|int|null \$arr) {}\n}\n",
  406. "<?php\nclass Foo\n{\n public function bar(string|null \$str, int|array|null \$arr) {}\n}\n",
  407. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  408. ];
  409. yield [
  410. "<?php\nclass Foo\n{\n public function bar(\\JsonSerializable|\\Stringable \$obj): array|int {}\n}\n",
  411. "<?php\nclass Foo\n{\n public function bar(\\Stringable|\\JsonSerializable \$obj): int|array {}\n}\n",
  412. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  413. ];
  414. yield [
  415. '<?php function foo(int|null|string $bar): null|\Stringable {}',
  416. '<?php function foo(string|int|null $bar): \Stringable|null {}',
  417. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  418. ];
  419. yield [
  420. '<?php fn (\Countable|int|null $number): int|null => $number;',
  421. '<?php fn (int|\Countable|null $number): int|null => $number;',
  422. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  423. ];
  424. yield [
  425. "<?php\ntry {\n foo();\n} catch (\\Error|\\TypeError) {\n}\n",
  426. "<?php\ntry {\n foo();\n} catch (\\TypeError|\\Error) {\n}\n",
  427. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  428. ];
  429. yield [
  430. '<?php
  431. class Foo
  432. {
  433. public ?string $foo = null;
  434. public /* int|string */ $bar;
  435. private array|null $baz = null;
  436. public function baz(): null|string {}
  437. protected function bar(string $str, ?array $config = null): callable {}
  438. }
  439. try {
  440. (new Foo)->baz();
  441. } catch (Exception $e) {
  442. return $e;
  443. }
  444. ',
  445. null,
  446. ['sort_algorithm' => 'alpha', 'null_adjustment' => 'none'],
  447. ];
  448. yield [
  449. "<?php\nclass Foo\n{\n public null|int|string \$bar = null;\n}\n",
  450. "<?php\nclass Foo\n{\n public string | null | int \$bar = null;\n}\n",
  451. ];
  452. yield [
  453. "<?php\nclass Foo\n{\n public null|int|string \$bar = null;\n}\n",
  454. "<?php\nclass Foo\n{\n public string | null | int \$bar = null;\n}\n",
  455. ];
  456. yield [
  457. "<?php\nclass Foo\n{\n public null|int|string \$bar = null;\n}\n",
  458. "<?php\nclass Foo\n{\n public string |/* array| */null|int \$bar = null;\n}\n",
  459. ];
  460. yield [
  461. "<?php\nclass Foo\n{\n private function bar(\$cb): null|static {}\n}\n",
  462. "<?php\nclass Foo\n{\n private function bar(\$cb): static /* |int */ | null {}\n}\n",
  463. ];
  464. yield 'case sensitive cases' => [
  465. "<?php\nclass Foo\n{\n public null|AAa|Aa \$bar = null;\n}\n",
  466. "<?php\nclass Foo\n{\n public Aa|AAa|null \$bar = null;\n}\n",
  467. ['case_sensitive' => true],
  468. ];
  469. }
  470. /**
  471. * @dataProvider provideFix81Cases
  472. *
  473. * @param null|array<string, string> $config
  474. *
  475. * @requires PHP 8.1
  476. */
  477. public function testFix81(string $expected, ?string $input = null, ?array $config = null): void
  478. {
  479. if (null !== $config) {
  480. $this->fixer->configure($config);
  481. }
  482. $this->doTest($expected, $input);
  483. }
  484. /**
  485. * @return iterable<array{string, 1: ?string, 2?: array<string, mixed>}>
  486. */
  487. public static function provideFix81Cases(): iterable
  488. {
  489. yield [
  490. "<?php\nclass Foo\n{\n public A&B \$bar;\n}\n",
  491. "<?php\nclass Foo\n{\n public B&A \$bar;\n}\n",
  492. ];
  493. yield [
  494. "<?php\nclass Foo\n{\n public Ae&At \$bar;\n}\n",
  495. "<?php\nclass Foo\n{\n public At&Ae \$bar;\n}\n",
  496. ];
  497. yield [
  498. "<?php\nclass Foo\n{\n public readonly null|A|B \$bar;\n}\n",
  499. "<?php\nclass Foo\n{\n public readonly B|null|A \$bar;\n}\n",
  500. ];
  501. yield [
  502. "<?php\nclass Foo\n{\n public readonly A|B|null \$bar;\n}\n",
  503. "<?php\nclass Foo\n{\n public readonly B|null|A \$bar;\n}\n",
  504. ['null_adjustment' => 'always_last'],
  505. ];
  506. yield [
  507. "<?php\nclass Foo\n{\n public readonly A|null|X \$bar;\n}\n",
  508. "<?php\nclass Foo\n{\n public readonly X|A|null \$bar;\n}\n",
  509. ['null_adjustment' => 'none'],
  510. ];
  511. yield [
  512. "<?php\nclass Foo\n{\n public B&A \$bar;\n}\n",
  513. null,
  514. ['sort_algorithm' => 'none'],
  515. ];
  516. }
  517. /**
  518. * Provisional support for PHP 8.2's Disjunctive Normal Form (DNF) Types.
  519. *
  520. * @dataProvider provideFix82Cases
  521. *
  522. * @param null|array<string, string> $config
  523. *
  524. * @requires PHP 8.2
  525. */
  526. public function testFix82(string $expected, ?string $input = null, ?array $config = null): void
  527. {
  528. if (null !== $config) {
  529. $this->fixer->configure($config);
  530. }
  531. $this->doTest($expected, $input);
  532. }
  533. /**
  534. * @return iterable<array{string, 1: ?string, 2?: array<string, mixed>}>
  535. */
  536. public static function provideFix82Cases(): iterable
  537. {
  538. yield [
  539. "<?php\nclass Foo\n{\n public null|array|(At&Bz)|string \$bar = null;\n}\n",
  540. "<?php\nclass Foo\n{\n public string|(Bz&At)|array|null \$bar = null;\n}\n",
  541. ];
  542. yield [
  543. "<?php\nclass Foo\n{\n public array|(At&Bz)|string|null \$bar = null;\n}\n",
  544. "<?php\nclass Foo\n{\n public string|(Bz&At)|array|null \$bar = null;\n}\n",
  545. ['null_adjustment' => 'always_last'],
  546. ];
  547. yield [
  548. "<?php\nclass Foo\n{\n public array|(At&Bz)|null|string \$bar = null;\n}\n",
  549. "<?php\nclass Foo\n{\n public string|(Bz&At)|array|null \$bar = null;\n}\n",
  550. ['null_adjustment' => 'none'],
  551. ];
  552. yield [
  553. "<?php\nclass Foo\n{\n public (A&B)|(A&C)|(B&D)|(C&D) \$bar;\n}\n",
  554. "<?php\nclass Foo\n{\n public (D&B)|(C&A)|(B&A)|(D&C) \$bar;\n}\n",
  555. ['sort_algorithm' => 'alpha'],
  556. ];
  557. yield [
  558. "<?php\nclass Foo\n{\n public (A&B)|(\\A&C)|(B&\\D)|(C&D) \$bar;\n}\n",
  559. "<?php\nclass Foo\n{\n public (\\D&B)|(C&\\A)|(B&A)|(D&C) \$bar;\n}\n",
  560. ['sort_algorithm' => 'alpha'],
  561. ];
  562. yield [
  563. "<?php\nclass Foo\n{\n public (A&C)|(B&D) \$bar;\n}\n",
  564. "<?php\nclass Foo\n{\n public (D&B)|(C&A) \$bar;\n}\n",
  565. ['sort_algorithm' => 'alpha'],
  566. ];
  567. yield [
  568. "<?php\nclass Foo\n{\n public (\\A&\\C)|(\\B&\\D) \$bar;\n}\n",
  569. "<?php\nclass Foo\n{\n public (\\D&\\B)|(\\C&\\A) \$bar;\n}\n",
  570. ['sort_algorithm' => 'alpha'],
  571. ];
  572. }
  573. }