diff --git a/Makefile b/Makefile index 3f59a3bc1..b7e03e3c3 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ PHP_CS_FIXER_CACHE=.php_cs.cache PHPSTAN=./vendor/bin/phpstan PSALM=./.tools/psalm -PSALM_URL="https://github.com/vimeo/psalm/releases/download/4.12.0/psalm.phar" +PSALM_URL="https://github.com/vimeo/psalm/releases/download/v4.15.0/psalm.phar" PHPUNIT=vendor/phpunit/phpunit/phpunit PARATEST=vendor/bin/paratest --runner=WrapperRunner diff --git a/src/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilder.php b/src/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilder.php index b8e20dab9..3d025ef68 100644 --- a/src/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilder.php +++ b/src/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilder.php @@ -101,7 +101,7 @@ public function build(string $version): string $this->addCoverageNodes($version, $xPath); $this->addRandomTestsOrderAttributesIfNotSet($version, $xPath); - $this->addFailOnAttributesIfNotSet($version, $xPath); + $this->configManipulator->addFailOnAttributesIfNotSet($version, $xPath); $this->configManipulator->replaceWithAbsolutePaths($xPath); $this->configManipulator->setStopOnFailure($xPath); $this->configManipulator->deactivateColours($xPath); @@ -155,16 +155,6 @@ private function addRandomTestsOrderAttributesIfNotSet(string $version, SafeDOMX } } - private function addFailOnAttributesIfNotSet(string $version, SafeDOMXPath $xPath): void - { - if (version_compare($version, '5.2', '<')) { - return; - } - - $this->addAttributeIfNotSet('failOnRisky', 'true', $xPath); - $this->addAttributeIfNotSet('failOnWarning', 'true', $xPath); - } - private function addAttributeIfNotSet(string $attribute, string $value, SafeDOMXPath $xPath): bool { $nodeList = $xPath->query(sprintf('/phpunit/@%s', $attribute)); diff --git a/src/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilder.php b/src/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilder.php index 786ce0950..866fac2b4 100644 --- a/src/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilder.php +++ b/src/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilder.php @@ -101,6 +101,7 @@ public function build( // activate PHPUnit's result cache and order tests by running defects first, then sorted by fastest first $this->configManipulator->handleResultCacheAndExecutionOrder($version, $xPath, $mutationHash); + $this->configManipulator->addFailOnAttributesIfNotSet($version, $xPath); $this->configManipulator->setStopOnFailure($xPath); $this->configManipulator->deactivateColours($xPath); $this->configManipulator->deactivateStderrRedirection($xPath); diff --git a/src/TestFramework/PhpUnit/Config/XmlConfigurationManipulator.php b/src/TestFramework/PhpUnit/Config/XmlConfigurationManipulator.php index 6eefa57d6..34d87e28a 100644 --- a/src/TestFramework/PhpUnit/Config/XmlConfigurationManipulator.php +++ b/src/TestFramework/PhpUnit/Config/XmlConfigurationManipulator.php @@ -200,6 +200,16 @@ public function removeDefaultTestSuite(SafeDOMXPath $xPath): void ); } + public function addFailOnAttributesIfNotSet(string $version, SafeDOMXPath $xPath): void + { + if (version_compare($version, '5.2', '<')) { + return; + } + + $this->addAttributeIfNotSet('failOnRisky', 'true', $xPath); + $this->addAttributeIfNotSet('failOnWarning', 'true', $xPath); + } + /** * @param string[] $srcDirs * @param list $filteredSourceFilesToMutate @@ -359,4 +369,18 @@ private function getOrCreateNode(SafeDOMXPath $xPath, DOMDocument $dom, string $ return $this->createNode($dom, $nodeName); } + + private function addAttributeIfNotSet(string $attribute, string $value, SafeDOMXPath $xPath): bool + { + $nodeList = $xPath->query(sprintf('/phpunit/@%s', $attribute)); + + if ($nodeList->length === 0) { + $node = $xPath->query('/phpunit')[0]; + $node->setAttribute($attribute, $value); + + return true; + } + + return false; + } } diff --git a/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_risky_set.xml b/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_risky_set.xml index 6fd710140..77210f18f 100644 --- a/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_risky_set.xml +++ b/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_risky_set.xml @@ -9,7 +9,7 @@ processIsolation="false" syntaxCheck="false" executionOrder="reverse" - failOnRisky="true" + failOnRisky="false" > diff --git a/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_warning_set.xml b/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_warning_set.xml index 664a6a22c..ad91bcab7 100644 --- a/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_warning_set.xml +++ b/tests/phpunit/Fixtures/Files/phpunit/phpunit_with_fail_on_warning_set.xml @@ -9,7 +9,7 @@ processIsolation="false" syntaxCheck="false" executionOrder="reverse" - failOnWarning="true" + failOnWarning="false" > diff --git a/tests/phpunit/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilderTest.php b/tests/phpunit/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilderTest.php index 8edf1c744..5989ce103 100644 --- a/tests/phpunit/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilderTest.php +++ b/tests/phpunit/TestFramework/PhpUnit/Config/Builder/InitialConfigBuilderTest.php @@ -407,7 +407,7 @@ public function test_it_does_not_update_fail_on_risky_attributes_if_it_is_alread $failOnRisky = $this->queryXpath($xml, sprintf('/phpunit/@%s', 'failOnRisky')); $this->assertInstanceOf(DOMNodeList::class, $failOnRisky); - $this->assertSame('true', $failOnRisky[0]->value); + $this->assertSame('false', $failOnRisky[0]->value); } public function test_it_does_not_update_fail_on_warning_attributes_if_it_is_already_set(): void @@ -421,7 +421,7 @@ public function test_it_does_not_update_fail_on_warning_attributes_if_it_is_alre $failOnRisky = $this->queryXpath($xml, sprintf('/phpunit/@%s', 'failOnWarning')); $this->assertInstanceOf(DOMNodeList::class, $failOnRisky); - $this->assertSame('true', $failOnRisky[0]->value); + $this->assertSame('false', $failOnRisky[0]->value); } public function test_it_creates_a_configuration(): void diff --git a/tests/phpunit/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilderTest.php b/tests/phpunit/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilderTest.php index 98ab19b59..c412b7a9f 100644 --- a/tests/phpunit/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilderTest.php +++ b/tests/phpunit/TestFramework/PhpUnit/Config/Builder/MutationConfigBuilderTest.php @@ -135,7 +135,7 @@ public function test_it_preserves_white_spaces_and_formatting(): void ~ ~ License: https://opensource.org/licenses/BSD-3-Clause New BSD License --> - + @@ -171,7 +171,7 @@ public function test_it_can_build_the_config_for_multiple_mutations(): void ~ ~ License: https://opensource.org/licenses/BSD-3-Clause New BSD License --> - + /path/to/FooTest.php @@ -241,7 +241,7 @@ public function test_it_can_build_the_config_for_multiple_mutations(): void ~ ~ License: https://opensource.org/licenses/BSD-3-Clause New BSD License --> - + /path/to/BarTest.php @@ -622,6 +622,108 @@ public function test_interceptor_is_included(): void ); } + /** + * @dataProvider failOnProvider + */ + public function test_it_adds_fail_on_risky_and_warning_for_proper_phpunit_versions( + string $version, + string $attributeName, + int $expectedNodeCount + ): void { + $xml = file_get_contents($this->builder->build( + [], + self::MUTATED_FILE_PATH, + self::HASH, + self::ORIGINAL_FILE_PATH, + $version + )); + + $nodes = $this->queryXpath($xml, sprintf('/phpunit/@%s', $attributeName)); + + $this->assertInstanceOf(DOMNodeList::class, $nodes); + + $this->assertSame($expectedNodeCount, $nodes->length); + } + + public function test_it_does_not_update_fail_on_risky_attributes_if_it_is_already_set(): void + { + $phpunitXmlPath = self::FIXTURES . '/phpunit_with_fail_on_risky_set.xml'; + + $builder = $this->createConfigBuilder($phpunitXmlPath); + + $xml = file_get_contents($builder->build( + [], + self::MUTATED_FILE_PATH, + self::HASH, + self::ORIGINAL_FILE_PATH, + '5.2' + )); + + $failOnRisky = $this->queryXpath($xml, sprintf('/phpunit/@%s', 'failOnRisky')); + + $this->assertInstanceOf(DOMNodeList::class, $failOnRisky); + $this->assertSame('false', $failOnRisky[0]->value); + } + + public function test_it_does_not_update_fail_on_warning_attributes_if_it_is_already_set(): void + { + $phpunitXmlPath = self::FIXTURES . '/phpunit_with_fail_on_warning_set.xml'; + + $builder = $this->createConfigBuilder($phpunitXmlPath); + + $xml = file_get_contents($builder->build( + [], + self::MUTATED_FILE_PATH, + self::HASH, + self::ORIGINAL_FILE_PATH, + '5.2' + )); + + $failOnRisky = $this->queryXpath($xml, sprintf('/phpunit/@%s', 'failOnWarning')); + + $this->assertInstanceOf(DOMNodeList::class, $failOnRisky); + $this->assertSame('false', $failOnRisky[0]->value); + } + + public function failOnProvider(): iterable + { + yield 'PHPUnit 5.1.99 runs without failOnRisky' => [ + '5.1.99', + 'failOnRisky', + 0, + ]; + + yield 'PHPUnit 5.2 runs with failOnRisky' => [ + '5.2', + 'failOnRisky', + 1, + ]; + + yield 'PHPUnit 5.3.1 runs with failOnRisky' => [ + '5.3.1', + 'failOnRisky', + 1, + ]; + + yield 'PHPUnit 5.1.99 runs without resolveDependencies' => [ + '5.1.99', + 'failOnWarning', + 0, + ]; + + yield 'PHPUnit 5.2 runs with resolveDependencies' => [ + '5.2', + 'failOnWarning', + 1, + ]; + + yield 'PHPUnit 5.3.1 runs resolveDependencies' => [ + '5.3.1', + 'failOnWarning', + 1, + ]; + } + public function locationsProvider(): iterable { yield [