1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 12:55:26 +01:00
psalm/tests/IntersectionTypeTest.php
Maximilian Bösing 6c58d98d67
feature: treat class-string<callable> as callable-object
Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>
2023-04-04 17:28:58 +02:00

195 lines
7.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Psalm\Tests;
use Psalm\Tests\Traits\InvalidCodeAnalysisTestTrait;
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;
final class IntersectionTypeTest extends TestCase
{
use ValidCodeAnalysisTestTrait;
use InvalidCodeAnalysisTestTrait;
public function providerValidCodeParse(): iterable
{
return [
'callableObject' => [
'code' => '<?php
/**
* @param object&callable():void $object
*/
function takesCallableObject(object $object): void {
$object();
}
',
],
'classStringOfCallableObject' => [
'code' => '<?php
/**
* @param class-string<object&callable():void> $className
*/
function takesCallableObject(string $className): void {
$object = new $className();
$object();
}',
'assertions' => [],
'ignored_issues' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'callableObjectWithRequiredStringArgument' => [
'code' => '<?php
/**
* @param object&callable(string):void $object
*/
function takesCallableObject(object $object): void {
$object("foo");
}
',
],
'classStringOfCallableObjectWithRequiredStringArgument' => [
'code' => '<?php
/**
* @param class-string<object&callable(string):void> $className
*/
function takesCallableObject(string $className): void {
$object = new $className();
$object("foo");
}',
'assertions' => [],
'ignored_issues' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'callableObjectWithReturnType' => [
'code' => '<?php
/**
* @param object&callable():int $object
*/
function takesCallableObject(object $object): int {
return $object();
}
',
],
'classStringOfCallableObjectWithReturnType' => [
'code' => '<?php
/**
* @param class-string<object&callable():int> $className
*/
function takesCallableObject(string $className): int {
$object = new $className();
return $object();
}
class Foo
{
public function __invoke(): int
{
return 0;
}
}
takesCallableObject(Foo::class);
',
'assertions' => [],
'ignored_issues' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'classStringOfCallableWillBeTreatedAsCallableObject' => [
'code' => '<?php
/**
* @param class-string<callable():int> $className
*/
function takesCallableObject(string $className): int {
$object = new $className();
return $object();
}
class Foo
{
public function __invoke(): int
{
return 0;
}
}
takesCallableObject(Foo::class);
',
'assertions' => [],
'ignored_issues' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
];
}
public function providerInvalidCodeParse(): iterable
{
return [
'callableObjectWithMissingStringArgument' => [
'code' => '<?php
/**
* @param object&callable(string):void $object
*/
function takesCallableObject(object $object): void {
$object();
}
',
'error_message' => 'TooFewArguments',
],
'classStringOfCallableObjectWithMissingRequiredStringArgument' => [
'code' => '<?php
/**
* @param class-string<object&callable(string):void> $className
*/
function takesCallableObject(string $className): void {
$object = new $className();
$object();
}',
'error_message' => 'TooFewArguments',
'error_levels' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'callableObjectWithInvalidStringArgument' => [
'code' => '<?php
/**
* @param object&callable(string):void $object
*/
function takesCallableObject(object $object): void {
$object(true);
}
',
'error_message' => 'InvalidArgument',
'error_levels' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'classStringOfCallableObjectWithInvalidStringArgument' => [
'code' => '<?php
/**
* @param class-string<object&callable(string):void> $className
*/
function takesCallableObject(string $className): void {
$object = new $className();
$object(0);
}',
'error_message' => 'InvalidArgument',
'error_levels' => ['UnsafeInstantiation', 'MixedMethodCall'],
],
'classStringOfCallableObjectWillTriggerMixedMethodCall' => [
'code' => '<?php
/**
* @param class-string<object&callable> $className
*/
function takesCallableObject(string $className): void {
new $className();
}
class Foo
{
public function __invoke(): int
{
return 0;
}
}
takesCallableObject(Foo::class);
',
'error_message' => 'MixedMethodCall',
],
];
}
}