Remove deprecated reflection calls from ArgumentAutowirer and related named arguments fix
MODIFY
features/autowire.feature
features/autowire.feature
@@ -12,6 +12,7 @@ Feature: Helper services autowire
- It only wires arguments that weren't otherwise set
- Services must be last arguments in step definitions
- Services must be last arguments in transformations
+ - Autowiring is not yet triggered for union types
Background:
Given a file named "behat.yaml" with:
@@ -245,3 +246,28 @@ Feature: Helper services autowire
"""
When I run "behat --no-colors -f progress features/autowire.feature"
Then it should pass
+
+ @php8
+ Scenario: Union constructor arguments
+ Given a file named "features/autowire.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given a step
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php use Behat\Behat\Context\Context;
+
+ class FeatureContext implements Context {
+ public function __construct(Service1|Service2 $s) {}
+
+ /** @Given a step */
+ public function aStep() {}
+ }
+ """
+ When I run "behat --no-colors -f progress features/autowire.feature"
+ Then it should fail with:
+ """
+ Can not find a matching value for an argument `$s` of the method `FeatureContext::__construct()`
+ """

MODIFY
src/Behat/Behat/Context/ContextFactory.php
src/Behat/Behat/Context/ContextFactory.php
@@ -130,7 +130,7 @@ final class ContextFactory
private function createInstance(ReflectionClass $reflection, array $arguments)
{
if (count($arguments)) {
- return $reflection->newInstanceArgs($arguments);
+ return $reflection->newInstanceArgs(array_values($arguments));
}
return $reflection->newInstance();

MODIFY
src/Behat/Behat/HelperContainer/ArgumentAutowirer.php
src/Behat/Behat/HelperContainer/ArgumentAutowirer.php
@@ -12,12 +12,14 @@ namespace Behat\Behat\HelperContainer;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface as PsrContainerInterface;
+use ReflectionClass;
use ReflectionFunctionAbstract;
+use ReflectionNamedType;
use ReflectionParameter;
use ReflectionException;
/**
- * Automatically wires arguments of a given function from inside the container by using type-hitns.
+ * Automatically wires arguments of a given function from inside the container by using type-hints.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
@@ -53,7 +55,7 @@ final class ArgumentAutowirer
$newArguments = $arguments;
foreach ($reflection->getParameters() as $index => $parameter) {
if ($this->isArgumentWireable($newArguments, $index, $parameter)) {
- $newArguments[$index] = $this->container->get($parameter->getClass()->getName());
+ $newArguments[$index] = $this->container->get($this->getClassFromParameter($parameter));
}
}
@@ -81,10 +83,32 @@ final class ArgumentAutowirer
return false;
}
+ if (!$parameter->getType() instanceof ReflectionNamedType) {
+ return false;
+ }
+
+ return (bool) $this->getClassFromParameter($parameter);
+ }
+
+ private function getClassFromParameter(ReflectionParameter $parameter) : ?string
+ {
try {
- return (bool) $parameter->getClass();
+ $typeString = $parameter->getType()->getName();
+
+ if ($typeString == 'self') {
+ return $parameter->getDeclaringClass()->getName();
+ }
+ elseif ($typeString == 'parent') {
+ return $parameter->getDeclaringClass()->getParentClass()->getName();
+ }
+
+ // will throw if not valid class
+ new ReflectionClass($typeString);
+
+ return $typeString;
+
} catch (ReflectionException $e) {
- return false;
+ return null;
}
}
}

Remove deprecated reflection calls from ArgumentAutowirer and related named arguments fix