ClassDefinitionFixerTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  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\ClassNotation;
  12. use PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer;
  13. use PhpCsFixer\Test\AbstractFixerTestCase;
  14. use PhpCsFixer\Tokenizer\Tokens;
  15. use PhpCsFixer\WhitespacesFixerConfig;
  16. /**
  17. * @author SpacePossum
  18. *
  19. * @internal
  20. *
  21. * @covers \PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer
  22. */
  23. final class ClassDefinitionFixerTest extends AbstractFixerTestCase
  24. {
  25. /**
  26. * @group legacy
  27. * @expectedDeprecation Passing NULL to set default configuration is deprecated and will not be supported in 3.0, use an empty array instead.
  28. */
  29. public function testLegacyConfigureDefaultToNull()
  30. {
  31. $defaultConfig = [
  32. 'multiLineExtendsEachSingleLine' => false,
  33. 'singleItemSingleLine' => false,
  34. 'singleLine' => false,
  35. ];
  36. $fixer = new ClassDefinitionFixer();
  37. $fixer->configure($defaultConfig);
  38. $this->assertAttributeSame($defaultConfig, 'configuration', $fixer);
  39. $fixer->configure(null);
  40. $this->assertAttributeSame($defaultConfig, 'configuration', $fixer);
  41. }
  42. public function testConfigureDefaultToNull()
  43. {
  44. $defaultConfig = [
  45. 'multiLineExtendsEachSingleLine' => false,
  46. 'singleItemSingleLine' => false,
  47. 'singleLine' => false,
  48. ];
  49. $fixer = new ClassDefinitionFixer();
  50. $fixer->configure($defaultConfig);
  51. $this->assertAttributeSame($defaultConfig, 'configuration', $fixer);
  52. $fixer->configure([]);
  53. $this->assertAttributeSame($defaultConfig, 'configuration', $fixer);
  54. }
  55. /**
  56. * @param string $expected PHP source code
  57. * @param string $input PHP source code
  58. * @param array<string, bool> $config
  59. *
  60. * @dataProvider provideAnonymousClassesCases
  61. *
  62. * @requires PHP 7.0
  63. */
  64. public function testFixingAnonymousClasses($expected, $input, array $config = [])
  65. {
  66. $this->fixer->configure($config);
  67. $this->doTest($expected, $input);
  68. }
  69. /**
  70. * @param string $expected PHP source code
  71. * @param string $input PHP source code
  72. *
  73. * @dataProvider provideClassesCases
  74. */
  75. public function testFixingClasses($expected, $input)
  76. {
  77. $this->fixer->configure([]);
  78. $this->doTest($expected, $input);
  79. }
  80. /**
  81. * @param string $expected PHP source code
  82. * @param string $input PHP source code
  83. * @param array<string, bool> $config
  84. *
  85. * @dataProvider provideClassesWithConfigCases
  86. */
  87. public function testFixingClassesWithConfig($expected, $input, array $config)
  88. {
  89. $this->fixer->configure($config);
  90. $this->doTest($expected, $input);
  91. }
  92. /**
  93. * @param string $expected PHP source code
  94. * @param string $input PHP source code
  95. *
  96. * @dataProvider provideInterfacesCases
  97. */
  98. public function testFixingInterfaces($expected, $input)
  99. {
  100. $this->fixer->configure([]);
  101. $this->doTest($expected, $input);
  102. }
  103. /**
  104. * @param string $expected PHP source code
  105. * @param string $input PHP source code
  106. *
  107. * @dataProvider provideTraitsCases
  108. */
  109. public function testFixingTraits($expected, $input)
  110. {
  111. $this->fixer->configure([]);
  112. $this->doTest($expected, $input);
  113. }
  114. public function testInvalidConfigurationKey()
  115. {
  116. $this->setExpectedExceptionRegExp(
  117. \PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class,
  118. '/^\[class_definition\] Invalid configuration: The option "a" does not exist\. Defined options are: "multiLineExtendsEachSingleLine", "singleItemSingleLine", "singleLine"\.$/'
  119. );
  120. $fixer = new ClassDefinitionFixer();
  121. $fixer->configure(['a' => false]);
  122. }
  123. public function testInvalidConfigurationValueType()
  124. {
  125. $this->setExpectedExceptionRegExp(
  126. \PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::class,
  127. '/^\[class_definition\] Invalid configuration: The option "singleLine" with value "z" is expected to be of type "bool", but is of type "string"\.$/'
  128. );
  129. $fixer = new ClassDefinitionFixer();
  130. $fixer->configure(['singleLine' => 'z']);
  131. }
  132. public function provideAnonymousClassesCases()
  133. {
  134. return [
  135. [
  136. '<?php $a = new class(0) extends SomeClass implements SomeInterface, D {};',
  137. "<?php \$a = new class(0) extends\nSomeClass\timplements SomeInterface, D {};",
  138. ],
  139. [
  140. '<?php $a = new class(1) extends SomeClass implements SomeInterface, D {};',
  141. "<?php \$a = new class(1) extends\nSomeClass\timplements SomeInterface, D {};",
  142. ['singleLine' => true],
  143. ],
  144. [
  145. "<?php \$a = new class('1a') implements\nA\n{};",
  146. "<?php \$a = new class('1a') implements\nA{};",
  147. ],
  148. [
  149. "<?php \$a = new class('1a') implements A {};",
  150. "<?php \$a = new class('1a') implements\nA{};",
  151. ['singleItemSingleLine' => true],
  152. ],
  153. [
  154. '<?php $a = new class {};',
  155. '<?php $a = new class{};',
  156. ],
  157. [
  158. '<?php $a = new class {};',
  159. "<?php \$a = new class\n{};",
  160. ],
  161. [
  162. '<?php $a = new class() {};',
  163. "<?php \$a = new\n class ( ){};",
  164. ],
  165. [
  166. '<?php $a = new class(10, 1, /**/ 2) {};',
  167. '<?php $a = new class( 10, 1,/**/2 ){};',
  168. ],
  169. [
  170. '<?php $a = new class(2) {};',
  171. '<?php $a = new class(2){};',
  172. ],
  173. [
  174. '<?php $a = new class($this->prop) {};',
  175. '<?php $a = new class( $this->prop ){};',
  176. ],
  177. [
  178. '<?php $a = new class($this->prop, $v[3], 4) {};',
  179. '<?php $a = new class( $this->prop,$v[3], 4) {};',
  180. ],
  181. 'PSR-12 Extends/Implements Parenthesis on the next line.' => [
  182. '<?php
  183. $instance = new class extends \Foo implements
  184. \ArrayAccess,
  185. \Countable,
  186. \Serializable
  187. {};',
  188. '<?php
  189. $instance = new class extends \Foo implements
  190. \ArrayAccess,\Countable,\Serializable{};',
  191. ],
  192. 'PSR-12 Implements Parenthesis on the next line.' => [
  193. '<?php
  194. $instance = new class implements
  195. \ArrayAccess,
  196. \Countable,
  197. \Serializable
  198. {};',
  199. '<?php
  200. $instance = new class implements
  201. \ArrayAccess,\Countable,\Serializable{};',
  202. ],
  203. 'PSR-12 Extends Parenthesis on the next line.' => [
  204. '<?php
  205. $instance = new class extends
  206. ArrayAccess
  207. {};',
  208. '<?php
  209. $instance = new class
  210. extends
  211. ArrayAccess
  212. {};',
  213. ],
  214. [
  215. "<?php \$a = new #
  216. class #
  217. ( #
  218. '1a', #
  219. 1 #
  220. ) #
  221. implements#
  222. A, #
  223. B,
  224. C #
  225. {#
  226. #
  227. }#
  228. ;",
  229. "<?php \$a = new#
  230. class#
  231. (#
  232. '1a',#
  233. 1 #
  234. )#
  235. implements#
  236. A, #
  237. B,C#
  238. {#
  239. #
  240. }#
  241. ;",
  242. ],
  243. [
  244. "<?php \$a = new #
  245. class #
  246. ( #
  247. '1a', #
  248. 1 #
  249. ) #
  250. implements #
  251. A #
  252. {#
  253. #
  254. }#
  255. ;",
  256. "<?php \$a = new#
  257. class#
  258. (#
  259. '1a',#
  260. 1 #
  261. )#
  262. implements#
  263. A#
  264. {#
  265. #
  266. }#
  267. ;",
  268. ['singleItemSingleLine' => true],
  269. ],
  270. [
  271. '<?php $a = new class() #
  272. {};',
  273. '<?php $a = new class()#
  274. {};',
  275. ],
  276. ];
  277. }
  278. public function provideClassesCases()
  279. {
  280. return array_merge(
  281. $this->provideClassyCases('class'),
  282. $this->provideClassyExtendingCases('class'),
  283. $this->provideClassyImplementsCases()
  284. );
  285. }
  286. public function provideClassesWithConfigCases()
  287. {
  288. return [
  289. [
  290. "<?php class configA implements B, C\n{}",
  291. "<?php class configA implements\nB, C{}",
  292. ['singleLine' => true],
  293. ],
  294. [
  295. "<?php class configA1 extends B\n{}",
  296. "<?php class configA1\n extends\nB{}",
  297. ['singleLine' => true],
  298. ],
  299. [
  300. "<?php class configA1a extends B\n{}",
  301. "<?php class configA1a\n extends\nB{}",
  302. ['singleLine' => false, 'singleItemSingleLine' => true],
  303. ],
  304. [
  305. "<?php class configA2 extends D implements B, C\n{}",
  306. "<?php class configA2 extends D implements\nB,\nC{}",
  307. ['singleLine' => true],
  308. ],
  309. [
  310. "<?php class configA3 extends D implements B, C\n{}",
  311. "<?php class configA3\n extends\nD\n\t implements\nB,\nC{}",
  312. ['singleLine' => true],
  313. ],
  314. [
  315. "<?php class configA4 extends D implements B, #\nC\n{}",
  316. "<?php class configA4\n extends\nD\n\t implements\nB,#\nC{}",
  317. ['singleLine' => true],
  318. ],
  319. [
  320. "<?php class configA5 implements A\n{}",
  321. "<?php class configA5 implements\nA{}",
  322. ['singleLine' => false, 'singleItemSingleLine' => true],
  323. ],
  324. [
  325. "<?php interface TestWithMultiExtendsMultiLine extends\n A,\nAb,\n C,\n D\n{}",
  326. "<?php interface TestWithMultiExtendsMultiLine extends A,\nAb,C,D\n{}",
  327. [
  328. 'singleLine' => false,
  329. 'singleItemSingleLine' => false,
  330. 'multiLineExtendsEachSingleLine' => true,
  331. ],
  332. ],
  333. ];
  334. }
  335. public function provideInterfacesCases()
  336. {
  337. $cases = array_merge(
  338. $this->provideClassyCases('interface'),
  339. $this->provideClassyExtendingCases('interface')
  340. );
  341. $cases[] = [
  342. '<?php
  343. interface Test extends
  344. /*a*/ /*b*/TestInterface1 , \A\B\C , /* test */
  345. TestInterface2 , // test
  346. '.'
  347. // Note: PSR does not have a rule for multiple extends
  348. TestInterface3, /**/ TestInterface4 ,
  349. TestInterface5 , '.'
  350. /**/TestInterface65
  351. {}
  352. ',
  353. '<?php
  354. interface Test
  355. extends
  356. /*a*/ /*b*/TestInterface1 , \A\B\C , /* test */
  357. TestInterface2 , // test
  358. '.'
  359. // Note: PSR does not have a rule for multiple extends
  360. TestInterface3, /**/ TestInterface4 ,
  361. TestInterface5 , '.'
  362. /**/TestInterface65 {}
  363. ',
  364. ];
  365. return $cases;
  366. }
  367. public function provideTraitsCases()
  368. {
  369. return $this->provideClassyCases('trait');
  370. }
  371. /**
  372. * @param string $source PHP source code
  373. * @param array $expected
  374. *
  375. * @dataProvider provideClassyDefinitionInfoCases
  376. */
  377. public function testClassyDefinitionInfo($source, array $expected)
  378. {
  379. Tokens::clearCache();
  380. $tokens = Tokens::fromCode($source);
  381. $method = new \ReflectionMethod($this->fixer, 'getClassyDefinitionInfo');
  382. $method->setAccessible(true);
  383. $result = $method->invoke($this->fixer, $tokens, $expected['classy']);
  384. $this->assertSame($expected, $result);
  385. }
  386. public function provideClassyDefinitionInfoCases()
  387. {
  388. return [
  389. [
  390. '<?php class A{}',
  391. [
  392. 'start' => 1,
  393. 'classy' => 1,
  394. 'open' => 4,
  395. 'extends' => false,
  396. 'implements' => false,
  397. 'anonymousClass' => false,
  398. ],
  399. ],
  400. [
  401. '<?php final class A{}',
  402. [
  403. 'start' => 1,
  404. 'classy' => 3,
  405. 'open' => 6,
  406. 'extends' => false,
  407. 'implements' => false,
  408. 'anonymousClass' => false,
  409. ],
  410. ],
  411. [
  412. '<?php abstract /**/ class A{}',
  413. [
  414. 'start' => 1,
  415. 'classy' => 5,
  416. 'open' => 8,
  417. 'extends' => false,
  418. 'implements' => false,
  419. 'anonymousClass' => false,
  420. ],
  421. ],
  422. [
  423. '<?php class A extends B {}',
  424. [
  425. 'start' => 1,
  426. 'classy' => 1,
  427. 'open' => 9,
  428. 'extends' => [
  429. 'start' => 5,
  430. 'numberOfExtends' => 1,
  431. 'multiLine' => false,
  432. ],
  433. 'implements' => false,
  434. 'anonymousClass' => false,
  435. ],
  436. ],
  437. [
  438. '<?php interface A extends B,C,D {}',
  439. [
  440. 'start' => 1,
  441. 'classy' => 1,
  442. 'open' => 13,
  443. 'extends' => [
  444. 'start' => 5,
  445. 'numberOfExtends' => 3,
  446. 'multiLine' => false,
  447. ],
  448. 'implements' => false,
  449. 'anonymousClass' => false,
  450. ],
  451. ],
  452. ];
  453. }
  454. /**
  455. * @param string $source PHP source code
  456. * @param string $label
  457. * @param array $expected
  458. *
  459. * @dataProvider provideClassyImplementsInfoCases
  460. */
  461. public function testClassyInheritanceInfo($source, $label, array $expected)
  462. {
  463. $this->doTestClassyInheritanceInfo($source, $label, $expected);
  464. }
  465. /**
  466. * @param string $source PHP source code
  467. * @param string $label
  468. * @param array $expected
  469. *
  470. * @requires PHP 7.0
  471. * @dataProvider provideClassyImplementsInfoCases7
  472. */
  473. public function testClassyInheritanceInfo7($source, $label, array $expected)
  474. {
  475. $this->doTestClassyInheritanceInfo($source, $label, $expected);
  476. }
  477. public function doTestClassyInheritanceInfo($source, $label, array $expected)
  478. {
  479. Tokens::clearCache();
  480. $tokens = Tokens::fromCode($source);
  481. $this->assertTrue($tokens[$expected['start']]->isGivenKind([T_IMPLEMENTS, T_EXTENDS]), sprintf('Token must be "implements" or "extends", got "%s".', $tokens[$expected['start']]->getContent()));
  482. $method = new \ReflectionMethod($this->fixer, 'getClassyInheritanceInfo');
  483. $method->setAccessible(true);
  484. $result = $method->invoke($this->fixer, $tokens, $expected['start'], $label);
  485. $this->assertSame($expected, $result);
  486. }
  487. public function provideClassyImplementsInfoCases()
  488. {
  489. return [
  490. [
  491. '<?php
  492. class X11 implements Z , T,R
  493. {
  494. }',
  495. 'numberOfImplements',
  496. ['start' => 5, 'numberOfImplements' => 3, 'multiLine' => false],
  497. ],
  498. [
  499. '<?php
  500. class X10 implements Z , T,R //
  501. {
  502. }',
  503. 'numberOfImplements',
  504. ['start' => 5, 'numberOfImplements' => 3, 'multiLine' => false],
  505. ],
  506. [
  507. '<?php class A implements B {}',
  508. 'numberOfImplements',
  509. ['start' => 5, 'numberOfImplements' => 1, 'multiLine' => false],
  510. ],
  511. [
  512. "<?php class A implements B,\n C{}",
  513. 'numberOfImplements',
  514. ['start' => 5, 'numberOfImplements' => 2, 'multiLine' => true],
  515. ],
  516. [
  517. "<?php class A implements Z\\C\\B,C,D {\n\n\n}",
  518. 'numberOfImplements',
  519. ['start' => 5, 'numberOfImplements' => 3, 'multiLine' => false],
  520. ],
  521. [
  522. '<?php
  523. namespace A {
  524. interface C {}
  525. }
  526. namespace {
  527. class B{}
  528. class A extends //
  529. B implements /* */ \A
  530. \C, Z{
  531. public function test()
  532. {
  533. echo 1;
  534. }
  535. }
  536. $a = new A();
  537. $a->test();
  538. }',
  539. 'numberOfImplements',
  540. ['start' => 36, 'numberOfImplements' => 2, 'multiLine' => true],
  541. ],
  542. ];
  543. }
  544. public function provideClassyImplementsInfoCases7()
  545. {
  546. return [
  547. [
  548. "<?php \$a = new class(3) extends\nSomeClass\timplements SomeInterface, D {};",
  549. 'numberOfExtends',
  550. ['start' => 12, 'numberOfExtends' => 1, 'multiLine' => true],
  551. ],
  552. [
  553. "<?php \$a = new class(4) extends\nSomeClass\timplements SomeInterface, D\n\n{};",
  554. 'numberOfImplements',
  555. ['start' => 16, 'numberOfImplements' => 2, 'multiLine' => false],
  556. ],
  557. [
  558. "<?php \$a = new class(5) extends SomeClass\nimplements SomeInterface, D {};",
  559. 'numberOfExtends',
  560. ['start' => 12, 'numberOfExtends' => 1, 'multiLine' => true],
  561. ],
  562. ];
  563. }
  564. /**
  565. * @param string $expected
  566. * @param null|string $input
  567. *
  568. * @dataProvider providePHP7Cases
  569. * @requires PHP 7.0
  570. */
  571. public function testFixPHP7($expected, $input = null)
  572. {
  573. $this->fixer->configure([]);
  574. $this->doTest($expected, $input);
  575. }
  576. public function providePHP7Cases()
  577. {
  578. return [
  579. [
  580. '<?php
  581. $a = new class implements
  582. \RFb,
  583. \Fcc,
  584. \GFddZz
  585. {
  586. };',
  587. '<?php
  588. $a = new class implements
  589. \RFb,
  590. \Fcc, \GFddZz
  591. {
  592. };',
  593. ],
  594. [
  595. '<?php
  596. $a = new class implements
  597. \RFb,
  598. \Fcc,
  599. \GFddZz
  600. {
  601. }?>',
  602. '<?php
  603. $a = new class implements
  604. \RFb,
  605. \Fcc, \GFddZz
  606. {
  607. }?>',
  608. ],
  609. ];
  610. }
  611. /**
  612. * @param string $expected
  613. * @param null|string $input
  614. *
  615. * @dataProvider provideMessyWhitespacesCases
  616. */
  617. public function testMessyWhitespaces($expected, $input = null)
  618. {
  619. $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
  620. $this->fixer->configure([]);
  621. $this->doTest($expected, $input);
  622. }
  623. public function provideMessyWhitespacesCases()
  624. {
  625. return [
  626. [
  627. "<?php\r\nclass Aaa implements\r\n\tBbb,\r\n\tCcc,\r\n\tDdd\r\n\t{\r\n\t}",
  628. "<?php\r\nclass Aaa implements\r\n\tBbb, Ccc,\r\n\tDdd\r\n\t{\r\n\t}",
  629. ],
  630. ];
  631. }
  632. private function provideClassyCases($classy)
  633. {
  634. return [
  635. [
  636. sprintf("<?php %s A\n{}", $classy),
  637. sprintf('<?php %s A {}', $classy),
  638. ],
  639. [
  640. sprintf("<?php %s B\n{}", $classy),
  641. sprintf('<?php %s B{}', $classy),
  642. ],
  643. [
  644. sprintf("<?php %s C\n{}", $classy),
  645. sprintf("<?php %s\n\tC{}", $classy),
  646. ],
  647. [
  648. sprintf("<?php %s D //\n{}", $classy),
  649. sprintf("<?php %s D//\n{}", $classy),
  650. ],
  651. [
  652. sprintf("<?php %s /**/ E //\n{}", $classy),
  653. sprintf("<?php %s/**/E//\n{}", $classy),
  654. ],
  655. [
  656. sprintf(
  657. "<?php
  658. %s A
  659. {}
  660. %s /**/ B //
  661. /**/\n{}", $classy, $classy
  662. ),
  663. sprintf(
  664. '<?php
  665. %s
  666. A
  667. {}
  668. %s/**/B //
  669. /**/ {}', $classy, $classy
  670. ),
  671. ],
  672. [
  673. sprintf('<?php
  674. namespace {
  675. %s IndentedNameSpacedClass
  676. {
  677. }
  678. }', $classy
  679. ),
  680. sprintf('<?php
  681. namespace {
  682. %s IndentedNameSpacedClass {
  683. }
  684. }', $classy
  685. ),
  686. ],
  687. ];
  688. }
  689. private function provideClassyExtendingCases($classy)
  690. {
  691. return [
  692. [
  693. sprintf("<?php %s AE0 extends B\n{}", $classy),
  694. sprintf('<?php %s AE0 extends B {}', $classy),
  695. ],
  696. [
  697. sprintf("<?php %s /**/ AE1 /**/ extends /**/ B /**/\n{}", $classy),
  698. sprintf('<?php %s/**/AE1/**/extends/**/B/**/{}', $classy),
  699. ],
  700. [
  701. sprintf("<?php %s /*%s*/ AE2 extends\nB\n{}", $classy, $classy),
  702. sprintf("<?php %s /*%s*/ AE2 extends\nB{}", $classy, $classy),
  703. ],
  704. [
  705. sprintf('<?php
  706. %s Test124 extends
  707. \Exception
  708. {}', $classy),
  709. sprintf('<?php
  710. %s
  711. Test124
  712. extends
  713. \Exception {}', $classy),
  714. ],
  715. ];
  716. }
  717. private function provideClassyImplementsCases()
  718. {
  719. return [
  720. [
  721. "<?php class E implements B\n{}",
  722. "<?php class E \nimplements B \t{}",
  723. ],
  724. [
  725. "<?php abstract class F extends B implements C\n{}",
  726. '<?php abstract class F extends B implements C {}',
  727. ],
  728. [
  729. "<?php abstract class G extends //
  730. B /* */ implements C\n{}",
  731. '<?php abstract class G extends //
  732. B/* */implements C{}',
  733. ],
  734. [
  735. '<?php
  736. class Aaa IMPLEMENTS
  737. \RFb,
  738. \Fcc,
  739. \GFddZz
  740. {
  741. }',
  742. '<?php
  743. class Aaa IMPLEMENTS
  744. \RFb,
  745. \Fcc, \GFddZz
  746. {
  747. }',
  748. ],
  749. [
  750. '<?php
  751. class //
  752. X //
  753. extends //
  754. Y //
  755. implements //
  756. Z, //
  757. U //
  758. {} //',
  759. '<?php
  760. class //
  761. X //
  762. extends //
  763. Y //
  764. implements //
  765. Z , //
  766. U //
  767. {} //',
  768. ],
  769. [
  770. '<?php
  771. class Aaa implements
  772. PhpCsFixer\Tests\Fixer,
  773. \RFb,
  774. \Fcc1,
  775. \GFdd
  776. {
  777. }',
  778. '<?php
  779. class Aaa implements
  780. PhpCsFixer\Tests\Fixer,\RFb,
  781. \Fcc1, \GFdd
  782. {
  783. }',
  784. ],
  785. [
  786. '<?php
  787. class /**/ Test123 EXtends /**/ \RuntimeException implements
  788. TestZ
  789. {
  790. }',
  791. '<?php
  792. class/**/Test123
  793. EXtends /**/ \RuntimeException implements
  794. TestZ
  795. {
  796. }',
  797. ],
  798. [
  799. '<?php
  800. class Aaa implements Ebb, \Ccc
  801. {
  802. }',
  803. '<?php
  804. class Aaa implements Ebb, \Ccc
  805. {
  806. }',
  807. ],
  808. [
  809. '<?php
  810. class X2 IMPLEMENTS
  811. Z, //
  812. U,
  813. D
  814. {
  815. }',
  816. '<?php
  817. class X2 IMPLEMENTS
  818. Z , //
  819. U, D
  820. {
  821. }',
  822. ],
  823. [
  824. '<?php
  825. class VeryLongClassNameWithLotsOfLetters extends AnotherVeryLongClassName implements
  826. VeryLongInterfaceNameThatIDontWantOnTheSameLine
  827. {
  828. }',
  829. '<?php
  830. class VeryLongClassNameWithLotsOfLetters extends AnotherVeryLongClassName implements
  831. VeryLongInterfaceNameThatIDontWantOnTheSameLine
  832. {
  833. }',
  834. ],
  835. [
  836. '<?php
  837. class /**/ Test125 //aaa
  838. extends /*
  839. */
  840. //
  841. \Exception //
  842. {}',
  843. '<?php
  844. class/**/Test125 //aaa
  845. extends /*
  846. */
  847. //
  848. \Exception //
  849. {}',
  850. ],
  851. [
  852. '<?php
  853. class Test extends TestInterface8 implements /*a*/ /*b*/
  854. TestInterface1, /* test */
  855. TestInterface2, // test
  856. '.'
  857. // test
  858. TestInterface3, /**/
  859. TestInterface4,
  860. TestInterface5, '.'
  861. /**/TestInterface6c
  862. {
  863. }',
  864. '<?php
  865. class Test
  866. extends
  867. TestInterface8
  868. implements /*a*/ /*b*/TestInterface1 , /* test */
  869. TestInterface2 , // test
  870. '.'
  871. // test
  872. TestInterface3, /**/ TestInterface4 ,
  873. TestInterface5 , '.'
  874. /**/TestInterface6c
  875. {
  876. }',
  877. ],
  878. ];
  879. }
  880. }