junit @Rule/@ClassRule check inspection (IDEA-102492)

This commit is contained in:
anna
2013-04-12 18:31:07 +02:00
parent 33dee73821
commit 72cde34363
6 changed files with 235 additions and 1 deletions
@@ -1313,6 +1313,9 @@
key="assertequals.called.on.arrays.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.AssertEqualsCalledOnArrayInspection"/>
<localInspection language="JAVA" shortName="JUnitRule" bundle="com.siyeh.InspectionGadgetsBundle"
key="junit.rule.display.name" implementationClass="com.siyeh.ig.junit.JUnitRuleInspection"
groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"/>
<localInspection language="JAVA" suppressId="MessageMissingOnJUnitAssertion" shortName="AssertsWithoutMessages"
bundle="com.siyeh.InspectionGadgetsBundle" key="asserts.without.messages.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
@@ -2597,7 +2600,6 @@
bundle="com.siyeh.InspectionGadgetsBundle" key="parameter.hides.member.variable.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.visibility.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.visibility.ParameterHidingMemberVariableInspection"/>
</extensions>
<application-components>
@@ -2020,3 +2020,6 @@ placeholder.count.matches.argument.count.more.problem.descriptor=<code>#ref()</c
placeholder.count.matches.argument.count.fewer.problem.descriptor=<code>#ref()</code> call has fewer arguments ({0}) than placeholders ({1}) #loc
assignment.to.superclass.field.display.name=Constructor assigns value to field defined in superclass
assignment.to.superclass.field.problem.descriptor=Assignment to field ''{0}'' defined in superclass ''{1}''
junit.rule.display.name=Malformed @Rule/@ClassRule field
junit.rule.problem.descriptor=Fields annotated with @{0} should be {1}
junit.rule.type.problem.descriptor=Field type should be subtype of org.junit.rules.TestRule
@@ -0,0 +1,152 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* User: anna
* Date: 4/12/13
*/
public class JUnitRuleInspection extends BaseInspection {
public static final String RULE_FQN = "org.junit.Rule";
public static final String CLASS_RULE_FQN = "org.junit.ClassRule";
public boolean REPORT_RULE_PROBLEMS = true;
public boolean REPORT_CLASS_RULE_PROBLEMS = true;
@Nls
@NotNull
@Override
public String getDisplayName() {
return InspectionGadgetsBundle.message("junit.rule.display.name");
}
@Nullable
@Override
public JComponent createOptionsPanel() {
final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
panel.addCheckbox("Report @Rule problems", "REPORT_RULE_PROBLEMS");
panel.addCheckbox("Report @ClassRule problems", "REPORT_CLASS_RULE_PROBLEMS");
return panel;
}
@NotNull
@Override
protected String buildErrorString(Object... infos) {
return (String)infos[0];
}
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
return infos.length > 1 ? new MakePublicStaticFix((String)infos[1], (String)infos[2]) : null;
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
@Override
public void visitField(PsiField field) {
final boolean ruleAnnotated = REPORT_RULE_PROBLEMS && AnnotationUtil.isAnnotated(field, RULE_FQN, false);
final boolean classRuleAnnotated = REPORT_CLASS_RULE_PROBLEMS && AnnotationUtil.isAnnotated(field, CLASS_RULE_FQN, false);
if (ruleAnnotated || classRuleAnnotated) {
String annotation = ruleAnnotated ? RULE_FQN : CLASS_RULE_FQN;
String errorMessage = null;
final boolean hasStatic = field.hasModifierProperty(PsiModifier.STATIC);
final boolean hasPublic = field.hasModifierProperty(PsiModifier.PUBLIC);
if (!hasPublic) {
if (classRuleAnnotated) {
if (!hasStatic) {
errorMessage = "public and static";
} else {
errorMessage = "public";
}
}
else {
if (!hasStatic){
errorMessage = "public";
} else {
errorMessage = "public and non-static";
}
}
}
else {
if (!hasStatic) {
if (classRuleAnnotated) {
errorMessage = "static";
}
}
else if (ruleAnnotated) {
errorMessage = "non-static";
}
}
if (errorMessage != null) {
registerError(field.getNameIdentifier(), InspectionGadgetsBundle.message("junit.rule.problem.descriptor", annotation, errorMessage), "Make field " + errorMessage, annotation);
}
if (!InheritanceUtil.isInheritor(PsiUtil.resolveClassInClassTypeOnly(field.getType()), false, "org.junit.rules.TestRule")) {
registerError(field.getNameIdentifier(), InspectionGadgetsBundle.message("junit.rule.type.problem.descriptor"));
}
}
}
};
}
private static class MakePublicStaticFix extends InspectionGadgetsFix {
private final String myName;
private final boolean myMakeStatic;
public MakePublicStaticFix(String name, String annotation) {
myName = name;
myMakeStatic = annotation.equals(CLASS_RULE_FQN);
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
if (element != null) {
final PsiElement parent = element.getParent();
if (parent instanceof PsiField) {
PsiUtil.setModifierProperty((PsiField)parent, PsiModifier.PUBLIC, true);
PsiUtil.setModifierProperty((PsiField)parent, PsiModifier.STATIC, myMakeStatic);
}
}
}
@NotNull
@Override
public String getName() {
return myName;
}
}
}
@@ -0,0 +1,16 @@
<html>
<body>
Reports malformed @Rule/@ClassRule usages: <br/>
<ul>
<li>
Checks for any member that is annotated with @Rule but is not public.
</li>
<li>
Checks for any member that is annotated with @ClassRule but is not public or not static.
</li>
</ul>
<!-- tooltip end -->
<p>
<small>New in 13, Powered by InspectionGadgets</small>
</body>
</html>
@@ -0,0 +1,11 @@
class Test {
@org.junit.ClassRule public static org.junit.rules.TestRule f1;
@org.junit.ClassRule public org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.ClassRule should be static">f2</warning>;
@org.junit.ClassRule static org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.ClassRule should be public">f3</warning>;
@org.junit.ClassRule org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.ClassRule should be public and static">f4</warning>;
@org.junit.Rule public static org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.Rule should be non-static">f5</warning>;
@org.junit.Rule public org.junit.rules.TestRule f6;
@org.junit.Rule static org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.Rule should be public and non-static">f7</warning>;
@org.junit.Rule org.junit.rules.TestRule <warning descr="Fields annotated with @org.junit.Rule should be public">f8</warning>;
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* User: anna
* Date: 10-Jun-2009
*/
package com.siyeh.ig.junit;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class JUnitRuleInspectionTest extends LightCodeInsightFixtureTestCase {
public void testWrongsignature() throws Exception {
myFixture.addClass("package org.junit.rules;\n" +
"public interface TestRule {}");
myFixture.addClass("package org.junit;\n" +
"public @interface Rule {}");
myFixture.addClass("package org.junit;\n" +
"public @interface ClassRule {}");
myFixture.testHighlighting(true, false, false, getTestName(true) + ".java");
}
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.enableInspections(new JUnitRuleInspection());
}
@NotNull
@Override
protected String getTestDataPath() {
return PluginPathManager.getPluginHomePath("InspectionGadgets") + "/test/com/siyeh/igtest/junit/rule/";
}
}