PhpUnitTestCaseStaticMethodCallsFixerTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  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\PhpUnit;
  13. use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException;
  14. use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer;
  15. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  16. use PhpCsFixer\Utils;
  17. use PHPUnit\Framework\TestCase;
  18. /**
  19. * @author Filippo Tessarotto <zoeslam@gmail.com>
  20. *
  21. * @internal
  22. *
  23. * @covers \PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer
  24. *
  25. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer>
  26. *
  27. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer
  28. */
  29. final class PhpUnitTestCaseStaticMethodCallsFixerTest extends AbstractFixerTestCase
  30. {
  31. public function testFixerContainsAllPhpunitStaticMethodsInItsList(): void
  32. {
  33. $assertionRefClass = new \ReflectionClass(TestCase::class);
  34. $updatedStaticMethodsList = $assertionRefClass->getMethods(\ReflectionMethod::IS_PUBLIC);
  35. $staticMethods = (new \ReflectionClass(PhpUnitTestCaseStaticMethodCallsFixer::class))->getConstant('STATIC_METHODS');
  36. $missingMethods = [];
  37. foreach ($updatedStaticMethodsList as $method) {
  38. if ($method->isStatic() && !isset($staticMethods[$method->name])) {
  39. $missingMethods[] = $method->name;
  40. }
  41. }
  42. self::assertSame([], $missingMethods, \sprintf(
  43. 'The following static methods from "%s" are missing from "%s::$staticMethods": %s',
  44. TestCase::class,
  45. PhpUnitTestCaseStaticMethodCallsFixer::class,
  46. // `Utils::naturalLanguageJoin` does not accept empty array, so let's use it only if there's an actual difference.
  47. [] === $missingMethods ? '' : Utils::naturalLanguageJoin($missingMethods)
  48. ));
  49. }
  50. public function testWrongConfigTypeForMethodsKey(): void
  51. {
  52. $this->expectException(InvalidFixerConfigurationException::class);
  53. $this->expectExceptionMessage('[php_unit_test_case_static_method_calls] Invalid configuration: The option "methods" with value array is expected to be of type "string[]", but one of the elements is of type "int".');
  54. $this->fixer->configure(['methods' => [123 => 1]]); // @phpstan-ignore-line
  55. }
  56. public function testWrongConfigTypeForMethodsValue(): void
  57. {
  58. $this->expectException(InvalidFixerConfigurationException::class);
  59. $this->expectExceptionMessage('[php_unit_test_case_static_method_calls] Invalid configuration: The option "methods" with value array is expected to be of type "string[]", but one of the elements is of type "int".');
  60. $this->fixer->configure(['methods' => ['assertSame' => 123]]); // @phpstan-ignore-line
  61. }
  62. /**
  63. * @param _AutogeneratedInputConfiguration $config
  64. *
  65. * @dataProvider provideFixCases
  66. */
  67. public function testFix(string $expected, ?string $input = null, array $config = []): void
  68. {
  69. $this->fixer->configure($config);
  70. $this->doTest($expected, $input);
  71. }
  72. public static function provideFixCases(): iterable
  73. {
  74. yield [
  75. <<<'EOF'
  76. <?php
  77. class MyTest extends \PHPUnit_Framework_TestCase
  78. {
  79. public function testBaseCase()
  80. {
  81. static::assertSame(1, 2);
  82. static::markTestIncomplete('foo');
  83. static::fail('foo');
  84. }
  85. }
  86. EOF,
  87. <<<'EOF'
  88. <?php
  89. class MyTest extends \PHPUnit_Framework_TestCase
  90. {
  91. public function testBaseCase()
  92. {
  93. $this->assertSame(1, 2);
  94. $this->markTestIncomplete('foo');
  95. $this->fail('foo');
  96. }
  97. }
  98. EOF,
  99. ];
  100. yield [
  101. <<<'EOF'
  102. <?php
  103. class MyTest extends \PHPUnit_Framework_TestCase
  104. {
  105. public function testMocks()
  106. {
  107. $mock = $this->createMock(MyInterface::class);
  108. $mock
  109. ->expects(static::once())
  110. ->method('run')
  111. ->with(
  112. static::identicalTo(1),
  113. static::stringContains('foo')
  114. )
  115. ->will(static::onConsecutiveCalls(
  116. static::returnSelf(),
  117. static::throwException(new \Exception())
  118. ))
  119. ;
  120. }
  121. }
  122. EOF,
  123. <<<'EOF'
  124. <?php
  125. class MyTest extends \PHPUnit_Framework_TestCase
  126. {
  127. public function testMocks()
  128. {
  129. $mock = $this->createMock(MyInterface::class);
  130. $mock
  131. ->expects($this->once())
  132. ->method('run')
  133. ->with(
  134. $this->identicalTo(1),
  135. $this->stringContains('foo')
  136. )
  137. ->will($this->onConsecutiveCalls(
  138. $this->returnSelf(),
  139. $this->throwException(new \Exception())
  140. ))
  141. ;
  142. }
  143. }
  144. EOF,
  145. ];
  146. yield [
  147. <<<'EOF'
  148. <?php
  149. class MyTest extends \PHPUnit_Framework_TestCase
  150. {
  151. public function testWeirdIndentation()
  152. {
  153. static
  154. // @TODO
  155. ::
  156. assertSame
  157. (1, 2);
  158. // $this->markTestIncomplete('foo');
  159. /*
  160. $this->fail('foo');
  161. */
  162. }
  163. }
  164. EOF,
  165. <<<'EOF'
  166. <?php
  167. class MyTest extends \PHPUnit_Framework_TestCase
  168. {
  169. public function testWeirdIndentation()
  170. {
  171. $this
  172. // @TODO
  173. ->
  174. assertSame
  175. (1, 2);
  176. // $this->markTestIncomplete('foo');
  177. /*
  178. $this->fail('foo');
  179. */
  180. }
  181. }
  182. EOF,
  183. ];
  184. yield [
  185. <<<'EOF'
  186. <?php
  187. class MyTest extends \PHPUnit_Framework_TestCase
  188. {
  189. public function testBaseCase()
  190. {
  191. $this->assertSame(1, 2);
  192. $this->markTestIncomplete('foo');
  193. $this->fail('foo');
  194. $lambda = function () {
  195. $this->assertSame(1, 23);
  196. self::assertSame(1, 23);
  197. static::assertSame(1, 23);
  198. };
  199. }
  200. }
  201. EOF,
  202. <<<'EOF'
  203. <?php
  204. class MyTest extends \PHPUnit_Framework_TestCase
  205. {
  206. public function testBaseCase()
  207. {
  208. $this->assertSame(1, 2);
  209. self::markTestIncomplete('foo');
  210. static::fail('foo');
  211. $lambda = function () {
  212. $this->assertSame(1, 23);
  213. self::assertSame(1, 23);
  214. static::assertSame(1, 23);
  215. };
  216. }
  217. }
  218. EOF,
  219. ['call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_THIS],
  220. ];
  221. yield [
  222. <<<'EOF'
  223. <?php
  224. class MyTest extends \PHPUnit_Framework_TestCase
  225. {
  226. public function testBaseCase()
  227. {
  228. self::assertSame(1, 2);
  229. self::markTestIncomplete('foo');
  230. self::fail('foo');
  231. }
  232. }
  233. EOF,
  234. <<<'EOF'
  235. <?php
  236. class MyTest extends \PHPUnit_Framework_TestCase
  237. {
  238. public function testBaseCase()
  239. {
  240. $this->assertSame(1, 2);
  241. self::markTestIncomplete('foo');
  242. static::fail('foo');
  243. }
  244. }
  245. EOF,
  246. ['call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_SELF],
  247. ];
  248. yield [
  249. <<<'EOF'
  250. <?php
  251. class MyTest extends \PHPUnit_Framework_TestCase
  252. {
  253. public function testBaseCase()
  254. {
  255. $this->assertSame(1, 2);
  256. $this->assertSame(1, 2);
  257. static::setUpBeforeClass();
  258. static::setUpBeforeClass();
  259. $otherTest->setUpBeforeClass();
  260. OtherTest::setUpBeforeClass();
  261. }
  262. }
  263. EOF,
  264. <<<'EOF'
  265. <?php
  266. class MyTest extends \PHPUnit_Framework_TestCase
  267. {
  268. public function testBaseCase()
  269. {
  270. static::assertSame(1, 2);
  271. $this->assertSame(1, 2);
  272. static::setUpBeforeClass();
  273. $this->setUpBeforeClass();
  274. $otherTest->setUpBeforeClass();
  275. OtherTest::setUpBeforeClass();
  276. }
  277. }
  278. EOF,
  279. [
  280. 'call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_THIS,
  281. 'methods' => ['setUpBeforeClass' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_STATIC],
  282. ],
  283. ];
  284. yield [
  285. <<<'EOF'
  286. <?php
  287. class MyTest extends \PHPUnit_Framework_TestCase
  288. {
  289. public static function foo()
  290. {
  291. $this->assertSame(1, 2);
  292. self::assertSame(1, 2);
  293. static::assertSame(1, 2);
  294. $lambda = function () {
  295. $this->assertSame(1, 2);
  296. self::assertSame(1, 2);
  297. static::assertSame(1, 2);
  298. };
  299. }
  300. public function bar()
  301. {
  302. $lambda = static function () {
  303. $this->assertSame(1, 2);
  304. self::assertSame(1, 2);
  305. static::assertSame(1, 2);
  306. };
  307. $myProphecy->setCount(0)->will(function () {
  308. $this->getCount()->willReturn(0);
  309. });
  310. }
  311. static public function baz()
  312. {
  313. $this->assertSame(1, 2);
  314. self::assertSame(1, 2);
  315. static::assertSame(1, 2);
  316. $lambda = function () {
  317. $this->assertSame(1, 2);
  318. self::assertSame(1, 2);
  319. static::assertSame(1, 2);
  320. };
  321. }
  322. static final protected function xyz()
  323. {
  324. static::assertSame(1, 2);
  325. }
  326. }
  327. EOF,
  328. null,
  329. [
  330. 'call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_THIS,
  331. ],
  332. ];
  333. yield [
  334. <<<'EOF'
  335. <?php
  336. class MyTest extends \PHPUnit_Framework_TestCase
  337. {
  338. public function foo()
  339. {
  340. $this->assertSame(1, 2);
  341. $this->assertSame(1, 2);
  342. $this->assertSame(1, 2);
  343. }
  344. public function bar()
  345. {
  346. $lambdaOne = static function () {
  347. $this->assertSame(1, 21);
  348. self::assertSame(1, 21);
  349. static::assertSame(1, 21);
  350. };
  351. $lambdaTwo = function () {
  352. $this->assertSame(1, 21);
  353. self::assertSame(1, 21);
  354. static::assertSame(1, 21);
  355. };
  356. }
  357. public function baz2()
  358. {
  359. $this->assertSame(1, 22);
  360. $this->assertSame(1, 22);
  361. $this->assertSame(1, 22);
  362. $this->assertSame(1, 23);
  363. }
  364. }
  365. EOF,
  366. <<<'EOF'
  367. <?php
  368. class MyTest extends \PHPUnit_Framework_TestCase
  369. {
  370. public function foo()
  371. {
  372. $this->assertSame(1, 2);
  373. self::assertSame(1, 2);
  374. static::assertSame(1, 2);
  375. }
  376. public function bar()
  377. {
  378. $lambdaOne = static function () {
  379. $this->assertSame(1, 21);
  380. self::assertSame(1, 21);
  381. static::assertSame(1, 21);
  382. };
  383. $lambdaTwo = function () {
  384. $this->assertSame(1, 21);
  385. self::assertSame(1, 21);
  386. static::assertSame(1, 21);
  387. };
  388. }
  389. public function baz2()
  390. {
  391. $this->assertSame(1, 22);
  392. self::assertSame(1, 22);
  393. static::assertSame(1, 22);
  394. STATIC::assertSame(1, 23);
  395. }
  396. }
  397. EOF,
  398. [
  399. 'call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_THIS,
  400. ],
  401. ];
  402. yield 'do not change class property and method signature' => [
  403. <<<'EOF'
  404. <?php
  405. class FooTest extends TestCase
  406. {
  407. public function foo()
  408. {
  409. $this->assertSame = 42;
  410. }
  411. public function assertSame($foo, $bar){}
  412. }
  413. EOF,
  414. ];
  415. yield 'do not change when only case is different' => [
  416. <<<'EOF'
  417. <?php
  418. class FooTest extends TestCase
  419. {
  420. public function foo()
  421. {
  422. STATIC::assertSame(1, 1);
  423. }
  424. }
  425. EOF,
  426. ];
  427. yield 'do not crash on abstract static function' => [
  428. <<<'EOF'
  429. <?php
  430. abstract class FooTest extends TestCase
  431. {
  432. abstract public static function dataProvider();
  433. }
  434. EOF,
  435. null,
  436. [
  437. 'call_type' => PhpUnitTestCaseStaticMethodCallsFixer::CALL_TYPE_THIS,
  438. ],
  439. ];
  440. yield 'handle $this with double colon following' => [
  441. '<?php
  442. class FooTest extends TestCase
  443. {
  444. public function testFoo()
  445. {
  446. static::assertTrue(true);
  447. }
  448. }',
  449. '<?php
  450. class FooTest extends TestCase
  451. {
  452. public function testFoo()
  453. {
  454. $this::assertTrue(true);
  455. }
  456. }',
  457. ];
  458. }
  459. public function testAnonymousClassFixing(): void
  460. {
  461. $this->doTest(
  462. '<?php
  463. class MyTest extends \PHPUnit_Framework_TestCase
  464. {
  465. public function testBaseCase()
  466. {
  467. static::assertSame(1, 2);
  468. $foo = new class() {
  469. public function assertSame($a, $b)
  470. {
  471. $this->assertSame(1, 2);
  472. }
  473. };
  474. }
  475. }',
  476. '<?php
  477. class MyTest extends \PHPUnit_Framework_TestCase
  478. {
  479. public function testBaseCase()
  480. {
  481. $this->assertSame(1, 2);
  482. $foo = new class() {
  483. public function assertSame($a, $b)
  484. {
  485. $this->assertSame(1, 2);
  486. }
  487. };
  488. }
  489. }'
  490. );
  491. }
  492. /**
  493. * @dataProvider provideFix81Cases
  494. *
  495. * @requires PHP 8.1
  496. */
  497. public function testFix81(string $expected, ?string $input = null): void
  498. {
  499. $this->doTest($expected, $input);
  500. }
  501. /**
  502. * @return iterable<array{string}>
  503. */
  504. public static function provideFix81Cases(): iterable
  505. {
  506. yield [
  507. '<?php
  508. class FooTest extends TestCase
  509. {
  510. public function testFoo()
  511. {
  512. $a = $this::assertTrue(...);
  513. }
  514. }
  515. ',
  516. ];
  517. }
  518. }