Skip to content

Commit

Permalink
A check for author tag is implemented.
Browse files Browse the repository at this point in the history
Some tests for it are added.
Added filter for auto generated classes.

Also-by: Svilen Valkanov <[email protected]>
Signed-off-by: Mihaela Memova <[email protected]>
  • Loading branch information
Mihaela K. Memova authored and Svilen Valkanov committed Jun 13, 2017
1 parent 46e7853 commit f88075c
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ For more information: https://pmd.github.io/pmd-5.4.1/customizing/rule-guideline
1. [The Java naming conventions should be used.](https://github.com/openhab/static-code-analysis/blob/master/src/main/resources/rulesets/checkstyle/rules.xml#L80) - `severity=info`
2. [Every Java file must have a license header. You can run mvn license:format on the root of the repo to automatically add missing headers.](https://github.com/openhab/static-code-analysis/blob/master/src/main/resources/rulesets/checkstyle/rules.xml#L34) - `severity=info`
3. [Every class, interface and enumeration should have JavaDoc describing its purpose and usage.](https://github.com/openhab/static-code-analysis/blob/master/src/main/resources/rulesets/checkstyle/rules.xml#L66) - `severity=warning`
4. Every class, interface and enumeration must have an @author tag in its JavaDoc for every author that wrote a substantial part of the file. - `Work in Progress`
4. [Every class, interface and enumeration must have an @author tag in its JavaDoc for every author that wrote a substantial part of the file.](https://github.com/openhab/static-code-analysis/blob/master/src/main/resources/rulesets/checkstyle/rules.xml#L97) - `severity=error`
5. Every constant, field and method with default, protected or public visibility should have JavaDoc (optional, but encouraged for private visibility as well). - `Not covered yet`
6. The code must be formatted:
- java files must use spaces for formatting, rather than tabs - `severity=error`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2010-2017 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.tools.analysis.checkstyle;

import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.checks.javadoc.WriteTagCheck;

/**
* Checks if a class/interface/enumeration has an author tag
*
* @author Mihaela Memova
*
*/
public class AuthorTagCheck extends WriteTagCheck {

/**
* Indicates whether the inner classes/interfaces/enumerations (briefly
* called units) should be checked for an author tag. It is a configuration
* property and can be changed through the check's configuration.
*/
private boolean checkInnerUnits;

public void setCheckInnerUnits(boolean checkInnerUnits) {
this.checkInnerUnits = checkInnerUnits;
}

/**
* {@inheritDoc}
* <p>
* Calls the {@link WriteTagCheck#visitToken(DetailAST)} taking into
* consideration the check configuration
*/
@Override
public void visitToken(DetailAST ast) {
if (!checkInnerUnits) {
DetailAST astParent = ast.getParent();
// if outer class/interface/enum
if (astParent == null) {
super.visitToken(ast);
}
} else {
super.visitToken(ast);
}
}
}
9 changes: 9 additions & 0 deletions src/main/resources/rulesets/checkstyle/rules.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@
<property name="processJavadoc" value="true"/>
<property name="severity" value="info" />
</module>

<module name="org.openhab.tools.analysis.checkstyle.AuthorTagCheck">
<property name="tag" value="@author"/>
<property name="tagFormat" value="\S"/> <!-- the tag can be anything but whitespace -->
<property name="checkInnerUnits" value="false"/>
<property name="severity" value="error"/> <!-- A property defining what should be done if the author is missing. In our case we want the build to fail. -->
<property name="tagSeverity" value="ignore"/> <!-- A property defining what should be done when the author tag is found. In our case we want to ignore it. -->
<message key="type.missingTag" value="An author tag is missing"/>
</module>

<!-- Rules for Java Naming Convention -->

Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/rulesets/checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@
<!-- Homematic and Tellstick bindings are creating and configuring things dynamically, they will log false positives for unused configuration -->
<!-- IO and Voice bundles have specific use cases - they use only the config .xml files and will log false positives as well -->
<suppress files=".+org.openhab.binding.homematic.+|.+org.openhab.binding.tellstick.+|.+org.openhab.io.+|.+org.openhab.voice.+" checks="EshInfXmlCheck"/>
<!-- All generated files will skip the author tag check -->
<suppress files=".+\\gen\\.+\.java" checks="AuthorTagCheck"/>
</suppressions>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package org.openhab.tools.analysis.checkstyle.test;

import java.io.File;

import org.junit.Test;
import org.openhab.tools.analysis.checkstyle.AuthorTagCheck;
import org.openhab.tools.analysis.checkstyle.api.AbstractStaticCheckTest;

import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;

/**
* Tests for {@link AuthorTagCheck}
*
* @author Mihaela Memova
*
*/
public class AuthorTagCheckTest extends AbstractStaticCheckTest {

private static final String EXPECTED_WARNING_MESSAGE = "An author tag is missing";

@Test
public void testOuterClassWithNoAuthorTag() throws Exception {

String fileName = "NoAuthorOuterAndInnerClasses.java";
/*
* an error is expected at the line where the outer class is declared
* in the file
*/
int warningLine = 4;
boolean checkInnerClasses = false;
checkFileForAuthorTags(checkInnerClasses, fileName, warningLine);
}

@Test
public void testOuterAndInnerClassesWithNoAuthorTag() throws Exception {

String fileName = "NoAuthorOuterAndInnerClasses.java";
/*
* errors are expected at the lines where the classes are declared in
* the file
*/
int firstWarningLine = 4;
int secondWarningLine = 9;
boolean checkInnerClasses = true;
checkFileForAuthorTags(checkInnerClasses, fileName, firstWarningLine, secondWarningLine);
}

@Test
public void testOuterClasWithNoJavaDoc() throws Exception {

String fileName = "NoJavaDocOuterAndInnerClasses.java";
/*
* an error is expected at the line where the outer class is declared
* in the file
*/
int warningLine = 1;
boolean checkInnerClasses = false;
checkFileForAuthorTags(checkInnerClasses, fileName, warningLine);
}

@Test
public void testOuterAndInnerClassesWithNoJavaDoc() throws Exception {

String fileName = "NoJavaDocOuterAndInnerClasses.java";
/*
* errors are expected at the lines where the classes are declared in
* the file
*/
int firstWarningLine = 1;
int secondWarningLine = 3;
boolean checkInnerClasses = true;
checkFileForAuthorTags(checkInnerClasses, fileName, firstWarningLine, secondWarningLine);
}

@Test
public void testOuterAndInnerClassesWithPresentAuthorTag() throws Exception {

String fileName = "PresentAuthorTagOuterAndInnerClasses.java";
boolean checkInnerClasses = true;
// no errors are expected so we don't pass any warning lines
checkFileForAuthorTags(checkInnerClasses, fileName);
}

private void checkFileForAuthorTags(boolean checkInnerUnits, String fileName, Integer... warningLine)
throws Exception {

String filePath = getPath("authorTagCheckTest"+ File.separator + fileName);
String[] expected = null;
if (warningLine.length > 0) {
expected = new String[warningLine.length];
for (int i = 0; i < warningLine.length; i++) {
expected[i] = warningLine[i] + ": " + EXPECTED_WARNING_MESSAGE;
}
} else {
expected = CommonUtils.EMPTY_STRING_ARRAY;
}

DefaultConfiguration configuration = createConfiguration(checkInnerUnits);
verify(configuration, filePath, expected);
}

private DefaultConfiguration createConfiguration(boolean checkInnerUnits) {

DefaultConfiguration configuration = createCheckConfig(AuthorTagCheck.class);
/*
* Modify the configuration with the needed attributes and message. They
* should be the same as their corresponding properties defined in
* rulesets.checkstyle/rules.xml file
*/
configuration.addAttribute("tag", "@author");
configuration.addAttribute("tagFormat", "\\S");
configuration.addAttribute("tagSeverity", "ignore");
configuration.addAttribute("checkInnerUnits", String.valueOf(checkInnerUnits));
configuration.addMessage("type.missingTag", EXPECTED_WARNING_MESSAGE);

return configuration;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* java-doc of the outer class
*/
class OuterClass {

/**
* java-doc of the inner class
*/
private class InnerClass {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class NoAuthorOuterClass {

private class NoAuthorInnerClass {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
*
* @author Author of the outer class
*
*/
public class OuterClass {

/**
* @author author of the inner class
*/
private class InnerClass {

}
}

0 comments on commit f88075c

Please sign in to comment.