Skip to content

Commit

Permalink
Commenting/CodeCoverageIgnoreDeprecated: check OO docblocks too
Browse files Browse the repository at this point in the history
As things were, the `Yoast.Commenting.CodeCoverageIgnoreDeprecated` sniff only checked function docblocks to find a `@deprecated` tag and verify this was accompanied by a `@codeCoverageIgnore` tag.

However, if a complete class (or other OO structure) is deprecated, we can also safely ignore it for code coverage checking.

This updates the sniff to also check the docblocks of OO structures for `@deprecated` tags and verifies that, if those are found, they are accompanied by a `@codeCoverageIgnore` tag.

Two exceptions are made:
* The rule does not apply to interfaces as those can't contain code, so code coverage is not relevant.
* The rule does not apply to anonymous classes. Those are treated the same as closures/arrow functions: those are normally nested within another construct and code coverage should be based on the wrapping construct.

Includes tests.
  • Loading branch information
jrfnl committed Nov 4, 2023
1 parent e152f2f commit 66ee5cb
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
>
<standard>
<![CDATA[
Deprecated functions and methods should be ignored for code coverage calculations.
Deprecated OO structures, functions and methods should be ignored for code coverage calculations.
]]>
</standard>
<code_comparison>
Expand Down
23 changes: 17 additions & 6 deletions Yoast/Sniffs/Commenting/CodeCoverageIgnoreDeprecatedSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Tokens\Collections;

/**
* Verifies functions which are marked as `deprecated` have a `codeCoverageIgnore` tag
* Verifies functions/OO structures which are marked as `deprecated` have a `codeCoverageIgnore` tag
* in their docblock.
*
* @since 1.1.0
* @since 3.0.0 Not just checks function docblocks, but also class/OO docblocks.
*/
final class CodeCoverageIgnoreDeprecatedSniff implements Sniff {

Expand All @@ -20,9 +22,13 @@ final class CodeCoverageIgnoreDeprecatedSniff implements Sniff {
* @return array<int|string>
*/
public function register() {
return [
\T_FUNCTION,
];
$targets = Tokens::$ooScopeTokens;
// Ignore interfaces as they can't contain code. Ignore anon classes as they are normally nested in another construct.
unset( $targets[ \T_ANON_CLASS ], $targets[ \T_INTERFACE ] );

$targets[ \T_FUNCTION ] = \T_FUNCTION;

return $targets;
}

/**
Expand All @@ -37,7 +43,12 @@ public function process( File $phpcsFile, $stackPtr ) {

$tokens = $phpcsFile->getTokens();

$ignore = Tokens::$methodPrefixes;
if ( $tokens[ $stackPtr ]['code'] === \T_FUNCTION ) {
$ignore = Tokens::$methodPrefixes;
}
else {
$ignore = Collections::classModifierKeywords();
}
$ignore[ \T_WHITESPACE ] = \T_WHITESPACE;

for ( $commentEnd = ( $stackPtr - 1 ); $commentEnd >= 0; $commentEnd-- ) {
Expand Down Expand Up @@ -69,7 +80,7 @@ public function process( File $phpcsFile, $stackPtr ) {
}

if ( $deprecated === false ) {
// Not a deprecated function.
// Not a deprecated function/OO structure.
return;
}

Expand Down
93 changes: 93 additions & 0 deletions Yoast/Tests/Commenting/CodeCoverageIgnoreDeprecatedUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,96 @@ abstract class SomeThing {
#[fietsbel /*comment*/]
public function inlineCommentWithinAttribute() {}
}

/**
* Description.
*
* @deprecated
*/
class C_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
*/
abstract class C_IsDeprecatedNotIgnoredAbstract {}

/**
* Description.
*
* @deprecated
*/
#[AllowDynamicProperties]
final class C_IsDeprecatedNotIgnoredFinal {}

/**
* Description.
*
* @deprecated
*/
readonly class C_IsDeprecatedNotIgnoredReadonly {}

/**
* Description.
*
* @deprecated
*/
final readonly class C_IsDeprecatedNotIgnoredFinalReadonly {}

/**
* Description.
*
* @codeCoverageIgnore
* @deprecated
*/
readonly final class C_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
#[MyAttribute, AnotherAttribute]
interface I_IsDeprecatedNotIgnored {}

/**
* @codeCoverageIgnore
* @deprecated
*/
interface I_IsDeprecatedAndIgnored {}

/**
* Description.
*
* @deprecated
*/
trait T_IsDeprecatedNotIgnored {}

/**
* @deprecated
* codeCoverageIgnore
*/
trait T_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
enum E_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
* @codeCoverageIgnore
*/
enum E_IsDeprecatedAndIgnored {}

/**
* Not necessarily correct, but as this is an anomymous class, this won't be flagged
* same as closures/arrow functions won't be flagged.
*
* @deprecated
*/
$anon = new
#[AllowDynamicProperties]
#[AnotherAttribute([1, 2, 3])]
class {};
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,96 @@ abstract class SomeThing {
#[fietsbel /*comment*/]
public function inlineCommentWithinAttribute() {}
}

/**
* Description.
*
* @deprecated
*/
class C_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
*/
abstract class C_IsDeprecatedNotIgnoredAbstract {}

/**
* Description.
*
* @deprecated
*/
#[AllowDynamicProperties]
final class C_IsDeprecatedNotIgnoredFinal {}

/**
* Description.
*
* @deprecated
*/
readonly class C_IsDeprecatedNotIgnoredReadonly {}

/**
* Description.
*
* @deprecated
*/
final readonly class C_IsDeprecatedNotIgnoredFinalReadonly {}

/**
* Description.
*
* @codeCoverageIgnore
* @deprecated
*/
readonly final class C_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
#[MyAttribute, AnotherAttribute]
interface I_IsDeprecatedNotIgnored {}

/**
* @codeCoverageIgnore
* @deprecated
*/
interface I_IsDeprecatedAndIgnored {}

/**
* Description.
*
* @deprecated
*/
trait T_IsDeprecatedNotIgnored {}

/**
* @deprecated
* @codeCoverageIgnore
*/
trait T_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
enum E_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
* @codeCoverageIgnore
*/
enum E_IsDeprecatedAndIgnored {}

/**
* Not necessarily correct, but as this is an anomymous class, this won't be flagged
* same as closures/arrow functions won't be flagged.
*
* @deprecated
*/
$anon = new
#[AllowDynamicProperties]
#[AnotherAttribute([1, 2, 3])]
class {};
18 changes: 13 additions & 5 deletions Yoast/Tests/Commenting/CodeCoverageIgnoreDeprecatedUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,19 @@ final class CodeCoverageIgnoreDeprecatedUnitTest extends AbstractSniffUnitTest {
*/
public function getErrorList(): array {
return [
41 => 1,
50 => 1,
55 => 1,
69 => 1,
90 => 1,
41 => 1,
50 => 1,
55 => 1,
69 => 1,
90 => 1,
98 => 1,
105 => 1,
113 => 1,
120 => 1,
127 => 1,
154 => 1,
158 => 1,
165 => 1,
];
}

Expand Down

0 comments on commit 66ee5cb

Please sign in to comment.