VoidReturnFixerTest.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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\FunctionNotation;
  13. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\Tokenizer\Tokens;
  15. /**
  16. * @author Mark Nielsen
  17. *
  18. * @internal
  19. *
  20. * @requires PHP 7.1
  21. * @covers \PhpCsFixer\Fixer\FunctionNotation\VoidReturnFixer
  22. */
  23. final class VoidReturnFixerTest 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. public function provideFixCases(): array
  33. {
  34. return [
  35. ['<?php class Test { public function __construct() {} }'],
  36. ['<?php class Test { public function __destruct() {} }'],
  37. ['<?php class Test { public function __clone() {} }'],
  38. ['<?php function foo($param) { return $param; }'],
  39. ['<?php function foo($param) { return null; }'],
  40. ['<?php function foo($param) { yield; }'],
  41. ['<?php function foo($param) { yield $param; }'],
  42. ['<?php function foo($param) { yield from test(); }'],
  43. ['<?php function foo($param): Void {}'],
  44. ['<?php interface Test { public function foo($param); }'],
  45. ['<?php function foo($param) { return function($a) use ($param): string {}; }'],
  46. ['<?php abstract class Test { abstract public function foo($param); }'],
  47. ['<?php
  48. /**
  49. * @return array
  50. */
  51. function foo($param) {}
  52. '],
  53. ['<?php
  54. interface Test {
  55. /**
  56. * @return array
  57. */
  58. public function foo($param);
  59. }
  60. '],
  61. [
  62. '<?php function foo($param): void { return; }',
  63. '<?php function foo($param) { return; }',
  64. ],
  65. [
  66. '<?php function foo($param): void {}',
  67. '<?php function foo($param) {}',
  68. ],
  69. [
  70. '<?php class Test { public function foo($param): void { return; } }',
  71. '<?php class Test { public function foo($param) { return; } }',
  72. ],
  73. [
  74. '<?php class Test { public function foo($param): void {} }',
  75. '<?php class Test { public function foo($param) {} }',
  76. ],
  77. [
  78. '<?php trait Test { public function foo($param): void { return; } }',
  79. '<?php trait Test { public function foo($param) { return; } }',
  80. ],
  81. [
  82. '<?php trait Test { public function foo($param): void {} }',
  83. '<?php trait Test { public function foo($param) {} }',
  84. ],
  85. [
  86. '<?php $arr = []; usort($arr, function ($a, $b): void {});',
  87. '<?php $arr = []; usort($arr, function ($a, $b) {});',
  88. ],
  89. [
  90. '<?php $arr = []; $param = 1; usort($arr, function ($a, $b) use ($param): void {});',
  91. '<?php $arr = []; $param = 1; usort($arr, function ($a, $b) use ($param) {});',
  92. ],
  93. [
  94. '<?php function foo($param) { return function($a) use ($param): void {}; }',
  95. '<?php function foo($param) { return function($a) use ($param) {}; }',
  96. ],
  97. [
  98. '<?php function foo($param): void { $arr = []; usort($arr, function ($a, $b) use ($param): void {}); }',
  99. '<?php function foo($param) { $arr = []; usort($arr, function ($a, $b) use ($param) {}); }',
  100. ],
  101. [
  102. '<?php function foo() { $arr = []; return usort($arr, new class { public function __invoke($a, $b): void {} }); }',
  103. '<?php function foo() { $arr = []; return usort($arr, new class { public function __invoke($a, $b) {} }); }',
  104. ],
  105. [
  106. '<?php function foo(): void { $arr = []; usort($arr, new class { public function __invoke($a, $b): void {} }); }',
  107. '<?php function foo() { $arr = []; usort($arr, new class { public function __invoke($a, $b) {} }); }',
  108. ],
  109. [
  110. '<?php
  111. function foo(): void {
  112. $a = function (): void {};
  113. }',
  114. '<?php
  115. function foo() {
  116. $a = function () {};
  117. }',
  118. ],
  119. [
  120. '<?php
  121. function foo(): void {
  122. (function (): void {
  123. return;
  124. })();
  125. }',
  126. '<?php
  127. function foo() {
  128. (function () {
  129. return;
  130. })();
  131. }',
  132. ],
  133. [
  134. '<?php
  135. function foo(): void {
  136. (function () {
  137. return 1;
  138. })();
  139. }',
  140. '<?php
  141. function foo() {
  142. (function () {
  143. return 1;
  144. })();
  145. }',
  146. ],
  147. [
  148. '<?php
  149. function foo(): void {
  150. $b = new class {
  151. public function b1(): void {}
  152. public function b2() { return 2; }
  153. };
  154. }',
  155. '<?php
  156. function foo() {
  157. $b = new class {
  158. public function b1() {}
  159. public function b2() { return 2; }
  160. };
  161. }',
  162. ],
  163. [
  164. '<?php
  165. /**
  166. * @return void
  167. */
  168. function foo($param): void {}',
  169. '<?php
  170. /**
  171. * @return void
  172. */
  173. function foo($param) {}',
  174. ],
  175. [
  176. '<?php
  177. interface Test {
  178. /**
  179. * @return void
  180. */
  181. public function foo($param): void;
  182. }',
  183. '<?php
  184. interface Test {
  185. /**
  186. * @return void
  187. */
  188. public function foo($param);
  189. }',
  190. ],
  191. [
  192. '<?php
  193. abstract class Test {
  194. /**
  195. * @return void
  196. */
  197. abstract protected function foo($param): void;
  198. }',
  199. '<?php
  200. abstract class Test {
  201. /**
  202. * @return void
  203. */
  204. abstract protected function foo($param);
  205. }',
  206. ],
  207. ];
  208. }
  209. /**
  210. * @dataProvider provideFixPhp74Cases
  211. * @requires PHP 7.4
  212. */
  213. public function testFixPhp74(string $expected, ?string $input = null): void
  214. {
  215. $this->doTest($expected, $input);
  216. }
  217. public function provideFixPhp74Cases(): array
  218. {
  219. return [
  220. [
  221. '<?php fn($a) => null;',
  222. ],
  223. [
  224. '<?php fn($a) => 1;',
  225. ],
  226. [
  227. '<?php fn($a) => var_dump($a);',
  228. ],
  229. ];
  230. }
  231. /**
  232. * Test if magic method is handled without causing syntax error.
  233. *
  234. * @dataProvider provideMethodWillNotCauseSyntaxErrorCases
  235. */
  236. public function testMethodWillNotCauseSyntaxError(string $method, int $arguments = 0, bool $static = false): void
  237. {
  238. $tokens = Tokens::fromCode(sprintf(
  239. '<?php class Test { public%s function %s(%s) {} }',
  240. $static ? ' static' : '',
  241. $method,
  242. implode(',', array_map(
  243. static function (int $n): string { return sprintf('$x%d', $n); },
  244. array_keys(array_fill(0, $arguments, true))
  245. ))
  246. ));
  247. $this->fixer->fix($this->getTestFile(), $tokens);
  248. static::assertNull($this->lintSource($tokens->generateCode()));
  249. }
  250. public static function provideMethodWillNotCauseSyntaxErrorCases(): iterable
  251. {
  252. // List: https://www.php.net/manual/en/language.oop5.magic.php
  253. yield ['__construct'];
  254. yield ['__destruct'];
  255. yield ['__call', 2];
  256. yield ['__callStatic', 2, true];
  257. yield ['__get', 1];
  258. yield ['__set', 2];
  259. yield ['__isset', 1];
  260. yield ['__unset', 1];
  261. yield ['__sleep'];
  262. yield ['__wakeup'];
  263. yield ['__serialize'];
  264. yield ['__unserialize', 1];
  265. yield ['__toString'];
  266. yield ['__invoke'];
  267. yield ['__set_state', 1, true];
  268. yield ['__clone'];
  269. yield ['__debugInfo'];
  270. }
  271. }