Skip to content

Commit 756c783

Browse files
vhenzlondrejmirtes
authored andcommitted
Add tests for EntityManagerFindDynamicReturnTypeExtension
1 parent 64f1284 commit 756c783

File tree

1 file changed

+247
-0
lines changed

1 file changed

+247
-0
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Tests\PHPStan\Type\Doctrine;
4+
5+
use PHPStan\Analyser\Scope;
6+
use PHPStan\Reflection\ClassReflection;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Type\Doctrine\EntityManagerFindDynamicReturnTypeExtension;
9+
use PHPStan\Type\ObjectWithoutClassType;
10+
use PHPUnit\Framework\TestCase;
11+
12+
final class EntityManagerFindDynamicReturnTypeExtensionTest extends TestCase
13+
{
14+
15+
const ENTITY_CLASS_NAME = '\\Foo\\Bar';
16+
17+
/** @var \PHPStan\Type\Doctrine\EntityManagerFindDynamicReturnTypeExtension */
18+
private $extension;
19+
20+
protected function setUp()
21+
{
22+
$this->extension = new EntityManagerFindDynamicReturnTypeExtension();
23+
}
24+
25+
/**
26+
* @return mixed[]
27+
*/
28+
public function dataIsMethodSupported(): array
29+
{
30+
return [
31+
['find', true],
32+
['getReference', true],
33+
['getPartialReference', true],
34+
['copy', false],
35+
['foo', false],
36+
];
37+
}
38+
39+
/**
40+
* @dataProvider dataIsMethodSupported
41+
* @param string $method
42+
* @param bool $expectedResult
43+
*/
44+
public function testIsMethodSupported(string $method, bool $expectedResult)
45+
{
46+
$methodReflection = $this->createMock(MethodReflection::class);
47+
$methodReflection->method('getName')->willReturn($method);
48+
$this->assertSame($expectedResult, $this->extension->isMethodSupported($methodReflection));
49+
}
50+
51+
/**
52+
* @return mixed[]
53+
*/
54+
public function dataGetTypeFromMethodCallWithClassConstFetch(): array
55+
{
56+
return [
57+
[
58+
'\Foo\Bar',
59+
'find',
60+
'\Foo\Bar|null',
61+
],
62+
[
63+
'self',
64+
'find',
65+
'\Foo\Bar|null',
66+
],
67+
[
68+
'static',
69+
'find',
70+
'mixed',
71+
],
72+
[
73+
'\Foo\Bar',
74+
'getReference',
75+
'\Foo\Bar',
76+
],
77+
[
78+
'self',
79+
'getReference',
80+
'\Foo\Bar',
81+
],
82+
[
83+
'static',
84+
'getReference',
85+
'mixed',
86+
],
87+
[
88+
'\Foo\Bar',
89+
'getPartialReference',
90+
'\Foo\Bar',
91+
],
92+
[
93+
'self',
94+
'getPartialReference',
95+
'\Foo\Bar',
96+
],
97+
[
98+
'static',
99+
'getPartialReference',
100+
'mixed',
101+
],
102+
];
103+
}
104+
105+
/**
106+
* @dataProvider dataGetTypeFromMethodCallWithClassConstFetch
107+
* @param string $entityClassName
108+
* @param string $method
109+
* @param string $expectedTypeDescription
110+
*/
111+
public function testGetTypeFromMethodCallWithClassConstFetch(
112+
string $entityClassName,
113+
string $method,
114+
string $expectedTypeDescription
115+
)
116+
{
117+
$methodReflection = $this->mockMethodReflection($method);
118+
$scope = $this->mockScope();
119+
$methodCall = $this->mockMethodCallWithClassConstFetch($entityClassName);
120+
121+
$resultType = $this->extension->getTypeFromMethodCall($methodReflection, $methodCall, $scope);
122+
123+
$this->assertSame($expectedTypeDescription, $resultType->describe());
124+
}
125+
126+
/**
127+
* @return mixed[]
128+
*/
129+
public function dataGetTypeFromMethodCallWithScalarString(): array
130+
{
131+
return [
132+
[
133+
self::ENTITY_CLASS_NAME,
134+
'find',
135+
'mixed',
136+
],
137+
[
138+
'self',
139+
'find',
140+
'mixed',
141+
],
142+
[
143+
'static',
144+
'find',
145+
'mixed',
146+
],
147+
[
148+
self::ENTITY_CLASS_NAME,
149+
'getReference',
150+
'mixed',
151+
],
152+
[
153+
'self',
154+
'getReference',
155+
'mixed',
156+
],
157+
[
158+
'static',
159+
'getReference',
160+
'mixed',
161+
],
162+
[
163+
self::ENTITY_CLASS_NAME,
164+
'getPartialReference',
165+
'mixed',
166+
],
167+
[
168+
'self',
169+
'getPartialReference',
170+
'mixed',
171+
],
172+
[
173+
'static',
174+
'getPartialReference',
175+
'mixed',
176+
],
177+
];
178+
}
179+
180+
/**
181+
* @dataProvider dataGetTypeFromMethodCallWithScalarString
182+
* @param string $entityClassName
183+
* @param string $method
184+
* @param string $expectedTypeDescription
185+
*/
186+
public function testGetTypeFromMethodCallWithScalarString(
187+
string $entityClassName,
188+
string $method,
189+
string $expectedTypeDescription
190+
)
191+
{
192+
$methodReflection = $this->mockMethodReflection($method);
193+
$scope = $this->mockScope();
194+
$methodCall = $this->mockMethodCallWithScalarString($entityClassName);
195+
196+
$resultType = $this->extension->getTypeFromMethodCall($methodReflection, $methodCall, $scope);
197+
198+
$this->assertSame($expectedTypeDescription, $resultType->describe());
199+
}
200+
201+
private function mockMethodReflection(string $method): MethodReflection
202+
{
203+
$methodReflection = $this->createMock(MethodReflection::class);
204+
$methodReflection->method('getReturnType')->willReturn(new ObjectWithoutClassType());
205+
$methodReflection->method('getName')->willReturn($method);
206+
return $methodReflection;
207+
}
208+
209+
private function mockScope(): Scope
210+
{
211+
$scope = $this->createMock(Scope::class);
212+
$scope->method('getClassReflection')->willReturnCallback(
213+
function (): ClassReflection {
214+
$classReflection = $this->createMock(ClassReflection::class);
215+
$classReflection->method('getName')->willReturn(self::ENTITY_CLASS_NAME);
216+
return $classReflection;
217+
}
218+
);
219+
return $scope;
220+
}
221+
222+
private function mockMethodCallWithClassConstFetch(string $entityClassName): \PhpParser\Node\Expr\MethodCall
223+
{
224+
$class = new \PhpParser\Node\Name($entityClassName);
225+
$value = new \PhpParser\Node\Expr\ClassConstFetch($class, 'class');
226+
$arg = new \PhpParser\Node\Arg($value);
227+
228+
$methodCall = $this->createMock(\PhpParser\Node\Expr\MethodCall::class);
229+
$methodCall->args = [
230+
0 => $arg,
231+
];
232+
return $methodCall;
233+
}
234+
235+
private function mockMethodCallWithScalarString(string $entityClassName): \PhpParser\Node\Expr\MethodCall
236+
{
237+
$value = new \PhpParser\Node\Scalar\String_($entityClassName);
238+
$arg = new \PhpParser\Node\Arg($value);
239+
240+
$methodCall = $this->createMock(\PhpParser\Node\Expr\MethodCall::class);
241+
$methodCall->args = [
242+
0 => $arg,
243+
];
244+
return $methodCall;
245+
}
246+
247+
}

0 commit comments

Comments
 (0)