From 178812f1d75a8ccc75138afd6e05e38e5a611b43 Mon Sep 17 00:00:00 2001 From: "Mihaela K. Memova" Date: Wed, 5 Apr 2017 16:28:01 +0300 Subject: [PATCH] A check for author tag is implemented. Some tests for it are added. Signed-off-by: Mihaela Memova --- README.md | 2 +- .../analysis/checkstyle/AuthorTagCheck.java | 51 ++++++++ .../resources/rulesets/checkstyle/rules.xml | 34 +++-- .../checkstyle/test/AuthorTagCheckTest.java | 119 ++++++++++++++++++ .../NoAuthorOuterAndInnerClasses.java | 12 ++ .../NoJavaDocOuterAndInnerClasses.java | 6 + .../PresentAuthorTagOuterAndInnerClasses.java | 14 +++ 7 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/openhab/tools/analysis/checkstyle/AuthorTagCheck.java create mode 100644 src/test/java/org/openhab/tools/analysis/checkstyle/test/AuthorTagCheckTest.java create mode 100644 src/test/resources/checks/checkstyle/authorTagCheckTest/NoAuthorOuterAndInnerClasses.java create mode 100644 src/test/resources/checks/checkstyle/authorTagCheckTest/NoJavaDocOuterAndInnerClasses.java create mode 100644 src/test/resources/checks/checkstyle/authorTagCheckTest/PresentAuthorTagOuterAndInnerClasses.java diff --git a/README.md b/README.md index ec5065d4..e623f5e0 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,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`; diff --git a/src/main/java/org/openhab/tools/analysis/checkstyle/AuthorTagCheck.java b/src/main/java/org/openhab/tools/analysis/checkstyle/AuthorTagCheck.java new file mode 100644 index 00000000..27387ac4 --- /dev/null +++ b/src/main/java/org/openhab/tools/analysis/checkstyle/AuthorTagCheck.java @@ -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} + *

+ * 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); + } + } +} diff --git a/src/main/resources/rulesets/checkstyle/rules.xml b/src/main/resources/rulesets/checkstyle/rules.xml index 32630915..45d53558 100644 --- a/src/main/resources/rulesets/checkstyle/rules.xml +++ b/src/main/resources/rulesets/checkstyle/rules.xml @@ -3,11 +3,11 @@ "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> - @@ -18,10 +18,10 @@ - + - + + + + + + - + diff --git a/src/test/java/org/openhab/tools/analysis/checkstyle/test/AuthorTagCheckTest.java b/src/test/java/org/openhab/tools/analysis/checkstyle/test/AuthorTagCheckTest.java new file mode 100644 index 00000000..334e729f --- /dev/null +++ b/src/test/java/org/openhab/tools/analysis/checkstyle/test/AuthorTagCheckTest.java @@ -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; + } +} diff --git a/src/test/resources/checks/checkstyle/authorTagCheckTest/NoAuthorOuterAndInnerClasses.java b/src/test/resources/checks/checkstyle/authorTagCheckTest/NoAuthorOuterAndInnerClasses.java new file mode 100644 index 00000000..7d623c6f --- /dev/null +++ b/src/test/resources/checks/checkstyle/authorTagCheckTest/NoAuthorOuterAndInnerClasses.java @@ -0,0 +1,12 @@ +/** + * java-doc of the outer class + */ +class OuterClass { + + /** + * java-doc of the inner class + */ + private class InnerClass { + + } +} diff --git a/src/test/resources/checks/checkstyle/authorTagCheckTest/NoJavaDocOuterAndInnerClasses.java b/src/test/resources/checks/checkstyle/authorTagCheckTest/NoJavaDocOuterAndInnerClasses.java new file mode 100644 index 00000000..bddaed9c --- /dev/null +++ b/src/test/resources/checks/checkstyle/authorTagCheckTest/NoJavaDocOuterAndInnerClasses.java @@ -0,0 +1,6 @@ +class NoAuthorOuterClass { + + private class NoAuthorInnerClass { + + } +} diff --git a/src/test/resources/checks/checkstyle/authorTagCheckTest/PresentAuthorTagOuterAndInnerClasses.java b/src/test/resources/checks/checkstyle/authorTagCheckTest/PresentAuthorTagOuterAndInnerClasses.java new file mode 100644 index 00000000..deaa3abb --- /dev/null +++ b/src/test/resources/checks/checkstyle/authorTagCheckTest/PresentAuthorTagOuterAndInnerClasses.java @@ -0,0 +1,14 @@ +/** + * + * @author Author of the outer class + * + */ +public class OuterClass { + + /** + * @author author of the inner class + */ + private class InnerClass { + + } +}