PhpUnitNoExpectationAnnotationFixerTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  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\Fixer\PhpUnit\PhpUnitTargetVersion;
  14. use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  15. use PhpCsFixer\WhitespacesFixerConfig;
  16. /**
  17. * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
  18. *
  19. * @internal
  20. *
  21. * @covers \PhpCsFixer\Fixer\PhpUnit\PhpUnitNoExpectationAnnotationFixer
  22. */
  23. final class PhpUnitNoExpectationAnnotationFixerTest extends AbstractFixerTestCase
  24. {
  25. /**
  26. * @param array<string, mixed> $config
  27. *
  28. * @dataProvider provideFixCases
  29. */
  30. public function testFix(string $expected, ?string $input = null, array $config = []): void
  31. {
  32. $this->fixer->configure($config);
  33. $this->doTest($expected, $input);
  34. }
  35. public static function provideFixCases(): iterable
  36. {
  37. yield 'empty exception message' => [
  38. '<?php
  39. final class MyTest extends \PHPUnit_Framework_TestCase
  40. {
  41. /**
  42. */
  43. public function testFnc()
  44. {
  45. $this->setExpectedException(\FooException::class, \'\');
  46. aaa();
  47. }
  48. }',
  49. '<?php
  50. final class MyTest extends \PHPUnit_Framework_TestCase
  51. {
  52. /**
  53. * @expectedException FooException
  54. * @expectedExceptionMessage
  55. */
  56. public function testFnc()
  57. {
  58. aaa();
  59. }
  60. }',
  61. ];
  62. yield 'expecting exception' => [
  63. '<?php
  64. final class MyTest extends \PHPUnit_Framework_TestCase
  65. {
  66. /**
  67. */
  68. public function testFnc()
  69. {
  70. $this->setExpectedException(\FooException::class);
  71. aaa();
  72. }
  73. }',
  74. '<?php
  75. final class MyTest extends \PHPUnit_Framework_TestCase
  76. {
  77. /**
  78. * @expectedException FooException
  79. */
  80. public function testFnc()
  81. {
  82. aaa();
  83. }
  84. }',
  85. ];
  86. yield 'expecting rooted exception' => [
  87. '<?php
  88. final class MyTest extends \PHPUnit_Framework_TestCase
  89. {
  90. /**
  91. */
  92. public function testFnc()
  93. {
  94. $this->setExpectedException(\FooException::class);
  95. aaa();
  96. }
  97. }',
  98. '<?php
  99. final class MyTest extends \PHPUnit_Framework_TestCase
  100. {
  101. /**
  102. * @expectedException \FooException
  103. */
  104. public function testFnc()
  105. {
  106. aaa();
  107. }
  108. }',
  109. ];
  110. yield 'expecting exception with msg' => [
  111. '<?php
  112. final class MyTest extends \PHPUnit_Framework_TestCase
  113. {
  114. /**
  115. */
  116. public function testFnc()
  117. {
  118. $this->setExpectedException(\FooException::class, \'foo@bar\');
  119. aaa();
  120. }
  121. }',
  122. '<?php
  123. final class MyTest extends \PHPUnit_Framework_TestCase
  124. {
  125. /**
  126. * @expectedException FooException
  127. * @expectedExceptionMessage foo@bar
  128. */
  129. public function testFnc()
  130. {
  131. aaa();
  132. }
  133. }',
  134. ];
  135. yield 'expecting exception with code' => [
  136. '<?php
  137. final class MyTest extends \PHPUnit_Framework_TestCase
  138. {
  139. /**
  140. */
  141. public function testFnc()
  142. {
  143. $this->setExpectedException(\FooException::class, null, 123);
  144. aaa();
  145. }
  146. }',
  147. '<?php
  148. final class MyTest extends \PHPUnit_Framework_TestCase
  149. {
  150. /**
  151. * @expectedException FooException
  152. * @expectedExceptionCode 123
  153. */
  154. public function testFnc()
  155. {
  156. aaa();
  157. }
  158. }',
  159. ];
  160. yield 'expecting exception with msg and code' => [
  161. '<?php
  162. final class MyTest extends \PHPUnit_Framework_TestCase
  163. {
  164. /**
  165. */
  166. public function testFnc()
  167. {
  168. $this->setExpectedException(\FooException::class, \'foo\', 123);
  169. aaa();
  170. }
  171. }',
  172. '<?php
  173. final class MyTest extends \PHPUnit_Framework_TestCase
  174. {
  175. /**
  176. * @expectedException FooException
  177. * @expectedExceptionMessage foo
  178. * @expectedExceptionCode 123
  179. */
  180. public function testFnc()
  181. {
  182. aaa();
  183. }
  184. }',
  185. ];
  186. yield 'expecting exception with msg regex [but too low target]' => [
  187. '<?php
  188. final class MyTest extends \PHPUnit_Framework_TestCase
  189. {
  190. /**
  191. * @expectedException FooException
  192. * @expectedExceptionMessageRegExp /foo.*$/
  193. */
  194. public function testFnc()
  195. {
  196. aaa();
  197. }
  198. }',
  199. null,
  200. ['target' => PhpUnitTargetVersion::VERSION_3_2],
  201. ];
  202. yield 'expecting exception with msg regex' => [
  203. '<?php
  204. final class MyTest extends \PHPUnit_Framework_TestCase
  205. {
  206. /**
  207. */
  208. public function testFnc()
  209. {
  210. $this->setExpectedExceptionRegExp(\FooException::class, \'/foo.*$/\');
  211. aaa();
  212. }
  213. }',
  214. '<?php
  215. final class MyTest extends \PHPUnit_Framework_TestCase
  216. {
  217. /**
  218. * @expectedException FooException
  219. * @expectedExceptionMessageRegExp /foo.*$/
  220. */
  221. public function testFnc()
  222. {
  223. aaa();
  224. }
  225. }',
  226. ['target' => PhpUnitTargetVersion::VERSION_4_3],
  227. ];
  228. yield 'use_class_const=false' => [
  229. '<?php
  230. final class MyTest extends \PHPUnit_Framework_TestCase
  231. {
  232. /**
  233. */
  234. public function testFnc()
  235. {
  236. $this->setExpectedException(\'FooException\');
  237. aaa();
  238. }
  239. }',
  240. '<?php
  241. final class MyTest extends \PHPUnit_Framework_TestCase
  242. {
  243. /**
  244. * @expectedException FooException
  245. */
  246. public function testFnc()
  247. {
  248. aaa();
  249. }
  250. }',
  251. ['use_class_const' => false],
  252. ];
  253. yield 'keep rest of docblock' => [
  254. '<?php
  255. final class MyTest extends \PHPUnit_Framework_TestCase
  256. {
  257. /**
  258. * Summary.
  259. *
  260. * @param int $param
  261. * @return void
  262. */
  263. public function testFnc($param)
  264. {
  265. $this->setExpectedException(\FooException::class);
  266. aaa();
  267. }
  268. }',
  269. '<?php
  270. final class MyTest extends \PHPUnit_Framework_TestCase
  271. {
  272. /**
  273. * Summary.
  274. *
  275. * @param int $param
  276. * @expectedException FooException
  277. * @return void
  278. */
  279. public function testFnc($param)
  280. {
  281. aaa();
  282. }
  283. }',
  284. ];
  285. yield 'fix method without visibility' => [
  286. '<?php
  287. final class MyTest extends \PHPUnit_Framework_TestCase
  288. {
  289. /**
  290. */
  291. function testFnc($param)
  292. {
  293. $this->setExpectedException(\FooException::class);
  294. aaa();
  295. }
  296. }',
  297. '<?php
  298. final class MyTest extends \PHPUnit_Framework_TestCase
  299. {
  300. /**
  301. * @expectedException FooException
  302. */
  303. function testFnc($param)
  304. {
  305. aaa();
  306. }
  307. }',
  308. ];
  309. yield 'fix final method' => [
  310. '<?php
  311. final class MyTest extends \PHPUnit_Framework_TestCase
  312. {
  313. /**
  314. */
  315. final function testFnc($param)
  316. {
  317. $this->setExpectedException(\FooException::class);
  318. aaa();
  319. }
  320. }',
  321. '<?php
  322. final class MyTest extends \PHPUnit_Framework_TestCase
  323. {
  324. /**
  325. * @expectedException FooException
  326. */
  327. final function testFnc($param)
  328. {
  329. aaa();
  330. }
  331. }',
  332. ];
  333. yield 'ignore when no docblock' => [
  334. '<?php
  335. final class MyTest extends \PHPUnit_Framework_TestCase
  336. {
  337. final function testFoo($param)
  338. {
  339. aaa();
  340. }
  341. /**
  342. */
  343. final function testFnc($param)
  344. {
  345. $this->setExpectedException(\FooException::class);
  346. aaa();
  347. }
  348. }',
  349. '<?php
  350. final class MyTest extends \PHPUnit_Framework_TestCase
  351. {
  352. final function testFoo($param)
  353. {
  354. aaa();
  355. }
  356. /**
  357. * @expectedException FooException
  358. */
  359. final function testFnc($param)
  360. {
  361. aaa();
  362. }
  363. }',
  364. ];
  365. yield 'valid docblock but for property, not method' => [
  366. '<?php
  367. final class MyTest extends \PHPUnit_Framework_TestCase
  368. {
  369. /**
  370. * @expectedException FooException
  371. * @expectedExceptionCode 123
  372. */
  373. public $foo;
  374. public function bar()
  375. {
  376. /**
  377. * @expectedException FooException
  378. * @expectedExceptionCode 123
  379. */
  380. $baz = 1;
  381. /**
  382. * @expectedException FooException
  383. * @expectedExceptionCode 123
  384. */
  385. while (false) {}
  386. }
  387. }',
  388. ];
  389. yield 'respect \' and " in expected msg' => [
  390. '<?php
  391. final class MyTest extends \PHPUnit_Framework_TestCase
  392. {
  393. /**
  394. * Summary.
  395. *
  396. */
  397. public function testFnc($param)
  398. {
  399. $this->setExpectedException(\FooException::class, \'Foo \\\' bar " baz\');
  400. aaa();
  401. }
  402. }',
  403. '<?php
  404. final class MyTest extends \PHPUnit_Framework_TestCase
  405. {
  406. /**
  407. * Summary.
  408. *
  409. * @expectedException FooException
  410. * @expectedExceptionMessage Foo \' bar " baz
  411. */
  412. public function testFnc($param)
  413. {
  414. aaa();
  415. }
  416. }',
  417. ];
  418. yield 'special \\ handling' => [
  419. <<<'EOT'
  420. <?php
  421. final class MyTest extends \PHPUnit_Framework_TestCase
  422. {
  423. /**
  424. */
  425. public function testElementNonExistentOne()
  426. {
  427. $this->setExpectedException(\Cake\View\Exception\MissingElementException::class, 'A backslash at the end \\');
  428. $this->View->element('non_existent_element');
  429. }
  430. /**
  431. */
  432. public function testElementNonExistentTwo()
  433. {
  434. $this->setExpectedExceptionRegExp(\Cake\View\Exception\MissingElementException::class, '#^Element file "Element[\\\\/]non_existent_element\\.ctp" is missing\\.$#');
  435. $this->View->element('non_existent_element');
  436. }
  437. }
  438. EOT
  439. ,
  440. <<<'EOT'
  441. <?php
  442. final class MyTest extends \PHPUnit_Framework_TestCase
  443. {
  444. /**
  445. * @expectedException \Cake\View\Exception\MissingElementException
  446. * @expectedExceptionMessage A backslash at the end \
  447. */
  448. public function testElementNonExistentOne()
  449. {
  450. $this->View->element('non_existent_element');
  451. }
  452. /**
  453. * @expectedException \Cake\View\Exception\MissingElementException
  454. * @expectedExceptionMessageRegExp #^Element file "Element[\\/]non_existent_element\.ctp" is missing\.$#
  455. */
  456. public function testElementNonExistentTwo()
  457. {
  458. $this->View->element('non_existent_element');
  459. }
  460. }
  461. EOT
  462. ,
  463. ];
  464. yield 'message on newline' => [
  465. <<<'EOT'
  466. <?php
  467. final class MyTest extends \PHPUnit_Framework_TestCase
  468. {
  469. /**
  470. */
  471. public function testMessageOnMultilines()
  472. {
  473. $this->setExpectedException(\RuntimeException::class, 'Message on multilines AAA €');
  474. aaa();
  475. }
  476. /**
  477. * @foo
  478. */
  479. public function testMessageOnMultilinesWithAnotherTag()
  480. {
  481. $this->setExpectedException(\RuntimeException::class, 'Message on multilines BBB è');
  482. bbb();
  483. }
  484. /**
  485. *
  486. * @foo
  487. */
  488. public function testMessageOnMultilinesWithAnotherSpaceAndTag()
  489. {
  490. $this->setExpectedException(\RuntimeException::class, 'Message on multilines CCC ✔');
  491. ccc();
  492. }
  493. }
  494. EOT
  495. ,
  496. <<<'EOT'
  497. <?php
  498. final class MyTest extends \PHPUnit_Framework_TestCase
  499. {
  500. /**
  501. * @expectedException \RuntimeException
  502. * @expectedExceptionMessage Message
  503. * on
  504. * multilines AAA
  505. * €
  506. */
  507. public function testMessageOnMultilines()
  508. {
  509. aaa();
  510. }
  511. /**
  512. * @expectedException \RuntimeException
  513. * @expectedExceptionMessage Message
  514. * on
  515. * multilines BBB
  516. * è
  517. * @foo
  518. */
  519. public function testMessageOnMultilinesWithAnotherTag()
  520. {
  521. bbb();
  522. }
  523. /**
  524. * @expectedException \RuntimeException
  525. * @expectedExceptionMessage Message
  526. * on
  527. * multilines CCC
  528. * ✔
  529. *
  530. * @foo
  531. */
  532. public function testMessageOnMultilinesWithAnotherSpaceAndTag()
  533. {
  534. ccc();
  535. }
  536. }
  537. EOT
  538. ,
  539. ];
  540. yield 'annotation with double @' => [
  541. '<?php
  542. final class MyTest extends \PHPUnit_Framework_TestCase
  543. {
  544. /**
  545. * Double "@" is/was below
  546. */
  547. public function testFnc()
  548. {
  549. $this->setExpectedException(\FooException::class);
  550. aaa();
  551. }
  552. }',
  553. '<?php
  554. final class MyTest extends \PHPUnit_Framework_TestCase
  555. {
  556. /**
  557. * Double "@" is/was below
  558. * @@expectedException FooException
  559. */
  560. public function testFnc()
  561. {
  562. aaa();
  563. }
  564. }',
  565. ];
  566. yield 'annotation with text before @' => [
  567. '<?php
  568. final class MyTest extends \PHPUnit_Framework_TestCase
  569. {
  570. /**
  571. * We are providing invalid input, for that we @expectedException FooException
  572. */
  573. public function testFnc()
  574. {
  575. aaa();
  576. }
  577. }',
  578. ];
  579. yield [
  580. '<?php
  581. abstract class MyTest extends \PHPUnit_Framework_TestCase
  582. {
  583. /**
  584. * @expectedException FooException
  585. * @expectedExceptionMessage
  586. */
  587. abstract public function testFnc();
  588. }',
  589. ];
  590. yield 'expecting exception in single line comment' => [
  591. '<?php
  592. final class MyTest extends \PHPUnit_Framework_TestCase
  593. {
  594. /** */
  595. public function testFnc()
  596. {
  597. $this->setExpectedException(\FooException::class);
  598. aaa();
  599. }
  600. }',
  601. '<?php
  602. final class MyTest extends \PHPUnit_Framework_TestCase
  603. {
  604. /** @expectedException FooException */
  605. public function testFnc()
  606. {
  607. aaa();
  608. }
  609. }',
  610. ];
  611. yield 'expecting exception with message below' => [
  612. '<?php
  613. class MyTest extends TestCase
  614. {
  615. /**
  616. */
  617. public function testSomething()
  618. {
  619. $this->setExpectedException(\Foo\Bar::class);
  620. $this->initialize();
  621. }
  622. }',
  623. '<?php
  624. class MyTest extends TestCase
  625. {
  626. /**
  627. * @expectedException Foo\Bar
  628. *
  629. * Testing stuff.
  630. */
  631. public function testSomething()
  632. {
  633. $this->initialize();
  634. }
  635. }',
  636. ];
  637. }
  638. /**
  639. * @dataProvider provideMessyWhitespacesCases
  640. */
  641. public function testMessyWhitespaces(string $expected, ?string $input = null): void
  642. {
  643. $expected = str_replace([' ', "\n"], ["\t", "\r\n"], $expected);
  644. if (null !== $input) {
  645. $input = str_replace([' ', "\n"], ["\t", "\r\n"], $input);
  646. }
  647. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  648. $this->doTest($expected, $input);
  649. }
  650. public static function provideMessyWhitespacesCases(): iterable
  651. {
  652. yield [
  653. '<?php
  654. final class MyTest extends \PHPUnit_Framework_TestCase
  655. {
  656. /**
  657. */
  658. public function testFnc()
  659. {
  660. $this->setExpectedException(\FooException::class, \'foo\', 123);
  661. aaa();
  662. }
  663. }',
  664. '<?php
  665. final class MyTest extends \PHPUnit_Framework_TestCase
  666. {
  667. /**
  668. * @expectedException FooException
  669. * @expectedExceptionMessage foo
  670. * @expectedExceptionCode 123
  671. */
  672. public function testFnc()
  673. {
  674. aaa();
  675. }
  676. }',
  677. ];
  678. yield [
  679. '<?php
  680. final class MyTest extends \PHPUnit_Framework_TestCase
  681. {
  682. /**
  683. */
  684. public function testFnc()
  685. {
  686. $this->setExpectedException(\FooException::class, \'foo\', 123);
  687. aaa();
  688. }
  689. }',
  690. '<?php
  691. final class MyTest extends \PHPUnit_Framework_TestCase
  692. {
  693. /**
  694. * @expectedException FooException
  695. * @expectedExceptionMessage foo
  696. * @expectedExceptionCode 123
  697. */
  698. public function testFnc()
  699. {
  700. aaa();
  701. }
  702. }',
  703. ];
  704. }
  705. }