From cfe89d20ac0bed8db66381a0b5d2e037fae58c64 Mon Sep 17 00:00:00 2001 From: Andrew Matia <73502748+drewmt@users.noreply.github.com> Date: Sun, 16 Aug 2026 17:08:46 +0300 Subject: [PATCH] Fix repeat with named dataset arguments (#1769) --- src/Concerns/Testable.php | 21 +++++++++++++++------ tests/.snapshots/success.txt | 10 +++++++++- tests/Features/Repeat.php | 22 ++++++++++++++++++++++ tests/Visual/Parallel.php | 4 ++-- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php index 420b7026..0debfaf4 100644 --- a/src/Concerns/Testable.php +++ b/src/Concerns/Testable.php @@ -408,16 +408,25 @@ trait Testable private function __resolveTestArguments(array $arguments): array { $method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name()); - - if ($method->repetitions > 1) { - $firstArgument = array_shift($arguments); - $arguments[] = $firstArgument; - } - $underlyingTest = Reflection::getFunctionVariable($this->__test, 'closure'); $testParameterTypesByName = Reflection::getFunctionArguments($underlyingTest); $testParameterTypes = array_values($testParameterTypesByName); + if ($method->repetitions > 1) { + $firstArgument = array_shift($arguments); + + if (array_is_list($arguments)) { + $arguments[] = $firstArgument; + } else { + $testParameterNames = array_keys($testParameterTypesByName); + $iterationParameterName = $testParameterNames[count($arguments)] ?? null; + + if ($iterationParameterName !== null) { + $arguments[$iterationParameterName] = $firstArgument; + } + } + } + if (count($arguments) !== 1) { foreach ($arguments as $argumentIndex => $argumentValue) { if (! $argumentValue instanceof Closure) { diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 0f872557..eae8cd58 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -1455,6 +1455,14 @@ ✓ multiple times with repeat iterator with multiple dataset ('c') / ('d') @ repetition 2 of 2 ✓ multiple times with repeat iterator with multiple dataset ('c') / ('e') @ repetition 2 of 2 ✓ multiple times with repeat iterator with multiple dataset ('c') / ('f') @ repetition 2 of 2 + ✓ multiple times with named dataset arguments ('Taylor', 'taylor@laravel.com') @ repetition 1 of 2 + ✓ multiple times with named dataset arguments ('Nuno', 'enunomaduro@gmail.com') @ repetition 1 of 2 + ✓ multiple times with named dataset arguments ('Taylor', 'taylor@laravel.com') @ repetition 2 of 2 + ✓ multiple times with named dataset arguments ('Nuno', 'enunomaduro@gmail.com') @ repetition 2 of 2 + ✓ multiple times with named dataset arguments and repeat iterator ('Taylor', 'taylor@laravel.com') @ repetition 1 of 2 + ✓ multiple times with named dataset arguments and repeat iterator ('Nuno', 'enunomaduro@gmail.com') @ repetition 1 of 2 + ✓ multiple times with named dataset arguments and repeat iterator ('Taylor', 'taylor@laravel.com') @ repetition 2 of 2 + ✓ multiple times with named dataset arguments and repeat iterator ('Nuno', 'enunomaduro@gmail.com') @ repetition 2 of 2 ✓ describe blocks → multiple times @ repetition 1 of 3 ✓ describe blocks → multiple times @ repetition 2 of 3 ✓ describe blocks → multiple times @ repetition 3 of 3 @@ -2226,4 +2234,4 @@ ✓ pass with dataset with ('my-datas-set-value') ✓ within describe → pass with dataset with ('my-datas-set-value') - Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1573 passed (3414 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1581 passed (3434 assertions) diff --git a/tests/Features/Repeat.php b/tests/Features/Repeat.php index e1fa5ef7..2a528126 100644 --- a/tests/Features/Repeat.php +++ b/tests/Features/Repeat.php @@ -44,6 +44,28 @@ test('multiple times with repeat iterator with multiple dataset', function (stri ->toBeGreaterThan(0); })->repeat(times: 2)->with(['a', 'b', 'c'], ['d', 'e', 'f']); +test('multiple times with named dataset arguments', function (string $name, string $email): void { + expect($name) + ->toBeIn(['Taylor', 'Nuno']) + ->and($email) + ->toContain('@'); +})->repeat(times: 2)->with([ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + ['name' => 'Nuno', 'email' => 'enunomaduro@gmail.com'], +]); + +test('multiple times with named dataset arguments and repeat iterator', function (string $name, string $email, int $iteration): void { + expect($name) + ->toBeIn(['Taylor', 'Nuno']) + ->and($email) + ->toContain('@') + ->and($iteration) + ->toBeIn([1, 2]); +})->repeat(times: 2)->with([ + ['name' => 'Taylor', 'email' => 'taylor@laravel.com'], + ['name' => 'Nuno', 'email' => 'enunomaduro@gmail.com'], +]); + describe('describe blocks', function (): void { test('multiple times', function (): void { expect(true)->toBeTrue(); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 94cfffc6..914b215f 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -26,13 +26,13 @@ test('parallel', function () use ($run): void { $file = file_get_contents(__FILE__); $file = preg_replace( '/\$expected = \'.*?\';/', - "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1555 passed (3359 assertions)';", + "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1563 passed (3379 assertions)';", $file, ); file_put_contents(__FILE__, $file); } - $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1555 passed (3359 assertions)'; + $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1563 passed (3379 assertions)'; expect($output) ->toContain("Tests: {$expected}")