forked from sevntu-checkstyle/sevntu.checkstyle
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes sevntu-checkstyle#83. NameConventionForTestsCheck was implemented
- Loading branch information
Showing
13 changed files
with
669 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
221 changes: 221 additions & 0 deletions
221
...src/main/java/com/github/sevntu/checkstyle/checks/coding/NameConvensionForTestsCheck.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code for adherence to a set of rules. | ||
// Copyright(C) 2001-2012 Oliver Burn | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
//////////////////////////////////////////////////////////////////////////////// | ||
package com.github.sevntu.checkstyle.checks.coding; | ||
|
||
import java.util.regex.Pattern; | ||
import com.puppycrawl.tools.checkstyle.api.Check; | ||
import com.puppycrawl.tools.checkstyle.api.DetailAST; | ||
import com.puppycrawl.tools.checkstyle.api.TokenTypes; | ||
|
||
/** | ||
* This check verifies the name of JUnit test class for compliance with the | ||
* Convention names. Usually class can be named "Test*", "*Test", "*TestCase" or | ||
* "*IT" (the latter is for integration tests), but you can provide you own | ||
* regexp to match 'valid' names of UTs classes. | ||
* @author <a href="mailto:denant0vz@gmail.com">Denis Antonenkov</a> | ||
*/ | ||
|
||
public class NameConvensionForTestsCheck extends Check | ||
{ | ||
/** | ||
* The key is pointing to the message text String in | ||
* "messages.properties file". | ||
*/ | ||
public static final String MSG_KEY = "name.convension.for.tests"; | ||
/** | ||
* Pattern object is used to store the regexp for the names of classes, that | ||
* could be named "Test*", "*Test", "*TestCase" or "*IT", but you can | ||
* provide you own regexp to match 'valid' names of UTs classes. | ||
*/ | ||
private Pattern mValidTestClassNameRegex = Pattern | ||
.compile(".+Test|Test.+|.+IT|.+TestCase"); | ||
|
||
/** | ||
* True, if the current class is Junit3 test. | ||
*/ | ||
private boolean mIsCurrentClassJUnit3Test; | ||
|
||
/** | ||
* True, f the current node is not related to the nodes of the test class. | ||
* Skip processing for the node. | ||
*/ | ||
private boolean mSkipCurrentNodeProcessing; | ||
|
||
/** | ||
* A current ClassDef AST is being processed by check. | ||
*/ | ||
private DetailAST mCurrentClassNode; | ||
|
||
/** | ||
* Sets 'valid' class name regexp for Uts. | ||
* @param aValidTestClassNameRegex | ||
* regexp to match 'valid' unit test class names. | ||
*/ | ||
public void setValidTestClassNameRegex( | ||
String aValidTestClassNameRegex) | ||
{ | ||
if (aValidTestClassNameRegex != null) { | ||
mValidTestClassNameRegex = Pattern | ||
.compile(aValidTestClassNameRegex); | ||
} | ||
|
||
} | ||
|
||
@Override | ||
public int[] getDefaultTokens() | ||
{ | ||
return new int[] {TokenTypes.CLASS_DEF, TokenTypes.METHOD_DEF, }; | ||
} | ||
|
||
@Override | ||
public void finishTree(DetailAST aRootAST) | ||
{ | ||
mCurrentClassNode = null; | ||
mSkipCurrentNodeProcessing = false; | ||
mIsCurrentClassJUnit3Test = false; | ||
} | ||
|
||
@Override | ||
public void visitToken(DetailAST aNode) | ||
{ | ||
if (!mSkipCurrentNodeProcessing) { | ||
switch (aNode.getType()) { | ||
case TokenTypes.CLASS_DEF: | ||
if (mCurrentClassNode == null) { | ||
mCurrentClassNode = aNode; | ||
mIsCurrentClassJUnit3Test = isExtendsClass( | ||
mCurrentClassNode, | ||
"TestCase"); | ||
} | ||
break; | ||
case TokenTypes.METHOD_DEF: | ||
if (hasCurrentClassNodeAsParent(aNode) | ||
&& isJUnitTestMethod(aNode) | ||
&& hasWrongName(mCurrentClassNode)) | ||
{ | ||
log(mCurrentClassNode.getLineNo(), MSG_KEY, | ||
mValidTestClassNameRegex); | ||
mSkipCurrentNodeProcessing = true; | ||
} | ||
break; | ||
default: | ||
throw new IllegalArgumentException("Node of type " | ||
+ aNode.getType() + " is not supименported"); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Returns true, if the current class extends class with specified | ||
* aClassName. | ||
* @param aClassDefNode | ||
* the node of class definition. | ||
* @param aClassName | ||
* the name of a extended class | ||
* @return True, if class extends class with specified aClassName. | ||
*/ | ||
private static boolean isExtendsClass( | ||
final DetailAST aClassDefNode, String aClassName) | ||
{ | ||
final DetailAST extendsNode = aClassDefNode | ||
.findFirstToken(TokenTypes.EXTENDS_CLAUSE); | ||
if (extendsNode != null) { | ||
final DetailAST dotNode = extendsNode | ||
.findFirstToken(TokenTypes.DOT); | ||
return dotNode != null | ||
&& aClassName.equals(getIdentText(dotNode)) | ||
|| dotNode == null | ||
&& aClassName.equals(getIdentText(extendsNode)); | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Returns true, if current class is a parent of aMethodDefNode. | ||
* @param aMethodDefNode | ||
* the node of method definition. | ||
* @return True, if current class is a parent of aMethodDefNode. | ||
*/ | ||
private boolean hasCurrentClassNodeAsParent(DetailAST aMethodDefNode) | ||
{ | ||
return aMethodDefNode.getParent().getParent().equals(mCurrentClassNode); | ||
} | ||
|
||
/** | ||
* Returns true, if the current method is JUnit test. | ||
* @param aMethodDefNode | ||
* the node of method definition. | ||
* @return True, if the current method is JUnit test. | ||
*/ | ||
private boolean isJUnitTestMethod(DetailAST aMethodDefNode) | ||
{ | ||
return isJUnit4Test(aMethodDefNode) || isJUnit3Test(aMethodDefNode); | ||
} | ||
|
||
/** | ||
* Returns true, if the class is not the correct name. | ||
* @param aJUnitTestClassDefNode | ||
* the node of class JUnit test. | ||
* @return True, if the class is not the correct name. | ||
*/ | ||
private boolean hasWrongName(final DetailAST aJUnitTestClassDefNode) | ||
{ | ||
final String className = getIdentText(aJUnitTestClassDefNode); | ||
return !mValidTestClassNameRegex.matcher(className).matches(); | ||
} | ||
|
||
/** | ||
* Returns true, if the method refers to methods of Junit3 test. | ||
* @param aMethodDefNode | ||
* the node of method definition. | ||
* @return True, if the method refers to methods of JUnit3 test. | ||
*/ | ||
private boolean isJUnit3Test(DetailAST aMethodDefNode) | ||
{ | ||
return mIsCurrentClassJUnit3Test | ||
&& getIdentText(aMethodDefNode).startsWith("test"); | ||
} | ||
|
||
/** | ||
* Returns true, if the method refers to methods of JUnit4 test. | ||
* @param aMethodDefNode | ||
* the node of method definition. | ||
* @return True, if the method refers to methods of JUnit4 test. | ||
*/ | ||
private static boolean isJUnit4Test(final DetailAST aMethodDefNode) | ||
{ | ||
final DetailAST modifiersNode = aMethodDefNode | ||
.findFirstToken(TokenTypes.MODIFIERS); | ||
final DetailAST annotationNode = modifiersNode | ||
.findFirstToken(TokenTypes.ANNOTATION); | ||
return annotationNode != null | ||
&& "Test".equals(getIdentText(annotationNode)); | ||
} | ||
|
||
/** | ||
* Returns the text identifier for the node containing the identifier. | ||
* @param aNodeWithIdent | ||
* the node containing identifier. | ||
* @return Returns the text identifier for the node containing the | ||
* identifier. | ||
*/ | ||
private static String getIdentText(DetailAST aNodeWithIdent) | ||
{ | ||
return aNodeWithIdent.findFirstToken(TokenTypes.IDENT).getText(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...test/java/com/github/sevntu/checkstyle/checks/coding/NameConvensionForTestsCheckTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code for adherence to a set of rules. | ||
// Copyright (C) 2001-2013 Oliver Burn | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
//////////////////////////////////////////////////////////////////////////////// | ||
package com.github.sevntu.checkstyle.checks.coding; | ||
|
||
import java.text.MessageFormat; | ||
|
||
import org.junit.Test; | ||
|
||
import com.github.sevntu.checkstyle.BaseCheckTestSupport; | ||
import com.puppycrawl.tools.checkstyle.DefaultConfiguration; | ||
|
||
/** | ||
* @author <a href="mailto:denant0vz@gmail.com">Denis Antonenkov</a> | ||
*/ | ||
public class NameConvensionForTestsCheckTest extends BaseCheckTestSupport | ||
{ | ||
|
||
private final String msgClass = getCheckMessage( | ||
NameConvensionForTestsCheck.MSG_KEY); | ||
|
||
private final DefaultConfiguration mCheckConfig = createCheckConfig( | ||
NameConvensionForTestsCheck.class); | ||
|
||
@Test | ||
public void testExtendsTestCase() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests1.java"), | ||
expected); | ||
} | ||
|
||
@Test | ||
public void testClassIsNotTest() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests2.java"), | ||
expected); | ||
|
||
} | ||
|
||
@Test | ||
public void testClassJUnit4Test() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests3.java"), | ||
expected); | ||
} | ||
|
||
@Test | ||
public void testEnum() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests4.java"), expected); | ||
} | ||
|
||
@Test | ||
public void testInterface() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests5.java"), expected); | ||
} | ||
|
||
@Test | ||
public void testNestedEnums() throws Exception | ||
{ | ||
final String[] expected = {buildMesssage("1", | ||
".+Test|Test.+|.+IT|.+TestCase"), }; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests6.java"), expected); | ||
} | ||
|
||
@Test | ||
public void testAttribute() throws Exception | ||
{ | ||
mCheckConfig.addAttribute("validTestClassNameRegex", "Hello*"); | ||
final String[] expected = {buildMesssage("15", "Hello*"), }; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests7.java"), | ||
expected); | ||
} | ||
|
||
@Test | ||
public void testQualifiedNameExtends() throws Exception | ||
{ | ||
final String[] expected = {}; | ||
verify(mCheckConfig, | ||
getPath("InputNameConvensionForTests8.java"), | ||
expected); | ||
} | ||
|
||
private String buildMesssage(String aLineNumber, String aArguments) | ||
{ | ||
return aLineNumber + ": " + MessageFormat.format(msgClass, aArguments); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...st/resources/com/github/sevntu/checkstyle/checks/coding/InputNameConvensionForTests1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
public class InputNameConvensionForTestsCheckTestExtendsTestCase extends TestCase | ||
{ | ||
|
||
public void testTest() | ||
{ | ||
} | ||
|
||
public void testTestCase() | ||
{ | ||
} | ||
|
||
public void testIT() | ||
{ | ||
} | ||
|
||
public void testTest() | ||
{ | ||
} | ||
|
||
} |
Oops, something went wrong.