Skip to content

Commit 717d56a

Browse files
committed
[DX] Fix message on callable filter returns union or intersection
1 parent 4913af4 commit 717d56a

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/Assert/Filter.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
use Closure;
88
use InvalidArgumentException;
99
use ReflectionFunction;
10+
use ReflectionIntersectionType;
1011
use ReflectionMethod;
1112
use ReflectionNamedType;
13+
use ReflectionUnionType;
1214

15+
use function array_map;
1316
use function gettype;
17+
use function implode;
1418
use function is_object;
1519
use function sprintf;
1620

@@ -30,6 +34,19 @@ public static function boolean(callable $filter): void
3034

3135
$returnType = $reflection->getReturnType();
3236

37+
if ($returnType instanceof ReflectionUnionType || $returnType instanceof ReflectionIntersectionType) {
38+
$separator = $returnType instanceof ReflectionUnionType ? '|' : '&';
39+
throw new InvalidArgumentException(
40+
sprintf(
41+
'Expected a bool return type on callable filter, %s given',
42+
implode($separator, array_map(
43+
static fn (ReflectionNamedType $type): string => $type->getName(),
44+
$returnType->getTypes()
45+
))
46+
)
47+
);
48+
}
49+
3350
if (! $returnType instanceof ReflectionNamedType) {
3451
throw new InvalidArgumentException('Expected a bool return type on callable filter, null given');
3552
}

tests/FilterTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,37 @@ public function __invoke(int $datum): string
6868

6969
AtLeast::once($data, $filter);
7070
}
71+
72+
public function testWithUnionReturnTypeCallable(): void
73+
{
74+
$this->expectException(InvalidArgumentException::class);
75+
$this->expectExceptionMessage('Expected a bool return type on callable filter, string|bool given');
76+
77+
$data = [1, 2, 3];
78+
$filter = new class {
79+
public function __invoke(int $datum): string|bool
80+
{
81+
return 'test';
82+
}
83+
};
84+
85+
AtLeast::once($data, $filter);
86+
}
87+
88+
public function testWithIntersectionTypeCallable(): void
89+
{
90+
$this->expectException(InvalidArgumentException::class);
91+
$this->expectExceptionMessage(
92+
'Expected a bool return type on callable filter, ArrayLookup\Tests\A&ArrayLookup\Tests\B given'
93+
);
94+
95+
$data = [1, 2, 3];
96+
$filter = new class {
97+
public function __invoke(int $datum): A&B
98+
{
99+
}
100+
};
101+
102+
AtLeast::once($data, $filter);
103+
}
71104
}

0 commit comments

Comments
 (0)