Skip to content

Commit

Permalink
Merge pull request #104 from WordPoints/develop
Browse files Browse the repository at this point in the history
2.3.0
  • Loading branch information
JDGrimes committed Nov 9, 2015
2 parents b1ad6e8 + c97c464 commit 6b50cc8
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 3 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
And as you can see, we [keep a CHANGELOG](http://keepachangelog.com/).

## [2.3.0] - 2015-11-09
### Added
- `WordPoints.PHPUnit.MissingCovers` sniff to flag tests missing `@covers`
annotations (#74).
- `Squiz.Scope.MethodScope` and `Squiz.WhiteSpace.ScopeKeywordSpacing` sniffs (#101).

### Removed
- `WordPress.VIP.RestrictedFunctions.custom_role` error (#102).

### Fixed
- `xmllint` sniffing when multiple XML files are present (#103).

## [2.2.0] - 2015-10-30
### Added
- `WordPoints.PHP.RequiredParentMethodCall` sniff to flag missing calls to
Expand Down Expand Up @@ -157,6 +169,7 @@ automatically installed if there is a config file for it. #23
- Initial code.

[Unreleased]: https://github.com/WordPoints/dev-lib/compare/master...develop
[2.3.0]: https://github.com/WordPoints/dev-lib/compare/2.2.0...2.3.0
[2.2.0]: https://github.com/WordPoints/dev-lib/compare/2.1.1...2.2.0
[2.1.1]: https://github.com/WordPoints/dev-lib/compare/2.1.0...2.1.1
[2.1.0]: https://github.com/WordPoints/dev-lib/compare/2.0.4...2.1.0
Expand Down
4 changes: 2 additions & 2 deletions bin/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ wpdl-codesniff-xmllint() {
local files=$(find "${CODESNIFF_PATH[@]}" -type f \( -name '*.xml' -o -name '*.xml.dist' \))

if [ ${#files[@]} != 0 ]; then
xmllint --noout "${files[@]}"
xmllint --noout ${files[@]}
fi
}

Expand Down Expand Up @@ -161,4 +161,4 @@ wpdl-phpunit-ms-network-ajax() {
WORDPOINTS_NETWORK_ACTIVE=1 WP_MULTISITE=1 wpdl-test-phpunit ajax ms-network
}

# EOF
# EOF
119 changes: 119 additions & 0 deletions phpcs/WordPoints/Sniffs/PHPUnit/MissingCoversSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

/**
* WordPoints PHPUnit Missing Covers Sniff class.
*
* @package WordPoints_Dev_Lib
* @since 2.3.0
*/

/**
* Sniff for missing @covers annotations on PHPUnit tests.
*
* @since 2.3.0
*/
class WordPoints_Sniffs_PHPUnit_MissingCoversSniff implements PHP_CodeSniffer_Sniff {

/**
* @since 2.3.0
*/
public function register() {
return array( T_CLASS, T_FUNCTION );
}

/**
* @since 2.3.0
*/
public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {

$tokens = $phpcsFile->getTokens();

$is_class = ! $is_function = T_FUNCTION === $tokens[ $stackPtr ]['code'];

$scope_closer = $tokens[ $stackPtr ]['scope_closer'];

if ( $is_function ) {

$function_name = $phpcsFile->getDeclarationName( $stackPtr );

// If this isn't a test method, we don't need to check it.
if ( 'test' !== substr( $function_name, 0, 4 ) ) {
return $scope_closer;
}

$class = $phpcsFile->getCondition( $stackPtr, T_CLASS );

// If it isn't in a class, we don't need to check it.
if ( ! $class ) {
return $scope_closer;
}
}

// Find the previous token (excluding scope modifiers and whitespace).
$exclude = PHP_CodeSniffer_Tokens::$methodPrefixes;
$exclude[] = T_WHITESPACE;

$comment_closer = $phpcsFile->findPrevious( $exclude, $stackPtr - 1, 0, $exclude );

// If the token isn't the close of a doc comment, there is no doc comment for
// this item, and therefore no annotations.
if ( T_DOC_COMMENT_CLOSE_TAG !== $tokens[ $comment_closer ]['code'] ) {

if ( $is_function ) {

$phpcsFile->addError(
'Missing PHPUnit code coverage annotation.'
, $stackPtr
, 'NoDocComment'
);

return $scope_closer;
}

return null;
}

// Now check if the docblock contains the required annotations.
$comment_opener = $tokens[ $comment_closer ]['comment_opener'];

$has_annotation = false;

foreach ( $tokens[ $comment_opener ]['comment_tags'] as $tag ) {

$tag_name = $tokens[ $tag ]['content'];

if ( '@covers' === $tag_name || '@coversNothing' === $tag_name ) {
$has_annotation = true;
break;
}
}

if ( ! $has_annotation ) {

if ( $is_class ) {

// Classes don't have to have the annotation, so this is OK. However,
// each method will have to have it.
return null;

} elseif ( $is_function ) {

$phpcsFile->addError(
'Missing PHPUnit code coverage annotation.'
, $stackPtr
, 'MissingAnnotation'
);
}
}

// We skip to the end of the class/function. If we're in a class and we're
// still here, we found the annotation, so we don't need to check each
// method. If we're in a function, we don't need to test any sub-functions
// either, since they won't be test methods.
return $scope_closer;

} // public function process()

} // class WordPoints_Sniffs_PHPUnit_MissingCoversSniff

// EOF
151 changes: 151 additions & 0 deletions phpcs/WordPoints/Tests/PHPUnit/MissingCoversUnitTest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

/**
* Class Has_Annotation
*
* @since 1.0.0
*
* @covers Something
*/
class Has_Annotation {

/**
* A test.
*
* @since 1.0.0
*
* @covers Something::tt
*/
public function test_has_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*
* @coversNothing
*/
public function test_has_nothing_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*/
public function test_no_annotation() {} // OK

public function test_no_doc_comment() {} // OK
public function not_a_test() {} // OK
}

/**
* Class Has_Nothing_Annotation
*
* @since 1.0.0
*
* @coversNothing
*/
class Has_Nothing_Annotation {

/**
* A test.
*
* @since 1.0.0
*
* @covers Something::tt
*/
public function test_has_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*
* @coversNothing
*/
public function test_has_nothing_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*/
public function test_no_annotation() {} // OK

public function test_no_doc_comment() {} // OK
public function not_a_test() {} // OK
}

/**
* Class Has_No_Annotation
*
* @since 1.0.0
*/
class Has_No_Annotation {

/**
* A test.
*
* @since 1.0.0
*
* @covers Something::tt
*/
public function test_has_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*
* @coversNothing
*/
public function test_has_nothing_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*/
public function test_no_annotation() {} // Bad

public function test_no_doc_comment() {} // Bad
public function not_a_test() {} // OK
}

class Has_No_Doc_Comment {

/**
* A test.
*
* @since 1.0.0
*
* @covers Something::tt
*/
public function test_has_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*
* @coversNothing
*/
public function test_has_nothing_annotation() {} // OK

/**
* A test.
*
* @since 1.0.0
*/
public function test_no_annotation() {} // Bad

public function test_no_doc_comment() {} // Bad
public function not_a_test() {} // OK
}

/**
* Not a test.
*
* @since 1.0.0
*/
function test_not_in_class() {} // OK
38 changes: 38 additions & 0 deletions phpcs/WordPoints/Tests/PHPUnit/MissingCoversUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* Unit test class for the missing covers sniff.
*
* @package WordPoints_Dev_Lib\Tests
* @since 2.3.0
*/

/**
* Unit test class for the missing covers sniff.
*
* @since 2.3.0
*/
class WordPoints_Tests_PHPUnit_MissingCoversUnitTest extends AbstractSniffUnitTest {

/**
* @since 2.3.0
*/
public function getErrorList() {

return array(
109 => 1,
111 => 1,
140 => 1,
142 => 1,
);
}

/**
* @since 2.3.0
*/
public function getWarningList() {
return array();
}
}

// EOF
11 changes: 10 additions & 1 deletion phpcs/WordPoints/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<rule ref="WordPress-VIP">
<exclude name="WordPress.VIP.RestrictedFunctions.switch_to_blog" />
<exclude name="WordPress.VIP.RestrictedFunctions.custom_role" />
<exclude name="WordPress.VIP.SuperGlobalInputUsage" />
<exclude name="WordPress.VIP.DirectDatabaseQuery.SchemaChange" />
<exclude name="WordPress.VIP.DirectDatabaseQuery.DirectQuery" />
Expand Down Expand Up @@ -92,7 +93,15 @@
<rule ref="WordPress.WP.PreparedSQL">
<exclude-pattern>/tests/*</exclude-pattern>
</rule>

<rule ref="WordPoints.PHPUnit.MissingCovers">
<exclude-pattern>^((?!(.*/MissingCoversUnitTest\.inc$|/tests/phpunit/tests/.*)))</exclude-pattern>
</rule>

<exclude-pattern>/vendor/*,/dev-lib/*</exclude-pattern>
<rule ref="Squiz.Scope.MethodScope"/>
<rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/>

<exclude-pattern>/vendor/*</exclude-pattern>
<exclude-pattern>/dev-lib/*</exclude-pattern>

</ruleset>

0 comments on commit 6b50cc8

Please sign in to comment.