diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php index 767a7c69..67a16b2c 100644 --- a/src/Concerns/Testable.php +++ b/src/Concerns/Testable.php @@ -350,7 +350,8 @@ private function __resolveTestArguments(array $arguments): array } $underlyingTest = Reflection::getFunctionVariable($this->__test, 'closure'); - $testParameterTypes = array_values(Reflection::getFunctionArguments($underlyingTest)); + $testParameterTypesByName = Reflection::getFunctionArguments($underlyingTest); + $testParameterTypes = array_values($testParameterTypesByName); if (count($arguments) !== 1) { foreach ($arguments as $argumentIndex => $argumentValue) { @@ -358,7 +359,11 @@ private function __resolveTestArguments(array $arguments): array continue; } - if (in_array($testParameterTypes[$argumentIndex], [Closure::class, 'callable', 'mixed'])) { + $parameterType = is_string($argumentIndex) + ? $testParameterTypesByName[$argumentIndex] + : $testParameterTypes[$argumentIndex]; + + if (in_array($parameterType, [Closure::class, 'callable', 'mixed'])) { continue; } @@ -384,7 +389,7 @@ private function __resolveTestArguments(array $arguments): array return [$boundDatasetResult]; } - return array_values($boundDatasetResult); + return $boundDatasetResult; } /** diff --git a/tests/Features/DatasetsTests.php b/tests/Features/DatasetsTests.php index 837b56f6..99682015 100644 --- a/tests/Features/DatasetsTests.php +++ b/tests/Features/DatasetsTests.php @@ -457,3 +457,88 @@ function () { test('after describe block with named dataset', function (...$args) { expect($args)->toBe(['after']); })->with('after-describe'); + +test('named parameters match by parameter name', function (string $email, string $name) { + expect($name)->toBe('Taylor'); + expect($email)->toBe('taylor@laravel.com'); +})->with([ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], +]); + +test('named parameters work with multiple dataset items', function (string $email, string $name) { + expect($name)->toBeString(); + expect($email)->toContain('@'); +})->with([ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + ['name' => 'James', 'email' => 'james@laravel.com'], +]); + +test('named parameters work in different order than closure params', function (string $third, string $first, string $second) { + expect($first)->toBe('a'); + expect($second)->toBe('b'); + expect($third)->toBe('c'); +})->with([ + ['first' => 'a', 'second' => 'b', 'third' => 'c'], +]); + +test('named parameters work with named dataset keys', function (string $email, string $name) { + expect($name)->toBeString(); + expect($email)->toContain('@'); +})->with([ + 'taylor' => ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + 'james' => ['name' => 'James', 'email' => 'james@laravel.com'], +]); + +test('named parameters work with closures that should be resolved', function (string $email, string $name) { + expect($name)->toBe('bar'); + expect($email)->toBe('bar@example.com'); +})->with([ + [ + 'name' => function () { + return $this->foo; + }, + 'email' => function () { + return $this->foo.'@example.com'; + }, + ], +]); + +test('named parameters work with closure type hints', function (Closure $callback, string $name) { + expect($name)->toBe('Taylor'); + expect($callback())->toBe('resolved'); +})->with([ + [ + 'name' => 'Taylor', + 'callback' => function () { + return 'resolved'; + }, + ], +]); + +dataset('named-params-dataset', [ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + ['name' => 'James', 'email' => 'james@laravel.com'], +]); + +test('named parameters work with registered datasets', function (string $email, string $name) { + expect($name)->toBeString(); + expect($email)->toContain('@'); +})->with('named-params-dataset'); + +test('named parameters work with bound closure returning associative array', function (string $email, string $name) { + expect($name)->toBe('bar'); + expect($email)->toBe('test@example.com'); +})->with([ + function () { + return ['name' => $this->foo, 'email' => 'test@example.com']; + }, +]); + +test('dataset items can mix named and sequential styles', function (string $name, string $email) { + expect($name)->toBeString(); + expect($email)->toContain('@'); +})->with([ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + ['James', 'james@laravel.com'], + ['James', 'email' => 'james@laravel.com'], +]);