Skip to content

Commit

Permalink
Fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 31, 2023
1 parent 87516ff commit 75f87d4
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 41 deletions.
7 changes: 4 additions & 3 deletions src/PhpDoc/PHPUnit/MockObjectTypeNodeResolverExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
use PHPStan\Type\NeverType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use function array_key_exists;
use function count;

class MockObjectTypeNodeResolverExtension implements TypeNodeResolverExtension, TypeNodeResolverAwareExtension
{
Expand Down Expand Up @@ -44,11 +44,12 @@ public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type

$types = $this->typeNodeResolver->resolveMultiple($typeNode->types, $nameScope);
foreach ($types as $type) {
if (!$type instanceof TypeWithClassName) {
$classNames = $type->getObjectClassNames();
if (count($classNames) !== 1) {
continue;
}

if (array_key_exists($type->getClassName(), $mockClassNames)) {
if (array_key_exists($classNames[0], $mockClassNames)) {
$resultType = TypeCombinator::intersect(...$types);
if ($resultType instanceof NeverType) {
continue;
Expand Down
74 changes: 38 additions & 36 deletions src/Rules/PHPUnit/MockMethodCallRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\ObjectType;
Expand Down Expand Up @@ -44,53 +43,56 @@ public function processNode(Node $node, Scope $scope): array
}

$argType = $scope->getType($node->getArgs()[0]->value);
if (!($argType instanceof ConstantStringType)) {
if (count($argType->getConstantStrings()) === 0) {
return [];
}

$method = $argType->getValue();
$type = $scope->getType($node->var);

if (
$type instanceof IntersectionType
&& (
in_array(MockObject::class, $type->getReferencedClasses(), true)
|| in_array(Stub::class, $type->getReferencedClasses(), true)
)
&& !$type->hasMethod($method)->yes()
) {
$mockClass = array_filter($type->getReferencedClasses(), static function (string $class): bool {
return $class !== MockObject::class && $class !== Stub::class;
});

return [
sprintf(
$errors = [];
foreach ($argType->getConstantStrings() as $constantString) {
$method = $constantString->getValue();
$type = $scope->getType($node->var);

if (
$type instanceof IntersectionType
&& (
in_array(MockObject::class, $type->getObjectClassNames(), true)
|| in_array(Stub::class, $type->getObjectClassNames(), true)
)
&& !$type->hasMethod($method)->yes()
) {
$mockClass = array_filter($type->getObjectClassNames(), static function (string $class): bool {
return $class !== MockObject::class && $class !== Stub::class;
});

$errors[] = sprintf(
'Trying to mock an undefined method %s() on class %s.',
$method,
implode('&', $mockClass)
),
];
}
);
}

if (
!($type instanceof GenericObjectType)
|| $type->getClassName() !== InvocationMocker::class
|| count($type->getTypes()) <= 0
) {
continue;
}

if (
$type instanceof GenericObjectType
&& $type->getClassName() === InvocationMocker::class
&& count($type->getTypes()) > 0
) {
$mockClass = $type->getTypes()[0];

if ($mockClass instanceof ObjectType && !$mockClass->hasMethod($method)->yes()) {
return [
sprintf(
'Trying to mock an undefined method %s() on class %s.',
$method,
$mockClass->getClassName()
),
];
if (!($mockClass instanceof ObjectType) || $mockClass->hasMethod($method)->yes()) {
continue;
}

$errors[] = sprintf(
'Trying to mock an undefined method %s() on class %s.',
$method,
$mockClass->getClassName()
);
}

return [];
return $errors;
}

}
8 changes: 6 additions & 2 deletions src/Type/PHPUnit/MockObjectDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use PHPStan\Type\IntersectionType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
use PHPUnit\Framework\MockObject\MockObject;
use function array_filter;
Expand Down Expand Up @@ -38,7 +37,12 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
}

$mockClasses = array_values(array_filter($type->getTypes(), static function (Type $type): bool {
return !$type instanceof TypeWithClassName || $type->getClassName() !== MockObject::class;
$classNames = $type->getObjectClassNames();
if (count($classNames) !== 1) {
return true;
}

return $classNames[0] !== MockObject::class;
}));

if (count($mockClasses) !== 1) {
Expand Down

0 comments on commit 75f87d4

Please sign in to comment.