HeaderCommentFixerTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. <?php
  2. /*
  3. * This file is part of PHP CS Fixer.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. namespace PhpCsFixer\Tests\Fixer\Comment;
  12. use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException;
  13. use PhpCsFixer\Fixer\Comment\HeaderCommentFixer;
  14. use PhpCsFixer\Tests\Test\AbstractFixerWithAliasedOptionsTestCase;
  15. use PhpCsFixer\WhitespacesFixerConfig;
  16. /**
  17. * @internal
  18. *
  19. * @covers \PhpCsFixer\Fixer\Comment\HeaderCommentFixer
  20. */
  21. final class HeaderCommentFixerTest extends AbstractFixerWithAliasedOptionsTestCase
  22. {
  23. /**
  24. * @param string $expected
  25. * @param string $input
  26. *
  27. * @dataProvider provideFixCases
  28. */
  29. public function testFix(array $configuration, $expected, $input)
  30. {
  31. $this->configureFixerWithAliasedOptions($configuration);
  32. $this->doTest($expected, $input);
  33. }
  34. public function provideFixCases()
  35. {
  36. return [
  37. [
  38. ['header' => ''],
  39. '<?php
  40. $a;',
  41. '<?php
  42. /**
  43. * new
  44. */
  45. $a;',
  46. ],
  47. [
  48. [
  49. 'header' => 'tmp',
  50. 'location' => 'after_declare_strict',
  51. ],
  52. '<?php
  53. declare(strict_types=1);
  54. /*
  55. * tmp
  56. */
  57. namespace A\B;
  58. echo 1;',
  59. '<?php
  60. declare(strict_types=1);namespace A\B;
  61. echo 1;',
  62. ],
  63. [
  64. [
  65. 'header' => 'tmp',
  66. 'location' => 'after_declare_strict',
  67. 'separate' => 'bottom',
  68. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  69. ],
  70. '<?php
  71. declare(strict_types=1);
  72. /**
  73. * tmp
  74. */
  75. namespace A\B;
  76. echo 1;',
  77. '<?php
  78. declare(strict_types=1);
  79. namespace A\B;
  80. echo 1;',
  81. ],
  82. [
  83. [
  84. 'header' => 'tmp',
  85. 'location' => 'after_open',
  86. ],
  87. '<?php
  88. /*
  89. * tmp
  90. */
  91. declare(strict_types=1);
  92. namespace A\B;
  93. echo 1;',
  94. '<?php
  95. declare(strict_types=1);
  96. namespace A\B;
  97. echo 1;',
  98. ],
  99. [
  100. [
  101. 'header' => 'new',
  102. 'comment_type' => HeaderCommentFixer::HEADER_COMMENT,
  103. ],
  104. '<?php
  105. /*
  106. * new
  107. */
  108. ',
  109. '<?php
  110. /** test */
  111. ',
  112. ],
  113. [
  114. [
  115. 'header' => 'new',
  116. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  117. ],
  118. '<?php
  119. /**
  120. * new
  121. */
  122. ',
  123. '<?php
  124. /* test */
  125. ',
  126. ],
  127. [
  128. [
  129. 'header' => 'def',
  130. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  131. ],
  132. '<?php
  133. /**
  134. * def
  135. */
  136. ',
  137. '<?php
  138. ',
  139. ],
  140. [
  141. ['header' => 'xyz'],
  142. '<?php
  143. /*
  144. * xyz
  145. */
  146. $b;',
  147. '<?php
  148. $b;',
  149. ],
  150. [
  151. [
  152. 'header' => 'xyz123',
  153. 'separate' => 'none',
  154. ],
  155. '<?php
  156. /*
  157. * xyz123
  158. */
  159. $a;',
  160. '<?php
  161. $a;',
  162. ],
  163. [
  164. [
  165. 'header' => 'abc',
  166. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  167. ],
  168. '<?php
  169. /**
  170. * abc
  171. */
  172. $c;',
  173. '<?php
  174. $c;',
  175. ],
  176. [
  177. [
  178. 'header' => 'ghi',
  179. 'separate' => 'both',
  180. ],
  181. '<?php
  182. /*
  183. * ghi
  184. */
  185. $d;',
  186. '<?php
  187. $d;',
  188. ],
  189. [
  190. [
  191. 'header' => 'ghi',
  192. 'separate' => 'top',
  193. ],
  194. '<?php
  195. /*
  196. * ghi
  197. */
  198. $d;',
  199. '<?php
  200. $d;',
  201. ],
  202. [
  203. [
  204. 'header' => 'tmp',
  205. 'location' => 'after_declare_strict',
  206. ],
  207. '<?php
  208. /*
  209. * tmp
  210. */
  211. declare(ticks=1);
  212. echo 1;',
  213. '<?php
  214. declare(ticks=1);
  215. echo 1;',
  216. ],
  217. [
  218. ['header' => 'Foo'],
  219. '<?php
  220. /*
  221. * Foo
  222. */
  223. echo \'bar\';',
  224. '<?php echo \'bar\';',
  225. ],
  226. [
  227. ['header' => 'x'],
  228. '<?php
  229. /*
  230. * x
  231. */
  232. echo \'a\';',
  233. '<?php
  234. /*
  235. * y
  236. * z
  237. */
  238. echo \'a\';',
  239. ],
  240. [
  241. ['header' => "a\na"],
  242. '<?php
  243. /*
  244. * a
  245. * a
  246. */
  247. echo \'x\';',
  248. '<?php
  249. /*
  250. * b
  251. * c
  252. */
  253. echo \'x\';',
  254. ],
  255. [
  256. [
  257. 'header' => 'foo',
  258. 'location' => 'after_open',
  259. 'separate' => 'bottom',
  260. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  261. ],
  262. '<?php
  263. /**
  264. * foo
  265. */
  266. declare(strict_types=1);
  267. namespace A;
  268. echo 1;',
  269. '<?php
  270. declare(strict_types=1);
  271. /**
  272. * foo
  273. */
  274. namespace A;
  275. echo 1;',
  276. ],
  277. [
  278. [
  279. 'header' => 'foo',
  280. 'location' => 'after_open',
  281. 'separate' => 'bottom',
  282. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  283. ],
  284. '<?php
  285. /**
  286. * foo
  287. */
  288. declare(strict_types=1);
  289. /**
  290. * bar
  291. */
  292. namespace A;
  293. echo 1;',
  294. '<?php
  295. declare(strict_types=1);
  296. /**
  297. * bar
  298. */
  299. namespace A;
  300. echo 1;',
  301. ],
  302. [
  303. [
  304. 'header' => 'Foo',
  305. 'separate' => 'none',
  306. ],
  307. '<?php
  308. declare(strict_types=1);
  309. /*
  310. * Foo
  311. */
  312. namespace SebastianBergmann\Foo;
  313. class Bar
  314. {
  315. }',
  316. '<?php
  317. /*
  318. * Foo
  319. */
  320. declare(strict_types=1);
  321. namespace SebastianBergmann\Foo;
  322. class Bar
  323. {
  324. }',
  325. ],
  326. [
  327. ['header' => 'tmp'],
  328. '<?php
  329. /*
  330. * tmp
  331. */
  332. /**
  333. * Foo class doc.
  334. */
  335. class Foo {}',
  336. '<?php
  337. /**
  338. * Foo class doc.
  339. */
  340. class Foo {}',
  341. ],
  342. [
  343. ['header' => 'tmp'],
  344. '<?php
  345. /*
  346. * tmp
  347. */
  348. class Foo {}',
  349. '<?php
  350. /*
  351. * Foo class doc.
  352. */
  353. class Foo {}',
  354. ],
  355. [
  356. [
  357. 'header' => 'tmp',
  358. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  359. ],
  360. '<?php
  361. /**
  362. * tmp
  363. */
  364. /**
  365. * Foo class doc.
  366. */
  367. class Foo {}',
  368. '<?php
  369. /**
  370. * Foo class doc.
  371. */
  372. class Foo {}',
  373. ],
  374. [
  375. [
  376. 'header' => 'tmp',
  377. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  378. ],
  379. '<?php
  380. /**
  381. * tmp
  382. */
  383. class Foo {}',
  384. '<?php
  385. /**
  386. * tmp
  387. */
  388. class Foo {}',
  389. ],
  390. [
  391. [
  392. 'header' => 'tmp',
  393. 'separate' => 'top',
  394. ],
  395. '<?php
  396. /*
  397. * tmp
  398. */
  399. class Foo {}',
  400. '<?php
  401. /**
  402. * Foo class doc.
  403. */
  404. class Foo {}',
  405. ],
  406. [
  407. [
  408. 'header' => 'bar',
  409. 'location' => 'after_open',
  410. ],
  411. '<?php
  412. /*
  413. * bar
  414. */
  415. declare(strict_types=1);
  416. // foo
  417. foo();',
  418. '<?php
  419. /*
  420. * foo
  421. */
  422. declare(strict_types=1);
  423. // foo
  424. foo();',
  425. ],
  426. [
  427. [
  428. 'header' => 'bar',
  429. 'location' => 'after_open',
  430. ],
  431. '<?php
  432. /*
  433. * bar
  434. */
  435. declare(strict_types=1);
  436. /* foo */
  437. foo();',
  438. '<?php
  439. /*
  440. * foo
  441. */
  442. declare(strict_types=1);
  443. /* foo */
  444. foo();',
  445. ],
  446. [
  447. [
  448. 'header' => 'tmp',
  449. 'location' => 'after_declare_strict',
  450. ],
  451. '<?php
  452. /*
  453. * tmp
  454. */
  455. declare(strict_types=1) ?>',
  456. '<?php
  457. declare(strict_types=1) ?>',
  458. ],
  459. ];
  460. }
  461. public function testDefaultConfiguration()
  462. {
  463. $this->fixer->configure(['header' => 'a']);
  464. $this->doTest(
  465. '<?php
  466. /*
  467. * a
  468. */
  469. echo 1;',
  470. '<?php
  471. echo 1;'
  472. );
  473. }
  474. /**
  475. * @group legacy
  476. * @expectedDeprecation Passing NULL to set default configuration is deprecated and will not be supported in 3.0, use an empty array instead.
  477. */
  478. public function testLegacyMisconfiguration()
  479. {
  480. $this->expectException(\PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class);
  481. $this->expectExceptionMessage('[header_comment] Missing required configuration: The required option "header" is missing.');
  482. $this->fixer->configure(null);
  483. }
  484. /**
  485. * @param null|array $configuration
  486. * @param string $exceptionMessage
  487. *
  488. * @dataProvider provideMisconfigurationCases
  489. */
  490. public function testMisconfiguration($configuration, $exceptionMessage)
  491. {
  492. $this->expectException(\PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class);
  493. $this->expectExceptionMessageMatches("#^\\[header_comment\\] {$exceptionMessage}$#");
  494. $this->configureFixerWithAliasedOptions($configuration);
  495. }
  496. public function provideMisconfigurationCases()
  497. {
  498. return [
  499. [[], 'Missing required configuration: The required option "header" is missing.'],
  500. [
  501. ['header' => 1],
  502. 'Invalid configuration: The option "header" with value 1 is expected to be of type "string", but is of type "(int|integer)"\.',
  503. ],
  504. [
  505. [
  506. 'header' => '',
  507. 'comment_type' => 'foo',
  508. ],
  509. 'Invalid configuration: The option "comment_type" with value "foo" is invalid\. Accepted values are: "PHPDoc", "comment"\.',
  510. ],
  511. [
  512. [
  513. 'header' => '',
  514. 'comment_type' => new \stdClass(),
  515. ],
  516. 'Invalid configuration: The option "comment_type" with value stdClass is invalid\. Accepted values are: "PHPDoc", "comment"\.',
  517. ],
  518. [
  519. [
  520. 'header' => '',
  521. 'location' => new \stdClass(),
  522. ],
  523. 'Invalid configuration: The option "location" with value stdClass is invalid\. Accepted values are: "after_open", "after_declare_strict"\.',
  524. ],
  525. [
  526. [
  527. 'header' => '',
  528. 'separate' => new \stdClass(),
  529. ],
  530. 'Invalid configuration: The option "separate" with value stdClass is invalid\. Accepted values are: "both", "top", "bottom", "none"\.',
  531. ],
  532. ];
  533. }
  534. /**
  535. * @param string $expected
  536. * @param string $header
  537. * @param string $type
  538. *
  539. * @dataProvider provideHeaderGenerationCases
  540. */
  541. public function testHeaderGeneration($expected, $header, $type)
  542. {
  543. $this->configureFixerWithAliasedOptions([
  544. 'header' => $header,
  545. 'comment_type' => $type,
  546. ]);
  547. $this->doTest(
  548. '<?php
  549. '.$expected.'
  550. echo 1;',
  551. '<?php
  552. echo 1;'
  553. );
  554. }
  555. public function provideHeaderGenerationCases()
  556. {
  557. return [
  558. [
  559. '/*
  560. * a
  561. */',
  562. 'a',
  563. HeaderCommentFixer::HEADER_COMMENT,
  564. ],
  565. [
  566. '/**
  567. * a
  568. */',
  569. 'a',
  570. HeaderCommentFixer::HEADER_PHPDOC,
  571. ],
  572. ];
  573. }
  574. /**
  575. * @param string $expected
  576. *
  577. * @dataProvider provideDoNotTouchCases
  578. */
  579. public function testDoNotTouch($expected)
  580. {
  581. $this->fixer->configure([
  582. 'header' => '',
  583. ]);
  584. $this->doTest($expected);
  585. }
  586. public function provideDoNotTouchCases()
  587. {
  588. return [
  589. ["<?php\nphpinfo();\n?>\n<?"],
  590. [" <?php\nphpinfo();\n"],
  591. ["<?php\nphpinfo();\n?><hr/>"],
  592. [" <?php\n"],
  593. ['<?= 1?>'],
  594. ["<?= 1?><?php\n"],
  595. ["<?= 1?>\n<?php\n"],
  596. ];
  597. }
  598. public function testWithoutConfiguration()
  599. {
  600. $this->expectException(\PhpCsFixer\ConfigurationException\RequiredFixerConfigurationException::class);
  601. $this->doTest('<?php echo 1;');
  602. }
  603. /**
  604. * @param string $expected
  605. * @param null|string $input
  606. *
  607. * @dataProvider provideMessyWhitespacesCases
  608. */
  609. public function testMessyWhitespaces(array $configuration, $expected, $input = null)
  610. {
  611. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  612. $this->configureFixerWithAliasedOptions($configuration);
  613. $this->doTest($expected, $input);
  614. }
  615. public function provideMessyWhitespacesCases()
  616. {
  617. return [
  618. [
  619. [
  620. 'header' => 'whitemess',
  621. 'location' => 'after_declare_strict',
  622. 'separate' => 'bottom',
  623. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  624. ],
  625. "<?php\r\ndeclare(strict_types=1);\r\n/**\r\n * whitemess\r\n */\r\n\r\nnamespace A\\B;\r\n\r\necho 1;",
  626. "<?php\r\ndeclare(strict_types=1);\r\n\r\nnamespace A\\B;\r\n\r\necho 1;",
  627. ],
  628. ];
  629. }
  630. public function testConfigurationUpdatedWithWhitespsacesConfig()
  631. {
  632. $this->fixer->configure(['header' => 'Foo']);
  633. $this->doTest(
  634. "<?php\n\n/*\n * Foo\n */\n\necho 1;",
  635. "<?php\necho 1;"
  636. );
  637. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig(' ', "\r\n"));
  638. $this->doTest(
  639. "<?php\r\n\r\n/*\r\n * Foo\r\n */\r\n\r\necho 1;",
  640. "<?php\r\necho 1;"
  641. );
  642. $this->fixer->configure(['header' => 'Bar']);
  643. $this->doTest(
  644. "<?php\r\n\r\n/*\r\n * Bar\r\n */\r\n\r\necho 1;",
  645. "<?php\r\necho 1;"
  646. );
  647. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig(' ', "\n"));
  648. $this->doTest(
  649. "<?php\n\n/*\n * Bar\n */\n\necho 1;",
  650. "<?php\necho 1;"
  651. );
  652. }
  653. public function testInvalidHeaderConfiguration()
  654. {
  655. $this->expectException(InvalidFixerConfigurationException::class);
  656. $this->expectExceptionMessageMatches('#^\[header_comment\] Cannot use \'\*/\' in header\.$#');
  657. $this->fixer->configure([
  658. 'header' => '/** test */',
  659. 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC,
  660. ]);
  661. }
  662. }