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

Issue #28: fix broken rules test #50

Merged
merged 1 commit into from
Dec 24, 2016
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
7 changes: 7 additions & 0 deletions checkstyle-sonar-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.7</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,103 @@

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.Filter;
import com.puppycrawl.tools.checkstyle.guava.collect.ImmutableSet;
import com.puppycrawl.tools.checkstyle.guava.reflect.ClassPath;
import com.puppycrawl.tools.checkstyle.guava.reflect.ClassPath.ClassInfo;

public final class CheckUtil {
private CheckUtil() {
}

/**
* Gets the checkstyle's modules. Checkstyle's modules are nonabstract
* classes from com.puppycrawl.tools.checkstyle package which names end with
* 'Check', do not contain the word 'Input' (are not input files for UTs),
* checkstyle's filters and SuppressWarningsHolder class.
*
* @return a set of checkstyle's modules names.
* Gets all checkstyle's modules.
* @return the set of checkstyle's module classes.
* @throws IOException if the attempt to read class path resources failed.
* @see #isCheckstyleModule(Class)
*/
public static Set<Class<?>> getCheckstyleModules() throws IOException {
final Set<Class<?>> checkstyleModules = new HashSet<>();

// final ClassLoader loader = Thread.currentThread().getContextClassLoader();
// final ClassPath classpath = ClassPath.from(loader);
// final String packageName = "com.puppycrawl.tools.checkstyle.checks";
// final ImmutableSet<ClassPath.ClassInfo> checkstyleClasses = classpath
// .getTopLevelClassesRecursive(packageName);
//
// for (ClassPath.ClassInfo clazz : checkstyleClasses) {
// final Class<?> loadedClass = clazz.load();
// if (isCheckstyleModule(loadedClass)) {
// checkstyleModules.add(loadedClass);
// }
// }
final ClassLoader loader = Thread.currentThread()
.getContextClassLoader();
final ClassPath classpath = ClassPath.from(loader);
final String packageName = "com.puppycrawl.tools.checkstyle";
final ImmutableSet<ClassInfo> checkstyleClasses = classpath
.getTopLevelClassesRecursive(packageName);

for (ClassPath.ClassInfo clazz : checkstyleClasses) {
final Class<?> loadedClass = clazz.load();
if (isCheckstyleModule(loadedClass)) {
checkstyleModules.add(loadedClass);
}
}
return checkstyleModules;
} /**
* Checks whether a class may be considered as a checkstyle module. Checkstyle's modules are
* non-abstract classes, which names do not start with the word 'Input' (are not input files for
* UTs), and are either checkstyle's checks, file sets, filters, file filters, or root module.
* @param loadedClass class to check.
* @return true if the class may be considered as the checkstyle module.
*/
private static boolean isCheckstyleModule(Class<?> loadedClass) {
final String className = loadedClass.getSimpleName();
return isValidCheckstyleClass(loadedClass, className)
&& (isCheckstyleCheck(loadedClass)
|| isFileSetModule(loadedClass)
|| isFilterModule(loadedClass));
}

/**
* Checks whether a class extends 'AutomaticBean', is non-abstract, and doesn't start with the
* word 'Input' (are not input files for UTs).
* @param loadedClass class to check.
* @param className class name to check.
* @return true if a class may be considered a valid production class.
*/
public static boolean isValidCheckstyleClass(Class<?> loadedClass, String className) {
return AutomaticBean.class.isAssignableFrom(loadedClass)
&& !Modifier.isAbstract(loadedClass.getModifiers())
&& !className.contains("Input");
}

/**
* Checks whether a class may be considered as the checkstyle check.
* Checkstyle's checks are classes which implement 'AbstractCheck' interface.
* @param loadedClass class to check.
* @return true if a class may be considered as the checkstyle check.
*/
public static boolean isCheckstyleCheck(Class<?> loadedClass) {
return AbstractCheck.class.isAssignableFrom(loadedClass);
}

/**
* Checks whether a class may be considered as the checkstyle file set.
* Checkstyle's file sets are classes which implement 'AbstractFileSetCheck' interface.
* @param loadedClass class to check.
* @return true if a class may be considered as the checkstyle file set.
*/
public static boolean isFileSetModule(Class<?> loadedClass) {
return AbstractFileSetCheck.class.isAssignableFrom(loadedClass);
}

/**
* Checks whether a class may be considered as the checkstyle filter.
* Checkstyle's filters are classes which implement 'Filter' interface.
* @param loadedClass class to check.
* @return true if a class may be considered as the checkstyle filter.
*/
public static boolean isFilterModule(Class<?> loadedClass) {
return Filter.class.isAssignableFrom(loadedClass);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@

import org.apache.commons.beanutils.PropertyUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.puppycrawl.tools.checkstyle.TreeWalker;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
Expand All @@ -65,7 +65,6 @@ public final class ChecksTest {
);

@SuppressWarnings("static-method")
@Ignore
@Test
public void verifyTestConfigurationFiles() throws Exception {
final Set<Class<?>> modules = CheckUtil.getCheckstyleModules();
Expand Down Expand Up @@ -95,6 +94,10 @@ private static void validateSonarFile(Document document, Set<Class<?>> modules)
final String key = rule.getAttributes().getNamedItem("key").getTextContent();

final Class<?> module = findModule(modules, key);

if (CheckUtil.isFilterModule(module))
Assert.fail("Module should not be in sonar rules: " + module.getCanonicalName());

modules.remove(module);

Assert.assertNotNull("Unknown class found in sonar: " + key, module);
Expand All @@ -114,7 +117,7 @@ private static void validateSonarFile(Document document, Set<Class<?>> modules)
expectedConfigKey = "Checker/TreeWalker/" + moduleSimpleName.replaceAll("Check$", "");
}
else {
expectedConfigKey = "Checker/" + moduleSimpleName.replaceAll("Check$", "");;
expectedConfigKey = "Checker/" + moduleSimpleName.replaceAll("Check$", "");
}

Assert.assertNotNull(moduleName + " requires a configKey in sonar", configKey);
Expand All @@ -125,7 +128,8 @@ private static void validateSonarFile(Document document, Set<Class<?>> modules)
}

for (Class<?> module : modules) {
Assert.fail("Module not found in sonar: " + module.getCanonicalName());
if (!CheckUtil.isFilterModule(module) && module != TreeWalker.class)
Assert.fail("Module not found in sonar: " + module.getCanonicalName());
}
}

Expand Down