From 3e64163f7c8b4562374bfc67cc7a4a58bcbf1ba0 Mon Sep 17 00:00:00 2001 From: Sartor Date: Wed, 18 Jun 2025 20:23:54 +0300 Subject: [PATCH 1/3] New attribute TestWithArray introduced. More compact version of multiple TestWith for many cases --- src/Framework/Attributes/TestWithArray.php | 36 ++++++++++ src/Metadata/Parser/AttributeParser.php | 10 +++ .../Metadata/Attribute/tests/TestWithTest.php | 38 ++++++++++ .../end-to-end/event/testwith-attribute.phpt | 44 ++++++++++-- .../Metadata/Parser/AttributeParserTest.php | 2 + .../Parser/AttributeParserTestCase.php | 70 ++++++++++++++----- 6 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 src/Framework/Attributes/TestWithArray.php diff --git a/src/Framework/Attributes/TestWithArray.php b/src/Framework/Attributes/TestWithArray.php new file mode 100644 index 00000000000..2d90ce3653f --- /dev/null +++ b/src/Framework/Attributes/TestWithArray.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; + +/** + * @immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] +final readonly class TestWithArray +{ + private array $cases; + + /** + * @param array> $arrayOfCases + */ + public function __construct(array $arrayOfCases) + { + $this->cases = $arrayOfCases; + } + + public function arrayOfCases(): array + { + return $this->cases; + } +} diff --git a/src/Metadata/Parser/AttributeParser.php b/src/Metadata/Parser/AttributeParser.php index 7734db354a6..4dd505ebce7 100644 --- a/src/Metadata/Parser/AttributeParser.php +++ b/src/Metadata/Parser/AttributeParser.php @@ -74,6 +74,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; +use PHPUnit\Framework\Attributes\TestWithArray; use PHPUnit\Framework\Attributes\TestWithJson; use PHPUnit\Framework\Attributes\Ticket; use PHPUnit\Framework\Attributes\UsesClass; @@ -868,6 +869,15 @@ public function forMethod(string $className, string $methodName): MetadataCollec $attributeInstance->name(), ); + break; + case TestWithArray::class: + assert($attributeInstance instanceof TestWithArray); + + foreach ($attributeInstance->arrayOfCases() as $name => $case) { + assert(is_array($case)); + $result[] = Metadata::testWith($case, is_int($name) ? null : $name); + } + break; case Ticket::class: diff --git a/tests/_files/Metadata/Attribute/tests/TestWithTest.php b/tests/_files/Metadata/Attribute/tests/TestWithTest.php index 5ed7dd01f1b..fe34931ead3 100644 --- a/tests/_files/Metadata/Attribute/tests/TestWithTest.php +++ b/tests/_files/Metadata/Attribute/tests/TestWithTest.php @@ -10,6 +10,7 @@ namespace PHPUnit\TestFixture\Metadata\Attribute; use PHPUnit\Framework\Attributes\TestWith; +use PHPUnit\Framework\Attributes\TestWithArray; use PHPUnit\Framework\Attributes\TestWithJson; use PHPUnit\Framework\TestCase; @@ -38,4 +39,41 @@ public function testTwoWithName($one, $two, $three): void { $this->assertTrue(true); } + + #[TestWithArray([ + [1, true], + ])] + public function testTestWithArrayBasic($one, $two): void + { + $this->assertTrue(true); + } + + #[TestWithArray([ + 'firstCase' => [2, false], + ])] + public function testTestWithArrayNamedCase($one, $two): void + { + $this->assertTrue(true); + } + + #[TestWithArray([ + 'odds' => [1, 3], + [-1, 0], + 'evens' => [2, 4], + ])] + public function testTestWithArrayManyCasesWithMixedNames($one, $two): void + { + $this->assertTrue(true); + } + + #[TestWithArray([ + [5], + ])] + #[TestWithArray([ + [6], + ])] + public function testMultipleTestWithArray($one): void + { + $this->assertTrue(true); + } } diff --git a/tests/end-to-end/event/testwith-attribute.phpt b/tests/end-to-end/event/testwith-attribute.phpt index d5761afdc7c..4c0c203d97f 100644 --- a/tests/end-to-end/event/testwith-attribute.phpt +++ b/tests/end-to-end/event/testwith-attribute.phpt @@ -14,11 +14,11 @@ require __DIR__ . '/../../bootstrap.php'; PHPUnit Started (PHPUnit %s using %s) Test Runner Configured Event Facade Sealed -Test Suite Loaded (4 tests) +Test Suite Loaded (11 tests) Test Runner Started Test Suite Sorted -Test Runner Execution Started (4 tests) -Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 4 tests) +Test Runner Execution Started (11 tests) +Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 11 tests) Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne, 1 test) Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testOne#0) @@ -43,7 +43,43 @@ Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithN Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName#Name2) Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTwoWithName, 1 test) -Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 4 tests) +Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic, 1 test) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic#0) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic#0) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic#0) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic#0) +Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayBasic, 1 test) +Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase, 1 test) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase#firstCase) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase#firstCase) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase#firstCase) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase#firstCase) +Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayNamedCase, 1 test) +Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames, 3 tests) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#odds) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#odds) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#odds) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#odds) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#0) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#0) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#0) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#0) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#evens) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#evens) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#evens) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames#evens) +Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testTestWithArrayManyCasesWithMixedNames, 3 tests) +Test Suite Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray, 2 tests) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#0) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#0) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#0) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#0) +Test Preparation Started (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#1) +Test Prepared (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#1) +Test Passed (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#1) +Test Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray#1) +Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest::testMultipleTestWithArray, 2 tests) +Test Suite Finished (PHPUnit\TestFixture\Metadata\Attribute\TestWithTest, 11 tests) Test Runner Execution Finished Test Runner Finished PHPUnit Finished (Shell Exit Code: 0) diff --git a/tests/unit/Metadata/Parser/AttributeParserTest.php b/tests/unit/Metadata/Parser/AttributeParserTest.php index 81bb3a45cdb..a96288f72cd 100644 --- a/tests/unit/Metadata/Parser/AttributeParserTest.php +++ b/tests/unit/Metadata/Parser/AttributeParserTest.php @@ -60,6 +60,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; +use PHPUnit\Framework\Attributes\TestWithArray; use PHPUnit\Framework\Attributes\TestWithJson; use PHPUnit\Framework\Attributes\Ticket; use PHPUnit\Framework\Attributes\UsesClass; @@ -127,6 +128,7 @@ #[CoversClass(Small::class)] #[CoversClass(TestDox::class)] #[CoversClass(Test::class)] +#[CoversClass(TestWithArray::class)] #[CoversClass(TestWithJson::class)] #[CoversClass(TestWith::class)] #[CoversClass(Ticket::class)] diff --git a/tests/unit/Metadata/Parser/AttributeParserTestCase.php b/tests/unit/Metadata/Parser/AttributeParserTestCase.php index 780578d61fb..5e55e975201 100644 --- a/tests/unit/Metadata/Parser/AttributeParserTestCase.php +++ b/tests/unit/Metadata/Parser/AttributeParserTestCase.php @@ -1094,10 +1094,11 @@ public function test_parses_TestWith_attribute_on_method(): void $metadata = $this->parser()->forMethod(TestWithTest::class, 'testOne')->isTestWith(); $this->assertCount(1, $metadata); - $this->assertTrue($metadata->asArray()[0]->isTestWith()); - $this->assertSame([1, 2, 3], $metadata->asArray()[0]->data()); - $this->assertFalse($metadata->asArray()[0]->hasName()); - $this->assertNull($metadata->asArray()[0]->name()); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->isTestWith()); + $this->assertSame([1, 2, 3], $firstCase->data()); + $this->assertFalse($firstCase->hasName()); + $this->assertNull($firstCase->name()); } #[TestDox('Parses #[TestWith] attribute with name on method')] @@ -1106,22 +1107,58 @@ public function test_parses_TestWith_attribute_with_name_on_method(): void $metadata = $this->parser()->forMethod(TestWithTest::class, 'testOneWithName')->isTestWith(); $this->assertCount(1, $metadata); - $this->assertTrue($metadata->asArray()[0]->isTestWith()); - $this->assertSame([1, 2, 3], $metadata->asArray()[0]->data()); - $this->assertTrue($metadata->asArray()[0]->hasName()); - $this->assertSame('Name1', $metadata->asArray()[0]->name()); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->isTestWith()); + $this->assertSame([1, 2, 3], $firstCase->data()); + $this->assertTrue($firstCase->hasName()); + $this->assertSame('Name1', $firstCase->name()); } + #[TestDox('Parses #[TestWithArray] attribute(s) on method')] + public function test_parses_TestWithArray_attribute_on_method(): void + { + /** @see TestWithTest::testTestWithArrayBasic() */ + $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayBasic'); + $this->assertCount(1, $metadata); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->isTestWith()); + $this->assertSame([1, true], $firstCase->data()); + $this->assertFalse($firstCase->hasName()); + $this->assertNull($firstCase->name()); + + /** @see TestWithTest::testTestWithArrayNamedCase() */ + $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayNamedCase')->isTestWith(); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->hasName()); + $this->assertSame('firstCase', $firstCase->name()); + + /** @see TestWithTest::testTestWithArrayManyCasesWithMixedNames() */ + $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayManyCasesWithMixedNames')->isTestWith(); + $this->assertCount(3, $metadata); + $cases = $metadata->asArray(); + $this->assertSame('odds', $cases[0]->name()); + $this->assertNull($cases[1]->name()); + $this->assertSame('evens', $cases[2]->name()); + + /** @see TestWithTest::testMultipleTestWithArray() */ + $metadata = $this->parser()->forMethod(TestWithTest::class, 'testMultipleTestWithArray')->isTestWith(); + $cases = $metadata->asArray(); + $this->assertSame([5], $cases[0]->data()); + $this->assertSame([6], $cases[1]->data()); + } + + #[TestDox('Parses #[TestWithJson] attribute on method')] public function test_parses_TestWithJson_attribute_on_method(): void { $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTwo')->isTestWith(); $this->assertCount(1, $metadata); - $this->assertTrue($metadata->asArray()[0]->isTestWith()); - $this->assertSame([1, 2, 3], $metadata->asArray()[0]->data()); - $this->assertFalse($metadata->asArray()[0]->hasName()); - $this->assertNull($metadata->asArray()[0]->name()); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->isTestWith()); + $this->assertSame([1, 2, 3], $firstCase->data()); + $this->assertFalse($firstCase->hasName()); + $this->assertNull($firstCase->name()); } #[TestDox('Parses #[TestWithJson] attribute with name on method')] @@ -1130,10 +1167,11 @@ public function test_parses_TestWithJson_attribute_with_name_on_method(): void $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTwoWithName')->isTestWith(); $this->assertCount(1, $metadata); - $this->assertTrue($metadata->asArray()[0]->isTestWith()); - $this->assertSame([1, 2, 3], $metadata->asArray()[0]->data()); - $this->assertTrue($metadata->asArray()[0]->hasName()); - $this->assertSame('Name2', $metadata->asArray()[0]->name()); + $firstCase = $metadata->asArray()[0]; + $this->assertTrue($firstCase->isTestWith()); + $this->assertSame([1, 2, 3], $firstCase->data()); + $this->assertTrue($firstCase->hasName()); + $this->assertSame('Name2', $firstCase->name()); } #[TestDox('Parses #[Ticket] attribute on method')] From bd119d65ba0490414d2752fa8214953e75e1f8e5 Mon Sep 17 00:00:00 2001 From: Sartor Date: Thu, 19 Jun 2025 10:56:34 +0300 Subject: [PATCH 2/3] Type annotations added to attribute TestWithArray and tests --- src/Framework/Attributes/TestWithArray.php | 6 ++++++ tests/unit/Metadata/Parser/AttributeParserTestCase.php | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/Framework/Attributes/TestWithArray.php b/src/Framework/Attributes/TestWithArray.php index 2d90ce3653f..0c31a92df8c 100644 --- a/src/Framework/Attributes/TestWithArray.php +++ b/src/Framework/Attributes/TestWithArray.php @@ -19,6 +19,9 @@ #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] final readonly class TestWithArray { + /** + * @var array> + */ private array $cases; /** @@ -29,6 +32,9 @@ public function __construct(array $arrayOfCases) $this->cases = $arrayOfCases; } + /** + * @return array> + */ public function arrayOfCases(): array { return $this->cases; diff --git a/tests/unit/Metadata/Parser/AttributeParserTestCase.php b/tests/unit/Metadata/Parser/AttributeParserTestCase.php index 5e55e975201..48b83dfdfff 100644 --- a/tests/unit/Metadata/Parser/AttributeParserTestCase.php +++ b/tests/unit/Metadata/Parser/AttributeParserTestCase.php @@ -21,6 +21,7 @@ use PHPUnit\Metadata\RequiresPhpunit; use PHPUnit\Metadata\RequiresPhpunitExtension; use PHPUnit\Metadata\RequiresSetting; +use PHPUnit\Metadata\TestWith; use PHPUnit\Metadata\Version\ComparisonRequirement; use PHPUnit\Metadata\Version\ConstraintRequirement; use PHPUnit\Metadata\WithEnvironmentVariable; @@ -1120,6 +1121,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayBasic() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayBasic'); $this->assertCount(1, $metadata); + /** @var TestWith $firstCase */ $firstCase = $metadata->asArray()[0]; $this->assertTrue($firstCase->isTestWith()); $this->assertSame([1, true], $firstCase->data()); @@ -1128,6 +1130,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayNamedCase() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayNamedCase')->isTestWith(); + /** @var TestWith $firstCase */ $firstCase = $metadata->asArray()[0]; $this->assertTrue($firstCase->hasName()); $this->assertSame('firstCase', $firstCase->name()); @@ -1135,6 +1138,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayManyCasesWithMixedNames() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayManyCasesWithMixedNames')->isTestWith(); $this->assertCount(3, $metadata); + /** @var TestWith[] $cases */ $cases = $metadata->asArray(); $this->assertSame('odds', $cases[0]->name()); $this->assertNull($cases[1]->name()); @@ -1142,6 +1146,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testMultipleTestWithArray() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testMultipleTestWithArray')->isTestWith(); + /** @var TestWith[] $cases */ $cases = $metadata->asArray(); $this->assertSame([5], $cases[0]->data()); $this->assertSame([6], $cases[1]->data()); From 4838e5d4114244606ac4fd065a95bd07155bee01 Mon Sep 17 00:00:00 2001 From: Sartor Date: Fri, 27 Jun 2025 18:49:57 +0300 Subject: [PATCH 3/3] PHP CS fixer linting update --- src/Metadata/Parser/AttributeParser.php | 3 +++ tests/unit/Metadata/Parser/AttributeParserTestCase.php | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Metadata/Parser/AttributeParser.php b/src/Metadata/Parser/AttributeParser.php index 4dd505ebce7..87debfcca54 100644 --- a/src/Metadata/Parser/AttributeParser.php +++ b/src/Metadata/Parser/AttributeParser.php @@ -12,6 +12,8 @@ use const JSON_THROW_ON_ERROR; use function assert; use function class_exists; +use function is_array; +use function is_int; use function json_decode; use function method_exists; use function sprintf; @@ -870,6 +872,7 @@ public function forMethod(string $className, string $methodName): MetadataCollec ); break; + case TestWithArray::class: assert($attributeInstance instanceof TestWithArray); diff --git a/tests/unit/Metadata/Parser/AttributeParserTestCase.php b/tests/unit/Metadata/Parser/AttributeParserTestCase.php index 48b83dfdfff..ad612d2bd29 100644 --- a/tests/unit/Metadata/Parser/AttributeParserTestCase.php +++ b/tests/unit/Metadata/Parser/AttributeParserTestCase.php @@ -1121,6 +1121,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayBasic() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayBasic'); $this->assertCount(1, $metadata); + /** @var TestWith $firstCase */ $firstCase = $metadata->asArray()[0]; $this->assertTrue($firstCase->isTestWith()); @@ -1130,6 +1131,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayNamedCase() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayNamedCase')->isTestWith(); + /** @var TestWith $firstCase */ $firstCase = $metadata->asArray()[0]; $this->assertTrue($firstCase->hasName()); @@ -1138,6 +1140,7 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testTestWithArrayManyCasesWithMixedNames() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testTestWithArrayManyCasesWithMixedNames')->isTestWith(); $this->assertCount(3, $metadata); + /** @var TestWith[] $cases */ $cases = $metadata->asArray(); $this->assertSame('odds', $cases[0]->name()); @@ -1146,13 +1149,13 @@ public function test_parses_TestWithArray_attribute_on_method(): void /** @see TestWithTest::testMultipleTestWithArray() */ $metadata = $this->parser()->forMethod(TestWithTest::class, 'testMultipleTestWithArray')->isTestWith(); + /** @var TestWith[] $cases */ $cases = $metadata->asArray(); $this->assertSame([5], $cases[0]->data()); $this->assertSame([6], $cases[1]->data()); } - #[TestDox('Parses #[TestWithJson] attribute on method')] public function test_parses_TestWithJson_attribute_on_method(): void {