Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A check for author tag is implemented. Some tests for it are added. #52

Merged
merged 1 commit into from
Jun 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {

}
}