Remove deprecated reflection from MixedArgumentOrganiser
MODIFY
src/Behat/Testwork/Argument/MixedArgumentOrganiser.php
src/Behat/Testwork/Argument/MixedArgumentOrganiser.php
@@ -131,17 +131,14 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
/**
* Checks if value matches typehint of provided parameter.
- *
- * @param object $value
- * @param ReflectionParameter $parameter
- *
- * @return bool
*/
- private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter)
+ private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter) : bool
{
- $typehintRefl = $parameter->getClass();
+ if ($typehintRefl = $this->getReflectionClassFromParameter($parameter)) {
+ return $typehintRefl->isInstance($value);
+ }
- return $typehintRefl && $typehintRefl->isInstance($value);
+ return false;
}
/**
@@ -217,29 +214,36 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
* @param ReflectionParameter[] $parameters Constructor Arguments
* @return ReflectionParameter[] Filtered $parameters
*/
- private function filterApplicableTypehintedParameters(array $parameters)
+ private function filterApplicableTypehintedParameters(array $parameters) : array
{
- $filtered = array();
+ return array_filter($parameters,
+ function($parameter, $num) {
+ return !$this->isArgumentDefined($num)
+ && $this->getReflectionClassFromParameter($parameter);
+ },
+ ARRAY_FILTER_USE_BOTH
+ );
- foreach ($parameters as $num => $parameter) {
- if ($this->isArgumentDefined($num)) {
- continue;
}
+ private function getReflectionClassFromParameter(\ReflectionParameter $parameter) : ?ReflectionClass
+ {
try {
- $reflectionClass = $parameter->getClass();
- } catch (ReflectionException $e) {
- continue;
+ if (!$parameter->hasType()) {
+ return null;
}
+ $type = $parameter->getType()->getName();
- if (!$reflectionClass) {
- continue;
+ if ($type == 'self') {
+ $type = $parameter->getDeclaringClass();
+ } elseif ($type == 'parent') {
+ $type = $parameter->getDeclaringClass()->getParentClass();
}
- $filtered[$num] = $parameter;
+ return new ReflectionClass($type); // will throw
+ } catch (ReflectionException $e) {
+ return null;
}
-
- return $filtered;
}
/**
@@ -283,7 +287,7 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
$predicate
) {
foreach ($candidates as $candidateIndex => $candidate) {
- if ($predicate($parameter->getClass(), $candidate)) {
+ if (($class = $this->getReflectionClassFromParameter($parameter)) && $predicate($class, $candidate)) {
$num = $parameter->getPosition();
$arguments[$num] = $candidate;

ADD
tests/Behat/Tests/Testwork/Argument/MixedArgumentOrganiserTest.php
+<?php
+declare(strict_types=1);
+
+namespace Behat\Tests\Testwork\Argument;
+
+use Behat\Testwork\Argument\MixedArgumentOrganiser;
+use PHPUnit\Framework\TestCase;
+
+final class MixedArgumentOrganiserTest extends TestCase
+{
+ private $organiser;
+
+ function setUp() : void
+ {
+ $this->organiser = new MixedArgumentOrganiser();
+ }
+
+ /** @test */
+ function it_organises_nothing_if_no_args()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $d) {}
+ );
+ $args = [];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_position()
+ {
+ $r = new \ReflectionFunction(
+ function($x, $y) {}
+ );
+ $args = [
+ 1,
+ 2,
+ 3
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([1,2], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_name()
+ {
+ $r = new \ReflectionFunction(
+ function($date) {}
+ );
+ $args = [
+ 'date' => $date = new \DateTime(),
+ 'x' => new \stdClass()
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame(['date' => $date], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_type()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $d) {}
+ );
+ $args = [
+ 'x' => $date = new \DateTime(),
+ 'y' => new \stdClass()
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([$date], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_name_over_type()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $a, $date) {}
+ );
+ $args = [
+ 'date' => $date = new \DateTime(),
+ 'x' => 1
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([1, 'date' => $date], $organised);
+ }
+}

Remove deprecated reflection from MixedArgumentOrganiser