Skip to content

Commit 128b634

Browse files
committed
improve validated callable support
1 parent d37cdef commit 128b634

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

src/functions.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@
3838
use Iterator;
3939
use LogicException;
4040
use ReflectionAttribute;
41+
use ReflectionClass;
4142
use ReflectionFunction;
4243
use ReflectionMethod;
44+
use ReflectionObject;
4345
use ReflectionParameter;
4446
use ReflectionProperty;
4547
use SebastianBergmann\Type\Parameter;
@@ -533,8 +535,13 @@ function reflectedParameterAttribute(
533535

534536
function validated(callable $callable, mixed ...$args): mixed
535537
{
536-
// @phpstan-ignore-next-line
537-
$reflection = new ReflectionFunction($callable);
538+
$reflection = match (true) {
539+
is_object($callable) => (new ReflectionObject($callable))->getMethod('__invoke'),
540+
// @phpstan-ignore-next-line
541+
is_array($callable) => (new ReflectionClass($callable[0]))->getMethod($callable[1]),
542+
// @phpstan-ignore-next-line
543+
default => new ReflectionFunction($callable),
544+
};
538545

539546
try {
540547
$parameters = reflectionToParameters($reflection);
@@ -564,7 +571,7 @@ function validated(callable $callable, mixed ...$args): mixed
564571
/**
565572
* @return array{0: string, 1: Throwable, 2: string, 3: int}
566573
*/
567-
function getExceptionArguments(Throwable $e, ReflectionFunction $reflection): array
574+
function getExceptionArguments(Throwable $e, ReflectionFunction|ReflectionMethod $reflection): array
568575
{
569576
// @infection-ignore-all
570577
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];

tests/FunctionsTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
namespace Chevere\Tests;
1515

1616
use BadMethodCallException;
17+
use Chevere\Parameter\Attributes\_int;
1718
use Chevere\Parameter\Exceptions\ParameterException;
1819
use Chevere\Parameter\Exceptions\ReturnException;
1920
use Chevere\Parameter\Interfaces\ParametersAccessInterface;
2021
use Chevere\Parameter\Interfaces\ParametersInterface;
22+
use Chevere\Tests\src\CallableClassMethod;
2123
use InvalidArgumentException;
2224
use LogicException;
2325
use OutOfBoundsException;
@@ -480,6 +482,41 @@ public function testValidatedFunction(): void
480482
validated($function, 100, 1, 'Test'); // base, times, name
481483
}
482484

485+
public static function dataProviderValidatedCallables(): array
486+
{
487+
$object = new class() {
488+
public function main(#[_int(min: 10)] int $base): void
489+
{
490+
}
491+
};
492+
493+
return [
494+
[
495+
fn (#[_int(min: 10)] int $base) => null,
496+
],
497+
['Chevere\Tests\src\intMin10'],
498+
[[CallableClassMethod::class, 'main']],
499+
[[$object, 'main']],
500+
[new class() {
501+
public function __invoke(#[_int(min: 10)] int $base): void
502+
{
503+
}
504+
}],
505+
];
506+
}
507+
508+
#[DataProvider('dataProviderValidatedCallables')]
509+
public function testValidatedCallables(callable $callable): void
510+
{
511+
$this->expectException(ParameterException::class);
512+
$this->expectExceptionMessage(
513+
<<<PLAIN
514+
InvalidArgumentException → [base]: Argument value provided `9` is less than `10`
515+
PLAIN
516+
);
517+
validated($callable, 9);
518+
}
519+
483520
#[DataProvider('dataProviderValMd')]
484521
public function testValMd(mixed $value, string $expects): void
485522
{

tests/src/CallableClassMethod.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Chevere.
5+
*
6+
* (c) Rodolfo Berrios <rodolfo@chevere.org>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Chevere\Tests\src;
15+
16+
use Chevere\Parameter\Attributes\_int;
17+
18+
class CallableClassMethod
19+
{
20+
public static function main(#[_int(min: 10)] int $base): void
21+
{
22+
}
23+
}

tests/src/functions.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,9 @@ function usesSensitiveParameterAttr(
8383
): void {
8484
assertArguments();
8585
}
86+
87+
function intMin10(
88+
#[_int(min: 10)]
89+
int $base
90+
): void {
91+
}

0 commit comments

Comments
 (0)