Remove deprecated reflection calls from ReturnTypeTransformation
MODIFY
features/definitions_transformations.feature
features/definitions_transformations.feature
@@ -637,3 +637,40 @@ Feature: Step Arguments Transformations
4 scenarios (4 passed)
8 steps (8 passed)
"""
+
+ @php8
+ Scenario: By-type transformations don't trigger from union types
+ Given a file named "features/union-transforms.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given I am "everzet"
+ And she is "lunivore"
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php
+ class User {
+ }
+ class FeatureContext implements Behat\Behat\Context\Context
+ {
+ /** @Transform */
+ public function userFromName($name) : User|int
+ {
+ return new User();
+ }
+
+ /**
+ * @Given I am :user
+ * @Given she is :user
+ */
+ public function iAm(User $user) {
+ $this->I = $user;
+ }
+ }
+ """
+ When I run "behat -f progress --no-colors"
+ Then it should fail with:
+ """
+ string given
+ """

MODIFY
src/Behat/Behat/Transformation/Transformation/ReturnTypeTransformation.php
src/Behat/Behat/Transformation/Transformation/ReturnTypeTransformation.php
@@ -16,6 +16,7 @@ use Behat\Behat\Transformation\SimpleArgumentTransformation;
use Behat\Testwork\Call\CallCenter;
use Behat\Testwork\Call\RuntimeCallee;
use Closure;
+use ReflectionClass;
use ReflectionFunctionAbstract;
use ReflectionMethod;
use ReflectionParameter;
@@ -127,7 +128,8 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
{
$type = $reflection->getReturnType();
- if (null === $type || $type->isBuiltin()) {
+ // Skip ReflectionUnionType as they can't be relied on for a transform
+ if (null === $type || !($type instanceof \ReflectionNamedType) || $type->isBuiltin()) {
return null;
}
@@ -152,9 +154,12 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
array_filter($this->getCallParameters($definitionCall),
$this->hasIndex($argumentIndex)
),
- $this->isClass()
+ $this->getClassReflection()
);
- return count($parameters) ? current($parameters)->getClass()->getName() : null;
+
+ if (count($parameters)) {
+ return ($this->getClassReflection())(current($parameters))->getName();
+ }
}
/**
@@ -214,10 +219,17 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
*
* @return Closure
*/
- private function isClass()
+ private function getClassReflection()
{
return function (ReflectionParameter $parameter) {
- return $parameter->getClass();
+ $t = $parameter->getType();
+
+ if ($t instanceof ReflectionNamedType) {
+ try {
+ return new ReflectionClass($t->getName());
+ }
+ catch (\TypeError $t) {}
+ }
};
}
}

Remove deprecated reflection calls from ReturnTypeTransformation