Skip to content

Commit 8d50f6d

Browse files
committed
add filter validation
1 parent d0adef6 commit 8d50f6d

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/Assert/Filter.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ArrayLookup\Assert;
6+
7+
use InvalidArgumentException;
8+
use ReflectionFunction;
9+
use ReflectionMethod;
10+
use ReflectionNamedType;
11+
use TypeError;
12+
13+
use function sprintf;
14+
15+
final class Filter
16+
{
17+
public static function boolean(callable $filter): void
18+
{
19+
try {
20+
$reflection = new ReflectionFunction($filter);
21+
} catch (TypeError) {
22+
$reflection = new ReflectionMethod($filter, '__invoke');
23+
}
24+
25+
$returnType = $reflection->getReturnType();
26+
27+
if (! $returnType instanceof ReflectionNamedType) {
28+
throw new InvalidArgumentException('Expected a bool return type on callable filter, null given');
29+
}
30+
31+
$returnTypeName = $returnType->getName();
32+
if ($returnTypeName !== 'bool') {
33+
throw new InvalidArgumentException(sprintf(
34+
'Expected a bool return type on callable filter, %s given',
35+
$returnTypeName
36+
));
37+
}
38+
}
39+
}

tests/FilterTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ArrayLookup\Tests;
6+
7+
use ArrayLookup\AtLeast;
8+
use InvalidArgumentException;
9+
use PHPUnit\Framework\TestCase;
10+
11+
final class FilterTest extends TestCase
12+
{
13+
public function testOnceWithFilterInvokableClass(): void
14+
{
15+
$data = [1, 2, 3];
16+
$filter = new class {
17+
public function __invoke(int $datum): bool
18+
{
19+
return $datum === 1;
20+
}
21+
};
22+
23+
$this->assertTrue(AtLeast::once($data, $filter));
24+
}
25+
26+
public function testWithoutReturnTypeCallable(): void
27+
{
28+
$this->expectException(InvalidArgumentException::class);
29+
$this->expectExceptionMessage('Expected a bool return type on callable filter, null given');
30+
31+
$data = [1, 2, 3];
32+
33+
// phpcs:disable
34+
$filter = new class {
35+
public function __invoke(int $datum)
36+
{
37+
return $datum === 1;
38+
}
39+
};
40+
// phpcs:enable
41+
42+
$this->assertTrue(AtLeast::once($data, $filter));
43+
}
44+
45+
public function testWithNonBoolReturnTypeCallable(): void
46+
{
47+
$this->expectException(InvalidArgumentException::class);
48+
$this->expectExceptionMessage('Expected a bool return type on callable filter, string given');
49+
50+
$data = [1, 2, 3];
51+
$filter = new class {
52+
public function __invoke(int $datum): string
53+
{
54+
return 'test';
55+
}
56+
};
57+
58+
$this->assertTrue(AtLeast::once($data, $filter));
59+
}
60+
}

0 commit comments

Comments
 (0)