Skip to content

Commit

Permalink
Use "metadata" instead of annotation (to reflect the fact that metada…
Browse files Browse the repository at this point in the history
…ta can be provided using attributes and docblock annotations)
  • Loading branch information
sebastianbergmann committed Sep 17, 2021
1 parent fff9174 commit 0c65a47
Show file tree
Hide file tree
Showing 23 changed files with 91 additions and 68 deletions.
2 changes: 2 additions & 0 deletions ChangeLog-10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ All notable changes of the PHPUnit 10.0 release series are documented in this fi
* The `status` attribute of `<test>` elements in the TestDox XML logfile now contains a textual representation instead of a number (`"success"` instead of `"0"`, for instance)
* The `size` attribute of `<test>` elements in the TestDox XML logfile now contains a textual representation instead of a number (`"unknown"` instead of `"-1"`, for instance)
* The JUnit XML logfile now has both `name` and `file` attributes on `<testcase>` elements for PHPT tests
* The `forceCoversAnnotation` attribute of the `<phpunit>` element of PHPUnit's XML configuration file has been renamed to `requireCoverageMetadata`
* The `beStrictAboutCoversAnnotation` attribute of the `<phpunit>` element of PHPUnit's XML configuration file has been renamed to `beStrictAboutCoverageMetadata`

### Removed

Expand Down
4 changes: 2 additions & 2 deletions phpunit.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
<xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
<xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
<xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
<xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
<xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
Expand All @@ -230,7 +230,7 @@
<xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
<xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
<xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
<xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
<xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class RiskyDueToMissingCoversAnnotationException extends AssertionFailedError implements RiskyTest
final class RiskyDueToMissingCodeCoverageMetadataException extends AssertionFailedError implements RiskyTest
{
public function __construct()
{
parent::__construct(
'This test does not define a code coverage target using an attribute or annotation but is expected to do so'
);
}
}
10 changes: 5 additions & 5 deletions src/Framework/TestResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ final class TestResult implements Countable

private bool $enforceTimeLimit = false;

private bool $forceCoversAnnotation = false;
private bool $requireCoverageMetadata = false;

private int $timeoutForSmallTests = 1;

Expand Down Expand Up @@ -497,14 +497,14 @@ public function enforcesTimeLimit(): bool
return $this->enforceTimeLimit;
}

public function forceCoversAnnotation(bool $flag): void
public function requireCoverageMetadata(bool $flag): void
{
$this->forceCoversAnnotation = $flag;
$this->requireCoverageMetadata = $flag;
}

public function enforcesCoversAnnotation(): bool
public function requiresCoverageMetadata(): bool
{
return $this->forceCoversAnnotation;
return $this->requireCoverageMetadata;
}

public function stopOnRisky(bool $flag): void
Expand Down
6 changes: 2 additions & 4 deletions src/Framework/TestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,11 @@ public function run(TestCase $test, TestResult $result): void
}

if (!$error && !$failure && !$warning && !$incomplete && !$skipped && !$risky &&
$result->enforcesCoversAnnotation() &&
$result->requiresCoverageMetadata() &&
!$this->hasCoverageMetadata($test::class, $test->getName(false))) {
$result->addFailure(
$test,
new RiskyDueToMissingCoversAnnotationException(
'This test does not have a @covers annotation but is expected to have one'
),
new RiskyDueToMissingCodeCoverageMetadataException,
$time
);

Expand Down
11 changes: 1 addition & 10 deletions src/Metadata/Api/CodeCoverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,9 @@ public function linesToBeCovered(string $className, string $methodName): array|f
}

/**
* Returns lines of code specified with the @uses annotation.
* @psalm-param class-string $className
*
* @throws CodeCoverageException
* @psalm-param class-string $className
*/
public function linesToBeUsed(string $className, string $methodName): array
{
Expand Down Expand Up @@ -219,28 +218,20 @@ public function shouldCodeCoverageBeCollectedFor(string $className, string $meth
$metadataForClass = Registry::parser()->forClass($className);
$metadataForMethod = Registry::parser()->forMethod($className, $methodName);

// If there is no @covers annotation but a @coversNothing annotation on
// the test method then code coverage data does not need to be collected
if ($metadataForMethod->isCoversNothing()->isNotEmpty()) {
return false;
}

// If there is at least one @covers annotation then
// code coverage data needs to be collected
if ($metadataForMethod->isCovers()->isNotEmpty() ||
$metadataForMethod->isCoversClass()->isNotEmpty() ||
$metadataForMethod->isCoversFunction()->isNotEmpty()) {
return true;
}

// If there is no @covers annotation but a @coversNothing annotation
// then code coverage data does not need to be collected
if ($metadataForClass->isCoversNothing()->isNotEmpty()) {
return false;
}

// If there is no @coversNothing annotation then
// code coverage data may be collected
return true;
}
}
10 changes: 5 additions & 5 deletions src/TextUI/Configuration/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ final class Configuration

private bool $reverseDefectList;

private bool $forceCoversAnnotation;
private bool $requireCoverageMetadata;

private bool $registerMockObjectsFromTestArgumentsRecursively;

Expand Down Expand Up @@ -189,7 +189,7 @@ final class Configuration
*/
private array $warnings;

public function __construct(?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $tooFewColumnsRequested, bool $loadPharExtensions, ?string $pharExtensionDirectory, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $convertDeprecationsToExceptions, bool $convertErrorsToExceptions, bool $convertNoticesToExceptions, bool $convertWarningsToExceptions, bool $processIsolation, bool $stopOnDefect, bool $stopOnError, bool $stopOnFailure, bool $stopOnWarning, bool $stopOnIncomplete, bool $stopOnRisky, bool $stopOnSkipped, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $verbose, bool $reverseDefectList, bool $forceCoversAnnotation, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noInteraction, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileText, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logfileTestdoxXml, ?string $plainTextTrace, bool $defaultOutput, bool $teamCityOutput, bool $testDoxOutput, int $repeat, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, array $testdoxGroups, array $testdoxExcludeGroups, ?string $includePath, int $randomOrderSeed, bool $includeUncoveredFiles, ?string $xmlValidationErrors, array $warnings)
public function __construct(?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $tooFewColumnsRequested, bool $loadPharExtensions, ?string $pharExtensionDirectory, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $convertDeprecationsToExceptions, bool $convertErrorsToExceptions, bool $convertNoticesToExceptions, bool $convertWarningsToExceptions, bool $processIsolation, bool $stopOnDefect, bool $stopOnError, bool $stopOnFailure, bool $stopOnWarning, bool $stopOnIncomplete, bool $stopOnRisky, bool $stopOnSkipped, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $verbose, bool $reverseDefectList, bool $requireCoverageMetadata, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noInteraction, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileText, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logfileTestdoxXml, ?string $plainTextTrace, bool $defaultOutput, bool $teamCityOutput, bool $testDoxOutput, int $repeat, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, array $testdoxGroups, array $testdoxExcludeGroups, ?string $includePath, int $randomOrderSeed, bool $includeUncoveredFiles, ?string $xmlValidationErrors, array $warnings)
{
$this->configurationFile = $configurationFile;
$this->bootstrap = $bootstrap;
Expand Down Expand Up @@ -248,7 +248,7 @@ public function __construct(?string $configurationFile, ?string $bootstrap, bool
$this->disallowTestOutput = $disallowTestOutput;
$this->verbose = $verbose;
$this->reverseDefectList = $reverseDefectList;
$this->forceCoversAnnotation = $forceCoversAnnotation;
$this->requireCoverageMetadata = $requireCoverageMetadata;
$this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively;
$this->noInteraction = $noInteraction;
$this->executionOrder = $executionOrder;
Expand Down Expand Up @@ -754,9 +754,9 @@ public function reverseDefectList(): bool
return $this->reverseDefectList;
}

public function forceCoversAnnotation(): bool
public function requireCoverageMetadata(): bool
{
return $this->forceCoversAnnotation;
return $this->requireCoverageMetadata;
}

public function registerMockObjectsFromTestArgumentsRecursively(): bool
Expand Down
6 changes: 3 additions & 3 deletions src/TextUI/Configuration/Merger.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlC
if ($cliConfiguration->hasStrictCoverage()) {
$strictCoverage = $cliConfiguration->strictCoverage();
} else {
$strictCoverage = $xmlConfiguration->phpunit()->beStrictAboutCoversAnnotation();
$strictCoverage = $xmlConfiguration->phpunit()->beStrictAboutCoverageMetadata();
}

if ($cliConfiguration->hasDisallowTestOutput()) {
Expand All @@ -360,7 +360,7 @@ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlC
$reverseDefectList = $xmlConfiguration->phpunit()->reverseDefectList();
}

$forceCoversAnnotation = $xmlConfiguration->phpunit()->forceCoversAnnotation();
$requireCoverageMetadata = $xmlConfiguration->phpunit()->requireCoverageMetadata();
$registerMockObjectsFromTestArgumentsRecursively = $xmlConfiguration->phpunit()->registerMockObjectsFromTestArgumentsRecursively();

if ($cliConfiguration->hasNoInteraction()) {
Expand Down Expand Up @@ -606,7 +606,7 @@ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlC
$disallowTestOutput,
$verbose,
$reverseDefectList,
$forceCoversAnnotation,
$requireCoverageMetadata,
$registerMockObjectsFromTestArgumentsRecursively,
$noInteraction,
$executionOrder,
Expand Down
4 changes: 2 additions & 2 deletions src/TextUI/Configuration/Xml/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ final class Generator
bootstrap="{bootstrap_script}"
cacheDirectory="{cache_directory}"
executionOrder="depends,defects"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true"
Expand Down
20 changes: 18 additions & 2 deletions src/TextUI/Configuration/Xml/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,22 @@ private function phpunit(string $filename, DOMDocument $document): PHPUnit
$backupStaticProperties = $this->getBooleanAttribute($document->documentElement, 'backupStaticAttributes', false);
}

$requireCoverageMetadata = false;

if ($document->documentElement->hasAttribute('requireCoverageMetadata')) {
$requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'requireCoverageMetadata', false);
} elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
$requireCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'forceCoversAnnotation', false);
}

$beStrictAboutCoverageMetadata = false;

if ($document->documentElement->hasAttribute('beStrictAboutCoverageMetadata')) {
$beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoverageMetadata', false);
} elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) {
$beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', false);
}

return new PHPUnit(
$cacheDirectory,
$this->getBooleanAttribute($document->documentElement, 'cacheResult', true),
Expand All @@ -778,7 +794,7 @@ private function phpunit(string $filename, DOMDocument $document): PHPUnit
$this->getBooleanAttribute($document->documentElement, 'convertErrorsToExceptions', true),
$this->getBooleanAttribute($document->documentElement, 'convertNoticesToExceptions', true),
$this->getBooleanAttribute($document->documentElement, 'convertWarningsToExceptions', true),
$this->getBooleanAttribute($document->documentElement, 'forceCoversAnnotation', false),
$requireCoverageMetadata,
$bootstrap,
$this->getBooleanAttribute($document->documentElement, 'processIsolation', false),
$this->getBooleanAttribute($document->documentElement, 'failOnEmptyTestSuite', false),
Expand All @@ -797,7 +813,7 @@ private function phpunit(string $filename, DOMDocument $document): PHPUnit
$this->getBooleanAttribute($document->documentElement, 'beStrictAboutChangesToGlobalState', false),
$this->getBooleanAttribute($document->documentElement, 'beStrictAboutOutputDuringTests', false),
$this->getBooleanAttribute($document->documentElement, 'beStrictAboutTestsThatDoNotTestAnything', true),
$this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', false),
$beStrictAboutCoverageMetadata,
$this->getBooleanAttribute($document->documentElement, 'enforceTimeLimit', false),
$this->getIntegerAttribute($document->documentElement, 'defaultTimeLimit', 1),
$this->getIntegerAttribute($document->documentElement, 'timeoutForSmallTests', 1),
Expand Down
Loading

0 comments on commit 0c65a47

Please sign in to comment.