Skip to content

Commit 8be3b63

Browse files
committed
Added different class order for test classes
1 parent c21ca33 commit 8be3b63

3 files changed

Lines changed: 311 additions & 2 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of Polymorphine/Dev package.
5+
*
6+
* (c) Shudd3r <q3.shudder@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+
12+
namespace Polymorphine\Dev\Fixer;
13+
14+
use PhpCsFixer\Fixer\FixerInterface;
15+
use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
16+
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
17+
use PhpCsFixer\Tokenizer\Tokens;
18+
use SplFileInfo;
19+
20+
21+
class MultiOrderedClassElementsFixer implements FixerInterface
22+
{
23+
private OrderedClassElementsFixer $srcFixer;
24+
private OrderedClassElementsFixer $testFixer;
25+
26+
/**
27+
* @param array $srcOrder
28+
* @param array $testOrder
29+
*/
30+
public function __construct(array $srcOrder, array $testOrder)
31+
{
32+
$this->srcFixer = new OrderedClassElementsFixer();
33+
$this->testFixer = new OrderedClassElementsFixer();
34+
35+
$this->srcFixer->configure(['order' => $srcOrder, 'sort_algorithm' => 'none']);
36+
$this->testFixer->configure(['order' => $testOrder, 'sort_algorithm' => 'none']);
37+
}
38+
39+
public function getName(): string
40+
{
41+
return 'Polymorphine/multi_ordered_class_elements';
42+
}
43+
44+
public function getDefinition(): FixerDefinitionInterface
45+
{
46+
return $this->srcFixer->getDefinition();
47+
}
48+
49+
public function isCandidate(Tokens $tokens): bool
50+
{
51+
return $this->srcFixer->isCandidate($tokens);
52+
}
53+
54+
public function isRisky(): bool
55+
{
56+
return false;
57+
}
58+
59+
public function fix(SplFileInfo $file, Tokens $tokens): void
60+
{
61+
$this->isTestClass($tokens)
62+
? $this->testFixer->fix($file, $tokens)
63+
: $this->srcFixer->fix($file, $tokens);
64+
}
65+
66+
public function getPriority(): int
67+
{
68+
return $this->srcFixer->getPriority();
69+
}
70+
71+
public function supports(SplFileInfo $file): bool
72+
{
73+
return $this->srcFixer->supports($file);
74+
}
75+
76+
private function isTestClass(Tokens $tokens): bool
77+
{
78+
$classIdx = $tokens->getNextTokenOfKind(0, [[T_CLASS]]);
79+
return $classIdx && substr($tokens[$classIdx + 2]->getContent(), -4) === 'Test';
80+
}
81+
}

src/FixerFactory.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class FixerFactory
5050
'no_useless_else' => true,
5151
'no_useless_return' => true,
5252
'non_printable_character' => ['use_escape_sequences_in_strings' => true],
53-
'ordered_class_elements' => ['order' => [], 'sort_algorithm' => 'none'],
53+
'ordered_class_elements' => false,
5454
'ordered_imports' => false,
5555
'php_unit_strict' => false,
5656
'php_unit_method_casing' => false,
@@ -84,7 +84,7 @@ public static function createFor(string $launchFile): Config
8484
'square_brace_block', 'curly_brace_block'
8585
];
8686

87-
self::$rules['ordered_class_elements']['order'] = [
87+
$srcOrder = [
8888
'use_trait', 'case',
8989
'constant_public', 'constant_protected', 'constant_private',
9090
'property_public_static', 'property_protected_static', 'property_private_static',
@@ -94,8 +94,19 @@ public static function createFor(string $launchFile): Config
9494
'method_public', 'method_protected', 'method_private'
9595
];
9696

97+
$testOrder = [
98+
'use_trait', 'case',
99+
'constant_public', 'constant_protected', 'constant_private',
100+
'property_public_static', 'property_protected_static', 'property_private_static',
101+
'property_public', 'property_protected', 'property_private',
102+
'construct', 'phpunit', 'magic', 'destruct',
103+
'method_public', 'method_protected', 'method_private',
104+
'method_public_static', 'method_protected_static', 'method_private_static'
105+
];
106+
97107
self::$rules['Polymorphine/double_line_before_class_definition'] = true;
98108
self::$rules['Polymorphine/no_trailing_comma_after_multiline_array'] = true;
109+
self::$rules['Polymorphine/multi_ordered_class_elements'] = true;
99110
self::$rules['Polymorphine/named_constructors_first_static'] = true;
100111
self::$rules['Polymorphine/aligned_method_chain'] = true;
101112
self::$rules['Polymorphine/aligned_assignments'] = true;
@@ -121,6 +132,7 @@ public static function createFor(string $launchFile): Config
121132
->registerCustomFixers([
122133
new Fixer\DoubleLineBeforeClassDefinitionFixer(),
123134
new Fixer\NoTrailingCommaInMultilineArrayFixer(),
135+
new Fixer\MultiOrderedClassElementsFixer($srcOrder, $testOrder),
124136
new Fixer\NamedConstructorsFirstStaticFixer(),
125137
new Fixer\AlignedMethodChainFixer(),
126138
new Fixer\AlignedAssignmentsFixer(),
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of Polymorphine/Dev package.
5+
*
6+
* (c) Shudd3r <q3.shudder@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+
12+
namespace Polymorphine\Dev\Tests\Fixer;
13+
14+
use PhpCsFixer\Fixer\FixerInterface;
15+
use Polymorphine\Dev\Tests\FixerTest;
16+
use Polymorphine\Dev\Fixer\MultiOrderedClassElementsFixer;
17+
18+
19+
class MultiOrderedClassElementsFixerTest extends FixerTest
20+
{
21+
public function testClassWithoutTestNameIsOrderedWithSrcConfig()
22+
{
23+
$code = <<<'CODE'
24+
<?php
25+
26+
class ExampleClass extends BaseExample implements ExampleInterface
27+
{
28+
private $self;
29+
30+
/** someMethod phpDoc */
31+
public function someMethod()
32+
{
33+
//code...
34+
}
35+
36+
public static function notConstructor(): SomeType
37+
{
38+
//code without 'self' return type
39+
}
40+
41+
final public static function staticConstructor(array $data): BaseExample
42+
{
43+
//return new self()
44+
}
45+
46+
/**
47+
* Static constructor with phpDoc
48+
*/
49+
public static function fromData(array $data): self
50+
{
51+
//return new self()
52+
}
53+
54+
public static function staticInterfaceConstructor(array $data): ExampleInterface
55+
{
56+
//return new self()
57+
}
58+
}
59+
60+
CODE;
61+
62+
$expected = <<<'CODE'
63+
<?php
64+
65+
class ExampleClass extends BaseExample implements ExampleInterface
66+
{
67+
68+
public static function notConstructor(): SomeType
69+
{
70+
//code without 'self' return type
71+
}
72+
73+
final public static function staticConstructor(array $data): BaseExample
74+
{
75+
//return new self()
76+
}
77+
78+
/**
79+
* Static constructor with phpDoc
80+
*/
81+
public static function fromData(array $data): self
82+
{
83+
//return new self()
84+
}
85+
86+
public static function staticInterfaceConstructor(array $data): ExampleInterface
87+
{
88+
//return new self()
89+
}
90+
private $self;
91+
92+
/** someMethod phpDoc */
93+
public function someMethod()
94+
{
95+
//code...
96+
}
97+
}
98+
99+
CODE;
100+
101+
$this->assertSame($expected, $this->runner->fix($code));
102+
}
103+
104+
public function testClassWithTestNameIsOrderedWithTestConfig()
105+
{
106+
$code = <<<'CODE'
107+
<?php
108+
109+
class ExampleClassTest extends BaseExample implements ExampleInterface
110+
{
111+
public static function notConstructor(): SomeType
112+
{
113+
//code without 'self' return type
114+
}
115+
116+
private $self;
117+
118+
/** someMethod phpDoc */
119+
public function someMethod()
120+
{
121+
//code...
122+
}
123+
124+
final public static function staticConstructor(array $data): BaseExample
125+
{
126+
//return new self()
127+
}
128+
129+
/**
130+
* Static constructor with phpDoc
131+
*/
132+
public static function fromData(array $data): self
133+
{
134+
//return new self()
135+
}
136+
137+
public static function staticInterfaceConstructor(array $data): ExampleInterface
138+
{
139+
//return new self()
140+
}
141+
}
142+
143+
CODE;
144+
145+
$expected = <<<'CODE'
146+
<?php
147+
148+
class ExampleClassTest extends BaseExample implements ExampleInterface
149+
{
150+
151+
private $self;
152+
153+
/** someMethod phpDoc */
154+
public function someMethod()
155+
{
156+
//code...
157+
}
158+
public static function notConstructor(): SomeType
159+
{
160+
//code without 'self' return type
161+
}
162+
163+
final public static function staticConstructor(array $data): BaseExample
164+
{
165+
//return new self()
166+
}
167+
168+
/**
169+
* Static constructor with phpDoc
170+
*/
171+
public static function fromData(array $data): self
172+
{
173+
//return new self()
174+
}
175+
176+
public static function staticInterfaceConstructor(array $data): ExampleInterface
177+
{
178+
//return new self()
179+
}
180+
}
181+
182+
CODE;
183+
184+
$this->assertSame($expected, $this->runner->fix($code));
185+
}
186+
187+
protected function fixer(): FixerInterface
188+
{
189+
$srcOrder = [
190+
'use_trait', 'case',
191+
'constant_public', 'constant_protected', 'constant_private',
192+
'property_public_static', 'property_protected_static', 'property_private_static',
193+
'method_public_static', 'method_protected_static', 'method_private_static',
194+
'property_public', 'property_protected', 'property_private',
195+
'construct', 'phpunit', 'magic', 'destruct',
196+
'method_public', 'method_protected', 'method_private'
197+
];
198+
199+
$testOrder = [
200+
'use_trait', 'case',
201+
'constant_public', 'constant_protected', 'constant_private',
202+
'property_public_static', 'property_protected_static', 'property_private_static',
203+
'property_public', 'property_protected', 'property_private',
204+
'construct', 'phpunit', 'magic', 'destruct',
205+
'method_public', 'method_protected', 'method_private',
206+
'method_public_static', 'method_protected_static', 'method_private_static'
207+
];
208+
209+
return new MultiOrderedClassElementsFixer($srcOrder, $testOrder);
210+
}
211+
212+
protected function properties(): array
213+
{
214+
return ['name' => 'Polymorphine/multi_ordered_class_elements', 'priority' => 65];
215+
}
216+
}

0 commit comments

Comments
 (0)