/
InterfaceAncestorsRuleTest.php
210 lines (202 loc) · 8.66 KB
/
InterfaceAncestorsRuleTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?php declare(strict_types = 1);
namespace PHPStan\Rules\Generics;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
/**
* @extends RuleTestCase<InterfaceAncestorsRule>
*/
class InterfaceAncestorsRuleTest extends RuleTestCase
{
protected function getRule(): Rule
{
return new InterfaceAncestorsRule(
new GenericAncestorsCheck(
$this->createReflectionProvider(),
new GenericObjectTypeCheck(),
new VarianceCheck(true),
true,
[],
),
new CrossCheckInterfacesHelper(),
);
}
public function testRuleImplements(): void
{
$this->analyse([__DIR__ . '/data/interface-ancestors-implements.php'], [
[
'Interface InterfaceAncestorsImplements\FooDoesNotImplementAnything has @implements tag, but can not implement any interface, must extend from it.',
35,
],
[
'Interface InterfaceAncestorsImplements\FooInvalidImplementsTags has @implements tag, but can not implement any interface, must extend from it.',
44,
],
[
'Interface InterfaceAncestorsImplements\FooInvalidImplementsTags has @implements tag, but can not implement any interface, must extend from it.',
44,
],
[
'Interface InterfaceAncestorsImplements\FooWrongClassImplemented has @implements tag, but can not implement any interface, must extend from it.',
52,
],
[
'Interface InterfaceAncestorsImplements\FooWrongTypeInImplementsTag @implements tag contains incompatible type class-string<InterfaceAncestorsImplements\T>.',
60,
],
[
'Interface InterfaceAncestorsImplements\FooCorrect has @implements tag, but can not implement any interface, must extend from it.',
68,
],
[
'Interface InterfaceAncestorsImplements\FooNotEnough has @implements tag, but can not implement any interface, must extend from it.',
76,
],
[
'Interface InterfaceAncestorsImplements\FooExtraTypes has @implements tag, but can not implement any interface, must extend from it.',
84,
],
[
'Interface InterfaceAncestorsImplements\FooNotSubtype has @implements tag, but can not implement any interface, must extend from it.',
92,
],
[
'Interface InterfaceAncestorsImplements\FooAlsoNotSubtype has @implements tag, but can not implement any interface, must extend from it.',
100,
],
[
'Interface InterfaceAncestorsImplements\FooUnknownClass has @implements tag, but can not implement any interface, must extend from it.',
108,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric has @implements tag, but can not implement any interface, must extend from it.',
117,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric2 has @implements tag, but can not implement any interface, must extend from it.',
126,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric3 has @implements tag, but can not implement any interface, must extend from it.',
136,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric4 has @implements tag, but can not implement any interface, must extend from it.',
145,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric5 has @implements tag, but can not implement any interface, must extend from it.',
154,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric6 has @implements tag, but can not implement any interface, must extend from it.',
163,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric7 has @implements tag, but can not implement any interface, must extend from it.',
172,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric8 has @implements tag, but can not implement any interface, must extend from it.',
182,
],
[
'Interface InterfaceAncestorsImplements\FooGenericGeneric8 has @implements tag, but can not implement any interface, must extend from it.',
182,
],
]);
}
public function testRuleExtends(): void
{
$this->analyse([__DIR__ . '/data/interface-ancestors-extends.php'], [
[
'Interface InterfaceAncestorsExtends\FooDoesNotImplementAnything has @extends tag, but does not extend any interface.',
35,
],
[
'The @extends tag of interface InterfaceAncestorsExtends\FooInvalidImplementsTags describes InterfaceAncestorsExtends\FooGeneric2 but the interface extends: InterfaceAncestorsExtends\FooGeneric',
44,
],
[
'The @extends tag of interface InterfaceAncestorsExtends\FooWrongClassImplemented describes InterfaceAncestorsExtends\FooGeneric2 but the interface extends: InterfaceAncestorsExtends\FooGeneric, InterfaceAncestorsExtends\FooGeneric3',
52,
],
[
'Interface InterfaceAncestorsExtends\FooWrongClassImplemented extends generic interface InterfaceAncestorsExtends\FooGeneric but does not specify its types: T, U',
52,
'You can turn this off by setting <fg=cyan>checkGenericClassInNonGenericObjectType: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Interface InterfaceAncestorsExtends\FooWrongClassImplemented extends generic interface InterfaceAncestorsExtends\FooGeneric3 but does not specify its types: T, W',
52,
'You can turn this off by setting <fg=cyan>checkGenericClassInNonGenericObjectType: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Interface InterfaceAncestorsExtends\FooWrongTypeInImplementsTag @extends tag contains incompatible type class-string<InterfaceAncestorsExtends\T>.',
60,
],
[
'Interface InterfaceAncestorsExtends\FooWrongTypeInImplementsTag extends generic interface InterfaceAncestorsExtends\FooGeneric but does not specify its types: T, U',
60,
'You can turn this off by setting <fg=cyan>checkGenericClassInNonGenericObjectType: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Generic type InterfaceAncestorsExtends\FooGeneric<int> in PHPDoc tag @extends does not specify all template types of interface InterfaceAncestorsExtends\FooGeneric: T, U',
76,
],
[
'Generic type InterfaceAncestorsExtends\FooGeneric<int, InvalidArgumentException, string> in PHPDoc tag @extends specifies 3 template types, but interface InterfaceAncestorsExtends\FooGeneric supports only 2: T, U',
84,
],
[
'Type Throwable in generic type InterfaceAncestorsExtends\FooGeneric<int, Throwable> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
92,
],
[
'Type stdClass in generic type InterfaceAncestorsExtends\FooGeneric<int, stdClass> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
100,
],
[
'PHPDoc tag @extends has invalid type InterfaceAncestorsExtends\Zazzuuuu.',
108,
],
[
'Type mixed in generic type InterfaceAncestorsExtends\FooGeneric<int, mixed> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
117,
],
[
'Type Throwable in generic type InterfaceAncestorsExtends\FooGeneric<int, Throwable> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
126,
],
[
'Type stdClass in generic type InterfaceAncestorsExtends\FooGeneric<int, stdClass> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
172,
],
[
'Type stdClass in generic type InterfaceAncestorsExtends\FooGeneric<int, stdClass> in PHPDoc tag @extends is not subtype of template type U of Exception of interface InterfaceAncestorsExtends\FooGeneric.',
182,
],
[
'Type stdClass in generic type InterfaceAncestorsExtends\FooGeneric2<int, stdClass> in PHPDoc tag @extends is not subtype of template type V of Exception of interface InterfaceAncestorsExtends\FooGeneric2.',
182,
],
[
'Interface InterfaceAncestorsExtends\ExtendsGenericInterface extends generic interface InterfaceAncestorsExtends\FooGeneric but does not specify its types: T, U',
197,
'You can turn this off by setting <fg=cyan>checkGenericClassInNonGenericObjectType: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Template type T is declared as covariant, but occurs in invariant position in extended type InterfaceAncestorsExtends\FooGeneric9<T, T> of interface InterfaceAncestorsExtends\FooGeneric10.',
215,
],
]);
}
public function testCrossCheckInterfaces(): void
{
$this->analyse([__DIR__ . '/data/cross-check-interfaces-interfaces.php'], [
[
'Interface IteratorAggregate specifies template type TValue of interface Traversable as string but it\'s already specified as CrossCheckInterfacesInInterfaces\Item.',
19,
],
]);
}
}