SelfAccessorFixerTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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 Gregor Harlan <gharlan@web.de>
  16. *
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer
  20. */
  21. final class SelfAccessorFixerTest 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 { const BAR = self::BAZ; }',
  34. '<?php class Foo { const BAR = Foo::BAZ; }',
  35. ];
  36. yield [
  37. '<?php class Foo { private $bar = self::BAZ; }',
  38. '<?php class Foo { private $bar = fOO::BAZ; }', // case insensitive
  39. ];
  40. yield [
  41. '<?php class Foo { function bar($a = self::BAR) {} }',
  42. '<?php class Foo { function bar($a = Foo::BAR) {} }',
  43. ];
  44. yield [
  45. '<?php class Foo { function bar() { self::baz(); } }',
  46. '<?php class Foo { function bar() { Foo::baz(); } }',
  47. ];
  48. yield [
  49. '<?php class Foo { function bar() { self::class; } }',
  50. '<?php class Foo { function bar() { Foo::class; } }',
  51. ];
  52. yield [
  53. '<?php class Foo { function bar() { $x instanceof self; } }',
  54. '<?php class Foo { function bar() { $x instanceof Foo; } }',
  55. ];
  56. yield [
  57. '<?php class Foo { function bar() { new self(); } }',
  58. '<?php class Foo { function bar() { new Foo(); } }',
  59. ];
  60. yield [
  61. '<?php interface Foo { const BAR = self::BAZ; function bar($a = self::BAR); }',
  62. '<?php interface Foo { const BAR = Foo::BAZ; function bar($a = Foo::BAR); }',
  63. ];
  64. yield [
  65. '<?php class Foo { const Foo = 1; }',
  66. ];
  67. yield [
  68. '<?php class Foo { function foo() { } }',
  69. ];
  70. yield [
  71. '<?php class Foo { function bar() { new \Baz\Foo(); } }',
  72. ];
  73. yield [
  74. '<?php class Foo { function bar() { new Foo\Baz(); } }',
  75. ];
  76. yield [
  77. '<?php class Foo { function bar() { Baz\Foo::class; } }',
  78. ];
  79. yield [
  80. // In trait "self" will reference the class it's used in, not the actual trait, so we can't replace "Foo" with "self" here
  81. '<?php trait Foo { function bar() { Foo::bar(); } } class Bar { use Foo; }',
  82. ];
  83. yield [
  84. '<?php class Foo { public function bar(self $foo, self $bar) { return new self(); } }',
  85. '<?php class Foo { public function bar(Foo $foo, Foo $bar) { return new Foo(); } }',
  86. ];
  87. yield [
  88. '<?php interface Foo { public function bar(self $foo, self $bar); }',
  89. '<?php interface Foo { public function bar(Foo $foo, Foo $bar); }',
  90. ];
  91. yield [
  92. '<?php interface Foo { public function bar(self $foo); }',
  93. '<?php interface Foo { public function bar(\Foo $foo); }',
  94. ];
  95. yield [
  96. '<?php namespace Foo; interface Bar { public function baz(\Bar $bar); }',
  97. ];
  98. yield [
  99. '<?php namespace Foo; interface Bar { public function baz(self $bar); }',
  100. '<?php namespace Foo; interface Bar { public function baz(Bar $bar); }',
  101. ];
  102. yield [
  103. '<?php namespace Foo; interface Bar { public function baz(self $bar); }',
  104. '<?php namespace Foo; interface Bar { public function baz(\Foo\Bar $bar); }',
  105. ];
  106. yield [
  107. '<?php namespace Foo; interface Bar { public function baz(Foo\Bar $bar); }',
  108. ];
  109. yield [
  110. '<?php namespace Foo; interface Bar { public function baz(Bar\Foo $bar); }',
  111. ];
  112. yield [
  113. '<?php
  114. namespace Foo\Foo2;
  115. interface Bar {
  116. public function baz00(Foo2\Bar $bar);
  117. public function baz10(\Foo2\Bar $bar);
  118. public function baz20(Foo\Foo2\Bar $bar);
  119. public function baz21(self $bar);
  120. public function baz30(Test\Foo\Foo2\Bar $bar);
  121. public function baz31(\Test\Foo\Foo2\Bar $bar);
  122. }',
  123. '<?php
  124. namespace Foo\Foo2;
  125. interface Bar {
  126. public function baz00(Foo2\Bar $bar);
  127. public function baz10(\Foo2\Bar $bar);
  128. public function baz20(Foo\Foo2\Bar $bar);
  129. public function baz21(\Foo\Foo2\Bar $bar);
  130. public function baz30(Test\Foo\Foo2\Bar $bar);
  131. public function baz31(\Test\Foo\Foo2\Bar $bar);
  132. }',
  133. ];
  134. yield [
  135. '<?php class Foo { function bar() {
  136. new class() { function baz() { new Foo(); } };
  137. } }',
  138. ];
  139. yield [
  140. '<?php class Foo { protected $foo; function bar() { return $this->foo::find(2); } }',
  141. ];
  142. yield [
  143. '<?php class Foo { public function bar(self $foo, self $bar): self { return new self(); } }',
  144. '<?php class Foo { public function bar(Foo $foo, Foo $bar): Foo { return new Foo(); } }',
  145. ];
  146. yield [
  147. '<?php interface Foo { public function bar(self $foo, self $bar): self; }',
  148. '<?php interface Foo { public function bar(Foo $foo, Foo $bar): Foo; }',
  149. ];
  150. yield [
  151. '<?php class Foo { public function bar(?self $foo, ?self $bar): ?self { return new self(); } }',
  152. '<?php class Foo { public function bar(?Foo $foo, ?Foo $bar): ?Foo { return new Foo(); } }',
  153. ];
  154. yield [
  155. "<?php interface Foo{ public function bar()\t/**/:?/**/self; }",
  156. "<?php interface Foo{ public function bar()\t/**/:?/**/Foo; }",
  157. ];
  158. yield 'do not replace in lambda' => [
  159. '<?php
  160. final class A
  161. {
  162. public static function Z(): void
  163. {
  164. (function () {
  165. var_dump(self::class, A::class);
  166. })->bindTo(null, B::class)();
  167. }
  168. }',
  169. ];
  170. yield 'do not replace in arrow function' => [
  171. '<?php
  172. final class A
  173. {
  174. public function Z($b): void
  175. {
  176. $a = fn($b) => self::class. A::class . $b;
  177. echo $a;
  178. }
  179. }',
  180. ];
  181. }
  182. /**
  183. * @dataProvider provideFix80Cases
  184. *
  185. * @requires PHP 8.0
  186. */
  187. public function testFix80(string $expected, ?string $input = null): void
  188. {
  189. $this->doTest($expected, $input);
  190. }
  191. public static function provideFix80Cases(): iterable
  192. {
  193. yield [
  194. '<?php interface Foo { public function bar(self $foo, self $bar,): self; }',
  195. '<?php interface Foo { public function bar(Foo $foo, Foo $bar,): Foo; }',
  196. ];
  197. yield [
  198. '<?php class Foo { function bar() { $x instanceof (Foo()); } }',
  199. ];
  200. yield [
  201. '<?php class Foo { protected $foo; function bar() { return $this?->foo::find(2); } }',
  202. ];
  203. yield [
  204. '<?php class Foo { public function f(self|Bar|Baz $b) {} }',
  205. '<?php class Foo { public function f(Foo|Bar|Baz $b) {} }',
  206. ];
  207. yield [
  208. '<?php class Foo { public function f(Bar|self|Baz $b) {} }',
  209. '<?php class Foo { public function f(Bar|Foo|Baz $b) {} }',
  210. ];
  211. yield [
  212. '<?php class Foo { public function f(Bar|Baz|self $b) {} }',
  213. '<?php class Foo { public function f(Bar|Baz|Foo $b) {} }',
  214. ];
  215. yield [
  216. '<?php class Foo { public function f(Bar|Foo\C|Baz $b) {} }',
  217. ];
  218. yield [
  219. '<?php class Foo { public function f(Bar|C\Foo|Baz $b) {} }',
  220. ];
  221. }
  222. /**
  223. * @dataProvider provideFix82Cases
  224. *
  225. * @requires PHP 8.2
  226. */
  227. public function testFix82(string $expected, ?string $input = null): void
  228. {
  229. $this->doTest($expected, $input);
  230. }
  231. public static function provideFix82Cases(): iterable
  232. {
  233. yield [
  234. '<?php class Foo { public function f(self|(Bar&Baz)|Qux $b) {} }',
  235. '<?php class Foo { public function f(Foo|(Bar&Baz)|Qux $b) {} }',
  236. ];
  237. yield [
  238. '<?php class Foo { public function f(Bar|(Baz&Qux)|self $b) {} }',
  239. '<?php class Foo { public function f(Bar|(Baz&Qux)|Foo $b) {} }',
  240. ];
  241. }
  242. }