PhpUnitDedicateAssertFixerTest.php 20 KB

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