From 96749ae31154501acc49d19f32715994e16dade3 Mon Sep 17 00:00:00 2001 From: Ion Bazan Date: Fri, 12 Apr 2024 11:18:10 +0800 Subject: [PATCH 1/2] Deprecate invalid named arguments in data providers --- src/Framework/TestCase.php | 36 +++++++++++++ .../InvalidParameterNameDataProviderTest.php | 31 +++++++++++ .../data-provider-invalid-argument-name.phpt | 54 +++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 tests/end-to-end/event/_files/InvalidParameterNameDataProviderTest.php create mode 100644 tests/end-to-end/event/data-provider-invalid-argument-name.phpt diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 155c6924341..3622fcab88e 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -18,7 +18,9 @@ use const PATHINFO_FILENAME; use const PHP_EOL; use const PHP_URL_PATH; +use function array_is_list; use function array_keys; +use function array_map; use function array_merge; use function array_values; use function assert; @@ -56,6 +58,7 @@ use DeepCopy\DeepCopy; use PHPUnit\Event; use PHPUnit\Event\NoPreviousThrowableException; +use PHPUnit\Event\RuntimeException; use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint; use PHPUnit\Framework\Constraint\ExceptionCode; @@ -91,7 +94,9 @@ use PHPUnit\Util\Test as TestUtil; use ReflectionClass; use ReflectionException; +use ReflectionMethod; use ReflectionObject; +use ReflectionParameter; use SebastianBergmann\CodeCoverage\StaticAnalysisCacheNotConfiguredException; use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; use SebastianBergmann\Comparator\Comparator; @@ -1061,6 +1066,37 @@ final public function setData(int|string $dataName, array $data): void { $this->dataName = $dataName; $this->data = $data; + + if (array_is_list($data)) { + return; + } + + try { + $reflector = new ReflectionMethod($this, $this->name); + $parameters = array_map(static fn (ReflectionParameter $parameter) => $parameter->name, $reflector->getParameters()); + + foreach (array_keys($data) as $parameter) { + if (is_string($parameter) && !in_array($parameter, $parameters, true)) { + Event\Facade::emitter()->testTriggeredPhpunitDeprecation( + $this->valueObjectForEvents(), + sprintf( + 'Providing invalid named argument $%s for method %s::%s() is deprecated and will not be supported in PHPUnit 11.0.', + $parameter, + $this::class, + $this->name, + ), + ); + } + } + // @codeCoverageIgnoreStart + } catch (ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + $e->getCode(), + $e, + ); + } + // @codeCoverageIgnoreEnd } /** diff --git a/tests/end-to-end/event/_files/InvalidParameterNameDataProviderTest.php b/tests/end-to-end/event/_files/InvalidParameterNameDataProviderTest.php new file mode 100644 index 00000000000..5e9d3717d43 --- /dev/null +++ b/tests/end-to-end/event/_files/InvalidParameterNameDataProviderTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestFixture\Event; + +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; + +final class InvalidParameterNameDataProviderTest extends TestCase +{ + public static function values(): array + { + return [ + ['value1' => true, 'value2' => true], + ['value3' => true, 'value4' => true], + ]; + } + + #[DataProvider('values')] + public function testSuccess(bool $value1, bool $value2): void + { + $this->assertTrue($value1); + $this->assertTrue($value2); + } +} diff --git a/tests/end-to-end/event/data-provider-invalid-argument-name.phpt b/tests/end-to-end/event/data-provider-invalid-argument-name.phpt new file mode 100644 index 00000000000..cdc880e1eda --- /dev/null +++ b/tests/end-to-end/event/data-provider-invalid-argument-name.phpt @@ -0,0 +1,54 @@ +--TEST-- +The right events are emitted in the right order for a test that uses a data provider that is not static +--FILE-- +run($_SERVER['argv']); + +print file_get_contents($traceFile); + +unlink($traceFile); +--EXPECTF-- +PHPUnit Started (PHPUnit %s using %s) +Test Runner Configured +Data Provider Method Called (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::values for test method PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess) +Data Provider Method Finished for PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess: +- PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::values +Test Triggered PHPUnit Deprecation (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Providing invalid named argument $value3 for method PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess() is deprecated and will not be supported in PHPUnit 11.0. +Test Triggered PHPUnit Deprecation (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Providing invalid named argument $value4 for method PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess() is deprecated and will not be supported in PHPUnit 11.0. +Test Suite Loaded (2 tests) +Event Facade Sealed +Test Runner Started +Test Suite Sorted +Test Runner Execution Started (2 tests) +Test Suite Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest, 2 tests) +Test Suite Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 tests) +Test Preparation Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) +Test Prepared (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) +Assertion Succeeded (Constraint: is true, Value: true) +Assertion Succeeded (Constraint: is true, Value: true) +Test Passed (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) +Test Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#0) +Test Preparation Started (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Test Prepared (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Assertion Succeeded (Constraint: is true, Value: true) +Assertion Succeeded (Constraint: is true, Value: true) +Test Passed (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Test Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess#1) +Test Suite Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest::testSuccess, 2 tests) +Test Suite Finished (PHPUnit\TestFixture\Event\InvalidParameterNameDataProviderTest, 2 tests) +Test Runner Execution Finished +Test Runner Finished +PHPUnit Finished (Shell Exit Code: 0) From b7ccfe25eafb6b8dc7f6c43836c06ccdcba03975 Mon Sep 17 00:00:00 2001 From: Ion Bazan Date: Fri, 12 Apr 2024 13:26:21 +0800 Subject: [PATCH 2/2] add throws tag --- src/Framework/TestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 3622fcab88e..88eb4e1559e 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -1060,6 +1060,8 @@ final public function requires(): array } /** + * @throws RuntimeException + * * @internal This method is not covered by the backward compatibility promise for PHPUnit */ final public function setData(int|string $dataName, array $data): void