PhpUnitDedicateAssertFixerTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  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\PhpUnitTargetVersion;
  15. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  16. /**
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer
  20. *
  21. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer>
  22. *
  23. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer
  24. */
  25. final class PhpUnitDedicateAssertFixerTest extends AbstractFixerTestCase
  26. {
  27. /**
  28. * @param _AutogeneratedInputConfiguration $config
  29. *
  30. * @dataProvider provideFixCases
  31. */
  32. public function testFix(string $expected, ?string $input = null, array $config = []): void
  33. {
  34. $this->fixer->configure($config);
  35. $this->doTest($expected, $input);
  36. }
  37. public static function provideFixCases(): iterable
  38. {
  39. yield [
  40. self::generateTest('
  41. $this->assertNan($a);
  42. $this->assertNan($a);
  43. $this->assertTrue(test\is_nan($a));
  44. $this->assertTrue(test\a\is_nan($a));
  45. '),
  46. self::generateTest('
  47. $this->assertTrue(is_nan($a));
  48. $this->assertTrue(\is_nan($a));
  49. $this->assertTrue(test\is_nan($a));
  50. $this->assertTrue(test\a\is_nan($a));
  51. '),
  52. ];
  53. yield [
  54. self::generateTest('
  55. $this->assertFileExists($a);
  56. $this->assertFileNotExists($a);
  57. $this->assertFileExists($a);
  58. $this->assertFileNotExists($a);
  59. '),
  60. self::generateTest('
  61. $this->assertTrue(file_exists($a));
  62. $this->assertFalse(file_exists($a));
  63. $this->assertTrue(\file_exists($a));
  64. $this->assertFalse(\file_exists($a));
  65. '),
  66. ];
  67. yield [
  68. self::generateTest('
  69. $this->assertNull($a);
  70. $this->assertNotNull($a);
  71. $this->assertNull($a);
  72. $this->assertNotNull($a, "my message");
  73. '),
  74. self::generateTest('
  75. $this->assertTrue(is_null($a));
  76. $this->assertFalse(is_null($a));
  77. $this->assertTrue(\is_null($a));
  78. $this->assertFalse(\is_null($a), "my message");
  79. '),
  80. ];
  81. yield [
  82. self::generateTest('
  83. $this->assertEmpty($a);
  84. $this->assertNotEmpty($a);
  85. '),
  86. self::generateTest('
  87. $this->assertTrue(empty($a));
  88. $this->ASSERTFALSE(empty($a));
  89. '),
  90. ];
  91. yield [
  92. self::generateTest('
  93. $this->assertInfinite($a);
  94. $this->assertFinite($a, "my message");
  95. $this->assertInfinite($a);
  96. $this->assertFinite($a, b"my message");
  97. '),
  98. self::generateTest('
  99. $this->assertTrue(is_infinite($a));
  100. $this->assertFalse(is_infinite($a), "my message");
  101. $this->assertTrue(\is_infinite($a));
  102. $this->assertFalse(\is_infinite($a), b"my message");
  103. '),
  104. ];
  105. yield [
  106. self::generateTest('
  107. $this->assertArrayHasKey("test", $a);
  108. $this->assertArrayNotHasKey($b, $a, $c);
  109. '),
  110. self::generateTest('
  111. $this->assertTrue(\array_key_exists("test", $a));
  112. $this->ASSERTFALSE(array_key_exists($b, $a), $c);
  113. '),
  114. ];
  115. yield [
  116. self::generateTest('
  117. $this->assertTrue(is_dir($a));
  118. $this->assertTrue(is_writable($a));
  119. $this->assertTrue(is_readable($a));
  120. '),
  121. null,
  122. ['target' => PhpUnitTargetVersion::VERSION_5_0],
  123. ];
  124. yield [
  125. self::generateTest('
  126. $this->assertTrue(is_dir($a));
  127. $this->assertTrue(is_writable($a));
  128. $this->assertTrue(is_readable($a));
  129. '),
  130. null,
  131. ['target' => PhpUnitTargetVersion::VERSION_3_0],
  132. ];
  133. yield [
  134. self::generateTest('
  135. $this->assertDirectoryNotExists($a);
  136. $this->assertNotIsWritable($a);
  137. $this->assertNotIsReadable($a);
  138. '),
  139. self::generateTest('
  140. $this->assertFalse(is_dir($a));
  141. $this->assertFalse(is_writable($a));
  142. $this->assertFalse(is_readable($a));
  143. '),
  144. ['target' => PhpUnitTargetVersion::VERSION_5_6],
  145. ];
  146. yield [
  147. self::generateTest('
  148. $this->assertDirectoryExists($a);
  149. $this->assertIsWritable($a);
  150. $this->assertIsReadable($a);
  151. '),
  152. self::generateTest('
  153. $this->assertTrue(is_dir($a));
  154. $this->assertTrue(is_writable($a));
  155. $this->assertTrue(is_readable($a));
  156. '),
  157. ['target' => PhpUnitTargetVersion::VERSION_NEWEST],
  158. ];
  159. foreach (['array', 'bool', 'callable', 'double', 'float', 'int', 'integer', 'long', 'numeric', 'object', 'real', 'scalar', 'string'] as $type) {
  160. yield [
  161. self::generateTest(\sprintf('$this->assertInternalType(\'%s\', $a);', $type)),
  162. self::generateTest(\sprintf('$this->assertTrue(is_%s($a));', $type)),
  163. ];
  164. yield [
  165. self::generateTest(\sprintf('$this->assertNotInternalType(\'%s\', $a);', $type)),
  166. self::generateTest(\sprintf('$this->assertFalse(is_%s($a));', $type)),
  167. ];
  168. }
  169. yield [
  170. self::generateTest('$this->assertInternalType(\'float\', $a, "my message");'),
  171. self::generateTest('$this->assertTrue(is_float( $a), "my message");'),
  172. ];
  173. yield [
  174. self::generateTest('$this->assertInternalType(\'float\', $a);'),
  175. self::generateTest('$this->assertTrue(\IS_FLOAT($a));'),
  176. ];
  177. yield [
  178. self::generateTest('$this->assertInternalType(#
  179. \'float\'#
  180. , #
  181. $a#
  182. #
  183. )#
  184. ;'),
  185. self::generateTest('$this->assertTrue(#
  186. \IS_FLOAT#
  187. (#
  188. $a#
  189. )#
  190. )#
  191. ;'),
  192. ];
  193. yield [
  194. self::generateTest('static::assertInternalType(\'float\', $a);'),
  195. self::generateTest('static::assertTrue(is_float( $a));'),
  196. ];
  197. yield [
  198. self::generateTest('self::assertInternalType(\'float\', $a);'),
  199. self::generateTest('self::assertTrue(is_float( $a));'),
  200. ];
  201. yield [
  202. self::generateTest('static::assertNull($a);'),
  203. self::generateTest('static::assertTrue(is_null($a));'),
  204. ];
  205. yield [
  206. self::generateTest('self::assertNull($a);'),
  207. self::generateTest('self::assertTrue(is_null($a));'),
  208. ];
  209. yield [
  210. self::generateTest('SELF::assertNull($a);'),
  211. self::generateTest('SELF::assertTrue(is_null($a));'),
  212. ];
  213. yield [
  214. self::generateTest('self::assertStringContainsString($needle, $haystack);'),
  215. self::generateTest('self::assertTrue(str_contains($haystack, $needle));'),
  216. ['target' => PhpUnitTargetVersion::VERSION_NEWEST],
  217. ];
  218. yield [
  219. self::generateTest('self::assertStringNotContainsString($needle, $a[$haystack.""](123)[foo()]);'),
  220. self::generateTest('self::assertFalse(str_contains($a[$haystack.""](123)[foo()], $needle));'),
  221. ['target' => PhpUnitTargetVersion::VERSION_NEWEST],
  222. ];
  223. yield [
  224. self::generateTest('self::assertStringStartsWith($needle, $haystack);'),
  225. self::generateTest('self::assertTrue(str_starts_with($haystack, $needle));'),
  226. ];
  227. yield [
  228. self::generateTest('self::assertStringStartsNotWith($needle, $haystack);'),
  229. self::generateTest('self::assertFalse(str_starts_with($haystack, $needle));'),
  230. ];
  231. yield [
  232. self::generateTest('self::assertStringStartsNotWith( #3
  233. $needle#4
  234. , #1
  235. $haystack#2
  236. );'),
  237. self::generateTest('self::assertFalse(str_starts_with( #1
  238. $haystack#2
  239. ,#3
  240. $needle#4
  241. ));'),
  242. ];
  243. yield [
  244. self::generateTest('self::assertStringEndsWith($needle, $haystack);'),
  245. self::generateTest('self::assertTrue(str_ends_with($haystack, $needle));'),
  246. ];
  247. yield [
  248. self::generateTest('self::assertStringEndsNotWith($needle, $haystack);'),
  249. self::generateTest('self::assertFalse(str_ends_with($haystack, $needle));'),
  250. ];
  251. yield '$a instanceof class' => [
  252. self::generateTest('
  253. $this->assertInstanceOf(SomeClass::class, $x);
  254. $this->assertInstanceOf(SomeClass::class, $y, $message);
  255. '),
  256. self::generateTest('
  257. $this->assertTrue($x instanceof SomeClass);
  258. $this->assertTrue($y instanceof SomeClass, $message);
  259. '),
  260. ];
  261. yield '$a instanceof class\a\b' => [
  262. self::generateTest('
  263. $this->assertInstanceOf(\PhpCsFixer\Tests\Fixtures\Test\AbstractFixerTest\SimpleFixer::class, $ii);
  264. '),
  265. self::generateTest('
  266. $this->assertTrue($ii instanceof \PhpCsFixer\Tests\Fixtures\Test\AbstractFixerTest\SimpleFixer);
  267. '),
  268. ];
  269. yield '$a instanceof $b' => [
  270. self::generateTest('
  271. $this->assertInstanceOf($tty, $abc/* 1 *//* 2 */);
  272. $this->assertInstanceOf($oo, $def, $message);
  273. '),
  274. self::generateTest('
  275. $this->assertTrue($abc instanceof /* 1 */$tty /* 2 */);
  276. $this->assertTrue($def instanceof $oo, $message);
  277. '),
  278. ];
  279. yield 'do not fix instance of' => [
  280. self::generateTest('
  281. $this->assertTrue($gg instanceof $ijl . "X", $something);
  282. $this->assertTrue($ff instanceof $klh . $b(1,2,$message), $noMsg);
  283. '),
  284. ];
  285. yield '!$a instanceof class' => [
  286. self::generateTest('
  287. $this->assertNotInstanceOf(SomeClass::class, $x);
  288. $this->assertNotInstanceOf(SomeClass::class, $y, $message);
  289. '),
  290. self::generateTest('
  291. $this->assertTrue(!$x instanceof SomeClass);
  292. $this->assertTrue(!$y instanceof SomeClass, $message);
  293. '),
  294. ];
  295. }
  296. /**
  297. * @dataProvider provideNotFixCases
  298. */
  299. public function testNotFix(string $expected): void
  300. {
  301. $this->fixer->configure(['target' => PhpUnitTargetVersion::VERSION_NEWEST]);
  302. $this->doTest($expected);
  303. }
  304. /**
  305. * @return iterable<int|string, array{string}>
  306. */
  307. public static function provideNotFixCases(): iterable
  308. {
  309. yield 'not a method call' => [
  310. self::generateTest('echo $this->assertTrue;'),
  311. ];
  312. yield 'wrong argument count 1' => [
  313. self::generateTest('static::assertTrue(is_null($a, $b));'),
  314. ];
  315. yield 'wrong argument count 2' => [
  316. self::generateTest('static::assertTrue(is_int($a, $b));'),
  317. ];
  318. yield [
  319. self::generateTest('
  320. $this->assertTrue(is_null);
  321. $this->assertTrue(is_int($a) && $b);
  322. $this->assertFalse(is_nan($a));
  323. $this->assertTrue(is_int($a) || \is_bool($b));
  324. $this->assertTrue($a&&is_int($a));
  325. static::assertTrue(is_null);
  326. self::assertTrue(is_null);
  327. '),
  328. ];
  329. yield 'not in class' => [
  330. '<?php self::assertTrue(is_null($a));',
  331. ];
  332. // Do not replace is_resource() by assertIsResource().
  333. // is_resource() also checks if the resource is open or closed,
  334. // while assertIsResource() does not.
  335. yield 'Do not replace is_resource' => [
  336. self::generateTest('self::assertTrue(is_resource($resource));'),
  337. ];
  338. }
  339. public function testInvalidConfig(): void
  340. {
  341. $this->expectException(InvalidFixerConfigurationException::class);
  342. $this->expectExceptionMessageMatches('/^\[php_unit_dedicate_assert\] Invalid configuration: The option "target" .*\.$/');
  343. $this->fixer->configure(['target' => '_unknown_']); // @phpstan-ignore-line
  344. }
  345. /**
  346. * @dataProvider provideTestAssertCountCases
  347. */
  348. public function testAssertCount(string $expected, ?string $input = null): void
  349. {
  350. if (null === $input) {
  351. $expected = \sprintf($expected, 'count');
  352. } else {
  353. $input = \sprintf($input, 'count');
  354. }
  355. $this->doTest($expected, $input);
  356. }
  357. /**
  358. * @dataProvider provideTestAssertCountCases
  359. */
  360. public function testAssertCountFromSizeOf(string $expected, ?string $input = null): void
  361. {
  362. if (null === $input) {
  363. $expected = \sprintf($expected, 'sizeof');
  364. } else {
  365. $input = \sprintf($input, 'sizeof');
  366. }
  367. $this->doTest($expected, $input);
  368. }
  369. /**
  370. * @return iterable<int|string, array{0: string, 1?: string}>
  371. */
  372. public static function provideTestAssertCountCases(): iterable
  373. {
  374. // positive fixing
  375. yield 'assert same' => [
  376. self::generateTest('$this->assertCount(1, $a);'),
  377. self::generateTest('$this->assertSame(1, %s($a));'),
  378. ];
  379. yield 'assert equals' => [
  380. self::generateTest('$this->assertCount(2, $b);'),
  381. self::generateTest('$this->assertEquals(2, %s($b));'),
  382. ];
  383. // negative fixing
  384. yield 'assert not same' => [
  385. self::generateTest('$this->assertNotCount(11, $c);'),
  386. self::generateTest('$this->assertNotSame(11, %s($c));'),
  387. ];
  388. yield 'assert not equals' => [
  389. self::generateTest('$this->assertNotCount(122, $d);'),
  390. self::generateTest('$this->assertNotEquals(122, %s($d));'),
  391. ];
  392. // other cases
  393. yield 'assert same with namespace' => [
  394. self::generateTest('$this->assertCount(1, $a);'),
  395. self::generateTest('$this->assertSame(1, \%s($a));'),
  396. ];
  397. yield 'no spacing' => [
  398. self::generateTest('$this->assertCount(1,$a);'),
  399. self::generateTest('$this->assertSame(1,%s($a));'),
  400. ];
  401. yield 'lot of spacing' => [
  402. self::generateTest('$this->assertCount(
  403. 1
  404. ,
  405. '.'
  406. '.'
  407. $a
  408. '.'
  409. )
  410. ;'),
  411. self::generateTest('$this->assertSame(
  412. 1
  413. ,
  414. %s
  415. (
  416. $a
  417. )
  418. )
  419. ;'),
  420. ];
  421. yield 'lot of fix cases' => [
  422. self::generateTest('
  423. $this->assertCount(1, $a);
  424. $this->assertCount(2, $a);
  425. $this->assertCount(3, $a);
  426. $this->assertNotCount(4, $a);
  427. $this->assertCount(5, $a, "abc");
  428. $this->assertCount(6, $a, "def");
  429. '),
  430. self::generateTest('
  431. $this->assertSame(1, %1$s($a));
  432. $this->assertSame(2, %1$s($a));
  433. $this->assertEquals(3, %1$s($a));
  434. $this->assertNotSame(4, %1$s($a));
  435. $this->assertEquals(5, %1$s($a), "abc");
  436. $this->assertSame(6, \%1$s($a), "def");
  437. '),
  438. ];
  439. yield 'comment handling' => [
  440. self::generateTest('$this->assertCount(# 0
  441. 1# 1
  442. ,# 2
  443. # 3
  444. # 4
  445. $a# 5
  446. # 6
  447. )# 7
  448. ;# 8'),
  449. self::generateTest('$this->assertSame(# 0
  450. 1# 1
  451. ,# 2
  452. %s# 3
  453. (# 4
  454. $a# 5
  455. )# 6
  456. )# 7
  457. ;# 8'),
  458. ];
  459. yield [
  460. self::generateTest('$this->assertCount($b, $a);'),
  461. self::generateTest('$this->assertSame($b, %s($a));'),
  462. ];
  463. yield 'do not fix 1' => [
  464. self::generateTest('$this->assertSame($b[1], %s($a));'),
  465. ];
  466. yield 'do not fix 2' => [
  467. self::generateTest('$this->assertSame(b(), %s($a));'),
  468. ];
  469. yield 'do not fix 3' => [
  470. self::generateTest('$this->assertSame(1.0, %s($a));'),
  471. ];
  472. yield 'do not fix 4' => [
  473. self::generateTest('$this->assertSame(1);'),
  474. ];
  475. yield 'do not fix 5' => [
  476. self::generateTest('$this->assertSame(1, "%s");'),
  477. ];
  478. yield 'do not fix 6' => [
  479. self::generateTest('$this->test(); // $this->assertSame($b, %s($a));'),
  480. ];
  481. yield 'do not fix 7' => [
  482. self::generateTest('$this->assertSame(2, count($array) - 1);'),
  483. ];
  484. yield 'do not fix 8' => [
  485. self::generateTest('
  486. Foo::assertSame(1, sizeof($a));
  487. $this->assertSame(1, sizeof2(2));
  488. $this->assertSame(1, sizeof::foo);
  489. '),
  490. ];
  491. }
  492. /**
  493. * @dataProvider provideTestAssertCountCasingCases
  494. */
  495. public function testAssertCountCasing(string $expected, string $input): void
  496. {
  497. $expected = \sprintf($expected, 'count');
  498. $input = \sprintf($input, 'COUNT');
  499. $this->doTest($expected, $input);
  500. }
  501. /**
  502. * @dataProvider provideTestAssertCountCasingCases
  503. */
  504. public function testAssertCountFromSizeOfCasing(string $expected, string $input): void
  505. {
  506. $expected = \sprintf($expected, 'sizeof');
  507. $input = \sprintf($input, 'SIZEOF');
  508. $this->doTest($expected, $input);
  509. }
  510. /**
  511. * @return iterable<array{string, string}>
  512. */
  513. public static function provideTestAssertCountCasingCases(): iterable
  514. {
  515. yield [
  516. self::generateTest('$this->assertCount(1, $a);'),
  517. self::generateTest('$this->assertSame(1, %s($a));'),
  518. ];
  519. yield [
  520. self::generateTest('$this->assertCount(1, $a);'),
  521. self::generateTest('$this->assertSame(1, \%s($a));'),
  522. ];
  523. }
  524. /**
  525. * @dataProvider provideFix73Cases
  526. */
  527. public function testFix73(string $expected, string $input): void
  528. {
  529. $this->fixer->configure(['target' => PhpUnitTargetVersion::VERSION_NEWEST]);
  530. $this->doTest($expected, $input);
  531. }
  532. /**
  533. * @return iterable<int|string, array{string, string}>
  534. */
  535. public static function provideFix73Cases(): iterable
  536. {
  537. yield [
  538. self::generateTest('$this->assertNan($a, );'),
  539. self::generateTest('$this->assertTrue(is_nan($a), );'),
  540. ];
  541. yield [
  542. self::generateTest('$this->assertNan($a);'),
  543. self::generateTest('$this->assertTrue(is_nan($a, ));'),
  544. ];
  545. yield [
  546. self::generateTest('$this->assertNan($a, );'),
  547. self::generateTest('$this->assertTrue(is_nan($a, ), );'),
  548. ];
  549. yield [
  550. self::generateTest('$this->assertInternalType(\'array\', $a,);'),
  551. self::generateTest('$this->assertTrue(is_array($a,),);'),
  552. ];
  553. yield [
  554. self::generateTest('$this->assertNan($b);'),
  555. self::generateTest('$this->assertTrue(\is_nan($b,));'),
  556. ];
  557. yield [
  558. self::generateTest('$this->assertFileExists($f, \'message\',);'),
  559. self::generateTest('$this->assertTrue(file_exists($f,), \'message\',);'),
  560. ];
  561. yield [
  562. self::generateTest('$this->assertNan($y , );'),
  563. self::generateTest('$this->assertTrue(is_nan($y) , );'),
  564. ];
  565. yield 'str_starts_with with trailing ","' => [
  566. self::generateTest('self::assertStringStartsWith($needle, $haystack);'),
  567. self::generateTest('self::assertTrue(str_starts_with($haystack, $needle,));'),
  568. ];
  569. }
  570. /**
  571. * @dataProvider provideFix81Cases
  572. *
  573. * @requires PHP 8.1
  574. */
  575. public function testFix81(string $expected, ?string $input = null): void
  576. {
  577. $this->fixer->configure(['target' => PhpUnitTargetVersion::VERSION_NEWEST]);
  578. $this->doTest($expected, $input);
  579. }
  580. /**
  581. * @return iterable<array{string}>
  582. */
  583. public static function provideFix81Cases(): iterable
  584. {
  585. yield [
  586. self::generateTest('$a = $this->assertTrue(...);'),
  587. ];
  588. }
  589. private static function generateTest(string $content): string
  590. {
  591. return "<?php final class FooTest extends \\PHPUnit_Framework_TestCase {\n public function testSomething() {\n ".$content."\n }\n}\n";
  592. }
  593. }