diff --git a/plugins/InspectionGadgets/src/META-INF/plugin.xml b/plugins/InspectionGadgets/src/META-INF/plugin.xml index 07af779efc64..1b3efecf24ca 100644 --- a/plugins/InspectionGadgets/src/META-INF/plugin.xml +++ b/plugins/InspectionGadgets/src/META-INF/plugin.xml @@ -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"/> + - diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 941a1b5f473a..df0905eac73c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -2020,3 +2020,6 @@ placeholder.count.matches.argument.count.more.problem.descriptor=#ref()#ref() 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 \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitRuleInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitRuleInspection.java new file mode 100644 index 000000000000..19e689b4bd42 --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnitRuleInspection.java @@ -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; + } + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitRule.html b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitRule.html new file mode 100644 index 000000000000..de3483f94236 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/JUnitRule.html @@ -0,0 +1,16 @@ + + +Reports malformed @Rule/@ClassRule usages:
+
    +
  • + Checks for any member that is annotated with @Rule but is not public. +
  • +
  • + Checks for any member that is annotated with @ClassRule but is not public or not static. +
  • +
+ +

+New in 13, Powered by InspectionGadgets + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/rule/wrongsignature.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/rule/wrongsignature.java new file mode 100644 index 000000000000..0a55b80c4633 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/junit/rule/wrongsignature.java @@ -0,0 +1,11 @@ +class Test { + @org.junit.ClassRule public static org.junit.rules.TestRule f1; + @org.junit.ClassRule public org.junit.rules.TestRule f2; + @org.junit.ClassRule static org.junit.rules.TestRule f3; + @org.junit.ClassRule org.junit.rules.TestRule f4; + + @org.junit.Rule public static org.junit.rules.TestRule f5; + @org.junit.Rule public org.junit.rules.TestRule f6; + @org.junit.Rule static org.junit.rules.TestRule f7; + @org.junit.Rule org.junit.rules.TestRule f8; +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnitRuleInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnitRuleInspectionTest.java new file mode 100644 index 000000000000..886e13848f03 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/junit/JUnitRuleInspectionTest.java @@ -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/"; + } +} \ No newline at end of file