Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5c52578

Browse files
committed
Support string arguments
1 parent a773786 commit 5c52578

File tree

5 files changed

+254
-12
lines changed

5 files changed

+254
-12
lines changed

‎src/Type/PHPUnit/CreateMockDynamicReturnTypeExtension.php‎

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node\Expr\MethodCall;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Type\Constant\ConstantStringType;
89
use PHPStan\Type\ObjectType;
910
use PHPStan\Type\Type;
1011
use PHPStan\Type\TypeCombinator;
@@ -38,26 +39,17 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
3839
if (!isset($methodCall->args[$argumentIndex])) {
3940
return $methodReflection->getReturnType();
4041
}
41-
$arg = $methodCall->args[$argumentIndex]->value;
42-
if (!($arg instanceof \PhpParser\Node\Expr\ClassConstFetch)) {
42+
$argType = $scope->getType($methodCall->args[$argumentIndex]->value);
43+
if (!$argType instanceof ConstantStringType) {
4344
return $methodReflection->getReturnType();
4445
}
4546

46-
$class = $arg->class;
47-
if (!($class instanceof \PhpParser\Node\Name)) {
48-
return $methodReflection->getReturnType();
49-
}
50-
51-
$class = (string) $class;
47+
$class = $argType->getValue();
5248

5349
if ($class === 'static') {
5450
return $methodReflection->getReturnType();
5551
}
5652

57-
if ($class === 'self') {
58-
$class = $scope->getClassReflection()->getName();
59-
}
60-
6153
return TypeCombinator::intersect(
6254
new ObjectType($class),
6355
$methodReflection->getReturnType()
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\PHPUnit;
4+
5+
class CreateMockDynamicReturnTypeExtensionTest extends \PHPStan\Type\PHPUnit\ExtensionTestCase
6+
{
7+
8+
public function createMockProvider(): array
9+
{
10+
return [
11+
[
12+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
13+
'$a',
14+
],
15+
[
16+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
17+
'$b',
18+
],
19+
[
20+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
21+
'$c',
22+
],
23+
[
24+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
25+
'$d',
26+
],
27+
[
28+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
29+
'$e',
30+
],
31+
[
32+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
33+
'$f',
34+
],
35+
[
36+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
37+
'$g',
38+
],
39+
[
40+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
41+
'$h',
42+
],
43+
[
44+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
45+
'$i',
46+
],
47+
[
48+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
49+
'$j',
50+
],
51+
[
52+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
53+
'$k',
54+
],
55+
[
56+
'CreateMockTest\MockedClass&PHPUnit\Framework\MockObject\MockObject',
57+
'$l',
58+
],
59+
[
60+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
61+
'$m',
62+
],
63+
[
64+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
65+
'$n',
66+
],
67+
[
68+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
69+
'$o',
70+
],
71+
[
72+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
73+
'$p',
74+
],
75+
[
76+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
77+
'$q',
78+
],
79+
[
80+
'CreateMockTest\TestClass&PHPUnit\Framework\MockObject\MockObject',
81+
'$r',
82+
],
83+
[
84+
'PHPUnit\Framework\MockObject\MockObject',
85+
'$s',
86+
],
87+
[
88+
'PHPUnit\Framework\MockObject\MockObject',
89+
'$t',
90+
],
91+
[
92+
'PHPUnit\Framework\MockObject\MockObject',
93+
'$u',
94+
],
95+
[
96+
'PHPUnit\Framework\MockObject\MockObject',
97+
'$v',
98+
],
99+
[
100+
'PHPUnit\Framework\MockObject\MockObject',
101+
'$w',
102+
],
103+
[
104+
'PHPUnit\Framework\MockObject\MockObject',
105+
'$x',
106+
],
107+
];
108+
}
109+
110+
/**
111+
* @dataProvider createMockProvider
112+
* @param string $description
113+
* @param string $expression
114+
*/
115+
public function testCreateMock(string $description, string $expression): void
116+
{
117+
$this->assertTypes(
118+
__DIR__ . '/data/TestClass.php',
119+
$description,
120+
$expression,
121+
[new CreateMockDynamicReturnTypeExtension()]
122+
);
123+
}
124+
125+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\PHPUnit;
4+
5+
use PHPStan\Analyser\NodeScopeResolver;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Analyser\TypeSpecifier;
8+
use PHPStan\Cache\Cache;
9+
use PHPStan\File\FileHelper;
10+
use PHPStan\PhpDoc\PhpDocStringResolver;
11+
use PHPStan\Testing\TestCase;
12+
use PHPStan\Type\FileTypeMapper;
13+
14+
abstract class ExtensionTestCase extends TestCase
15+
{
16+
17+
protected function assertTypes(
18+
string $file,
19+
string $description,
20+
string $expression,
21+
array $dynamicMethodReturnTypeExtensions = [],
22+
array $dynamicStaticMethodReturnTypeExtensions = [],
23+
string $evaluatedPointExpression = 'die;'
24+
): void
25+
{
26+
$this->processFile($file, function (\PhpParser\Node $node, Scope $scope) use ($description, $expression, $evaluatedPointExpression): void {
27+
$printer = new \PhpParser\PrettyPrinter\Standard();
28+
$printedNode = $printer->prettyPrint([$node]);
29+
if ($printedNode === $evaluatedPointExpression) {
30+
/** @var \PhpParser\Node\Expr $expressionNode */
31+
$expressionNode = $this->getParser()->parseString(sprintf('<?php %s;', $expression))[0];
32+
$type = $scope->getType($expressionNode);
33+
$this->assertTypeDescribe(
34+
$description,
35+
$type->describe(),
36+
sprintf('%s at %s', $expression, $evaluatedPointExpression)
37+
);
38+
}
39+
}, $dynamicMethodReturnTypeExtensions, $dynamicStaticMethodReturnTypeExtensions);
40+
}
41+
42+
protected function processFile(string $file, \Closure $callback, array $dynamicMethodReturnTypeExtensions = [], array $dynamicStaticMethodReturnTypeExtensions = []): void
43+
{
44+
/** @var \PHPStan\PhpDoc\PhpDocStringResolver $phpDocStringResolver */
45+
$phpDocStringResolver = $this->getContainer()->getByType(PhpDocStringResolver::class);
46+
47+
$printer = new \PhpParser\PrettyPrinter\Standard();
48+
$resolver = new NodeScopeResolver(
49+
$this->createBroker(),
50+
$this->getParser(),
51+
$printer,
52+
new FileTypeMapper($this->getParser(), $phpDocStringResolver, $this->createMock(Cache::class)),
53+
new FileHelper('/'),
54+
true,
55+
true,
56+
[]
57+
);
58+
$resolver->processNodes(
59+
$this->getParser()->parseFile($file),
60+
new Scope(
61+
$this->createBroker($dynamicMethodReturnTypeExtensions, $dynamicStaticMethodReturnTypeExtensions),
62+
$printer,
63+
new TypeSpecifier($printer),
64+
$file
65+
),
66+
$callback
67+
);
68+
}
69+
70+
protected function assertTypeDescribe(string $expectedDescription, string $actualDescription, string $label = ''): void
71+
{
72+
self::assertSame(
73+
$expectedDescription,
74+
$actualDescription,
75+
$label
76+
);
77+
}
78+
79+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace CreateMockTest;
4+
5+
class MockedClass
6+
{
7+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace CreateMockTest;
4+
5+
class TestClass extends \PHPStan\Testing\TestCase
6+
{
7+
public function doMocks()
8+
{
9+
$a = $this->createMock(MockedClass::class);
10+
$b = $this->createConfiguredMock(MockedClass::class, []);
11+
$c = $this->createPartialMock(MockedClass::class, []);
12+
$d = $this->createTestProxy(MockedClass::class);
13+
$e = $this->getMockForAbstractClass(MockedClass::class);
14+
$f = $this->getMockFromWsdl('', MockedClass::class);
15+
16+
$g = $this->createMock('CreateMockTest\MockedClass');
17+
$h = $this->createConfiguredMock('CreateMockTest\MockedClass', []);
18+
$i = $this->createPartialMock('CreateMockTest\MockedClass', []);
19+
$j = $this->createTestProxy('CreateMockTest\MockedClass');
20+
$k = $this->getMockForAbstractClass('CreateMockTest\MockedClass');
21+
$l = $this->getMockFromWsdl('', 'CreateMockTest\MockedClass');
22+
23+
$m = $this->createMock(self::class);
24+
$n = $this->createConfiguredMock(self::class);
25+
$o = $this->createPartialMock(self::class);
26+
$p = $this->createTestProxy(self::class);
27+
$q = $this->getMockForAbstractClass(self::class);
28+
$r = $this->getMockFromWsdl('', self::class);
29+
30+
$s = $this->createMock(static::class);
31+
$t = $this->createConfiguredMock(static::class);
32+
$u = $this->createPartialMock(static::class);
33+
$v = $this->createTestProxy(static::class);
34+
$w = $this->getMockForAbstractClass(static::class);
35+
$x = $this->getMockFromWsdl('', static::class);
36+
37+
die;
38+
}
39+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /