PhpUnitConstructFixerTest.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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\Tests\Test\AbstractFixerTestCase;
  15. /**
  16. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  17. *
  18. * @internal
  19. *
  20. * @covers \PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer
  21. *
  22. * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer>
  23. *
  24. * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer
  25. */
  26. final class PhpUnitConstructFixerTest extends AbstractFixerTestCase
  27. {
  28. /**
  29. * @dataProvider provideFixCases
  30. */
  31. public function testFix(string $expected, ?string $input = null): void
  32. {
  33. $this->fixer->configure(['assertions' => [
  34. 'assertEquals',
  35. 'assertSame',
  36. 'assertNotEquals',
  37. 'assertNotSame',
  38. ]]);
  39. $this->doTest($expected, $input);
  40. foreach (['assertSame', 'assertEquals', 'assertNotEquals', 'assertNotSame'] as $method) {
  41. $this->fixer->configure(['assertions' => [$method]]);
  42. $this->doTest(
  43. $expected,
  44. null !== $input && str_contains($input, $method) ? $input : null
  45. );
  46. }
  47. }
  48. /**
  49. * @return iterable<int|string, array{0: string, 1?: string}>
  50. */
  51. public static function provideFixCases(): iterable
  52. {
  53. $cases = [
  54. ['$sth->assertSame(true, $foo);'],
  55. ['$this->assertSame($b, null);'],
  56. [
  57. '$this->assertNull(/*bar*/ $a);',
  58. '$this->assertSame(null /*foo*/, /*bar*/ $a);',
  59. ],
  60. [
  61. '$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException());',
  62. ],
  63. [
  64. '$this->assertSame(null /*comment*/ === $eventException ? $exception : $eventException, $event->getException());',
  65. ],
  66. [
  67. '
  68. $this->assertTrue(
  69. $a,
  70. "foo" . $bar
  71. );',
  72. '
  73. $this->assertSame(
  74. true,
  75. $a,
  76. "foo" . $bar
  77. );',
  78. ],
  79. [
  80. '
  81. $this->assertTrue(#
  82. #
  83. $a,#
  84. "foo" . $bar#
  85. );',
  86. '
  87. $this->assertSame(#
  88. true,#
  89. $a,#
  90. "foo" . $bar#
  91. );',
  92. ],
  93. [
  94. '$this->assertSame("a", $a); $this->assertTrue($b);',
  95. '$this->assertSame("a", $a); $this->assertSame(true, $b);',
  96. ],
  97. [
  98. '$this->assertSame(true || $a, $b); $this->assertTrue($c);',
  99. '$this->assertSame(true || $a, $b); $this->assertSame(true, $c);',
  100. ],
  101. [
  102. '$this->assertFalse($foo);',
  103. '$this->assertEquals(FALSE, $foo);',
  104. ],
  105. [
  106. '$this->assertTrue($foo);',
  107. '$this->assertEquals(TruE, $foo);',
  108. ],
  109. [
  110. '$this->assertNull($foo);',
  111. '$this->assertEquals(NULL, $foo);',
  112. ],
  113. ];
  114. array_walk(
  115. $cases,
  116. static function (array &$case): void {
  117. $case[0] = self::generateTest($case[0]);
  118. if (isset($case[1])) {
  119. $case[1] = self::generateTest($case[1]);
  120. }
  121. }
  122. );
  123. return array_merge(
  124. $cases,
  125. [
  126. 'not in a class' => ['<?php $this->assertEquals(NULL, $foo);'],
  127. 'not phpunit class' => ['<?php class Foo { public function testFoo(){ $this->assertEquals(NULL, $foo); }}'],
  128. 'multiple candidates in multiple classes ' => [
  129. '<?php
  130. class FooTest1 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertNull($foo); }}
  131. class FooTest2 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertNull($foo); }}
  132. class FooTest3 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertNull($foo); }}
  133. ',
  134. '<?php
  135. class FooTest1 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertEquals(NULL, $foo); }}
  136. class FooTest2 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertEquals(NULL, $foo); }}
  137. class FooTest3 extends PHPUnit_Framework_TestCase { public function testFoo(){ $this->assertEquals(NULL, $foo); }}
  138. ',
  139. ],
  140. ],
  141. self::generateCases('$this->assert%s%s($a); //%s %s', '$this->assert%s(%s, $a); //%s %s'),
  142. self::generateCases('$this->assert%s%s($a, "%s", "%s");', '$this->assert%s(%s, $a, "%s", "%s");'),
  143. self::generateCases('static::assert%s%s($a); //%s %s', 'static::assert%s(%s, $a); //%s %s'),
  144. self::generateCases('STATIC::assert%s%s($a); //%s %s', 'STATIC::assert%s(%s, $a); //%s %s'),
  145. self::generateCases('self::assert%s%s($a); //%s %s', 'self::assert%s(%s, $a); //%s %s')
  146. );
  147. }
  148. public function testInvalidConfig(): void
  149. {
  150. $this->expectException(InvalidFixerConfigurationException::class);
  151. $this->expectExceptionMessageMatches('/^\[php_unit_construct\] Invalid configuration: The option "assertions" .*\.$/');
  152. $this->fixer->configure(['assertions' => ['__TEST__']]); // @phpstan-ignore-line
  153. }
  154. /**
  155. * @dataProvider provideFix73Cases
  156. */
  157. public function testFix73(string $expected, string $input): void
  158. {
  159. $this->doTest($expected, $input);
  160. }
  161. /**
  162. * @return iterable<array{string, string}>
  163. */
  164. public static function provideFix73Cases(): iterable
  165. {
  166. yield [
  167. self::generateTest('$this->assertTrue($a, );'),
  168. self::generateTest('$this->assertSame(true, $a, );'),
  169. ];
  170. yield [
  171. self::generateTest('$this->assertTrue($a, $message , );'),
  172. self::generateTest('$this->assertSame(true, $a, $message , );'),
  173. ];
  174. }
  175. public function testEmptyAssertions(): void
  176. {
  177. $this->fixer->configure(['assertions' => []]);
  178. $this->doTest(self::generateTest('$this->assertSame(null, $a);'));
  179. }
  180. /**
  181. * @dataProvider provideFix81Cases
  182. *
  183. * @requires PHP 8.1
  184. */
  185. public function testFix81(string $expected, ?string $input = null): void
  186. {
  187. $this->doTest($expected, $input);
  188. }
  189. /**
  190. * @return iterable<array{string}>
  191. */
  192. public static function provideFix81Cases(): iterable
  193. {
  194. yield [
  195. self::generateTest('$this->assertEquals(...);'),
  196. ];
  197. }
  198. /**
  199. * @return list<array{string, string}>
  200. */
  201. private static function generateCases(string $expectedTemplate, string $inputTemplate): array
  202. {
  203. $functionTypes = ['Same' => true, 'NotSame' => false, 'Equals' => true, 'NotEquals' => false];
  204. $cases = [];
  205. foreach (['true', 'false', 'null'] as $type) {
  206. foreach ($functionTypes as $method => $positive) {
  207. $cases[] = [
  208. self::generateTest(\sprintf($expectedTemplate, $positive ? '' : 'Not', ucfirst($type), $method, $type)),
  209. self::generateTest(\sprintf($inputTemplate, $method, $type, $method, $type)),
  210. ];
  211. }
  212. }
  213. return $cases;
  214. }
  215. private static function generateTest(string $content): string
  216. {
  217. return "<?php final class FooTest extends \\PHPUnit_Framework_TestCase {\n public function testSomething() {\n ".$content."\n }\n}\n";
  218. }
  219. }