diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java index 454b4f880329..916dd8e8d081 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsBetweenInconvertibleTypesInspection.java @@ -15,14 +15,10 @@ */ package com.siyeh.ig.junit; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; -import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.PsiMethodCallExpression; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.TypeUtils; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class AssertEqualsBetweenInconvertibleTypesInspection extends BaseInspection { @@ -36,13 +32,7 @@ public class AssertEqualsBetweenInconvertibleTypesInspection extends BaseInspect @Override @NotNull public String buildErrorString(Object... infos) { - final PsiType comparedType = (PsiType)infos[0]; - final PsiType comparisonType = (PsiType)infos[1]; - final String comparedTypeText = comparedType.getPresentableText(); - final String comparisonTypeText = comparisonType.getPresentableText(); - return InspectionGadgetsBundle.message("assertequals.between.inconvertible.types.problem.descriptor", - StringUtil.escapeXml(comparedTypeText), - StringUtil.escapeXml(comparisonTypeText)); + return (String)infos[0]; } @Override @@ -60,63 +50,10 @@ public class AssertEqualsBetweenInconvertibleTypesInspection extends BaseInspect @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); - final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - @NonNls final String methodName = methodExpression.getReferenceName(); - if (!"assertEquals".equals(methodName)) { - return; + final String compatibilityErrorMessage = AssertEqualsHint.areExpectedActualTypesCompatible(expression); + if (compatibilityErrorMessage != null) { + registerMethodCallError(expression, compatibilityErrorMessage); } - final PsiMethod method = expression.resolveMethod(); - if (method == null) { - return; - } - final PsiClass containingClass = method.getContainingClass(); - final boolean junit5Assertions = InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.ORG_JUNIT_JUPITER_API_ASSERTIONS); - if (!InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.JUNIT_FRAMEWORK_ASSERT) && - !InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.ORG_JUNIT_ASSERT) && - !junit5Assertions) { - return; - } - final PsiParameterList parameterList = method.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); - if (parameters.length < 2) { - return; - } - final PsiType firstParameterType = parameters[0].getType(); - final PsiExpressionList argumentList = expression.getArgumentList(); - final PsiExpression[] arguments = argumentList.getExpressions(); - final int argumentIndex; - if (!junit5Assertions && firstParameterType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { - if (arguments.length < 3) { - return; - } - argumentIndex = 1; - } - else { - if (arguments.length < 2) { - return; - } - argumentIndex = 0; - } - final PsiExpression expression1 = arguments[argumentIndex]; - final PsiExpression expression2 = arguments[argumentIndex + 1]; - final PsiType type1 = expression1.getType(); - if (type1 == null) { - return; - } - final PsiType type2 = expression2.getType(); - if (type2 == null) { - return; - } - final PsiType parameterType1 = parameters[argumentIndex].getType(); - final PsiType parameterType2 = parameters[argumentIndex + 1].getType(); - final PsiClassType objectType = TypeUtils.getObjectType(expression); - if (!objectType.equals(parameterType1) || !objectType.equals(parameterType2)) { - return; - } - if (TypeUtils.areConvertible(type1, type2)) { - return; - } - registerMethodCallError(expression, type1, type2); } } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java index c67185790c26..92e7e6537b90 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java @@ -47,11 +47,17 @@ public class AssertEqualsCalledOnArrayInspection extends BaseInspection { @Override protected InspectionGadgetsFix buildFix(Object... infos) { - return new AssertEqualsCalledOnArrayFix(); + return new AssertEqualsCalledOnArrayFix((String)infos[0]); } private static class AssertEqualsCalledOnArrayFix extends InspectionGadgetsFix { + private final String myAssertClassName; + + public AssertEqualsCalledOnArrayFix(String assertClassName) { + myAssertClassName = assertClassName; + } + @Override @NotNull public String getFamilyName() { @@ -67,11 +73,11 @@ public class AssertEqualsCalledOnArrayInspection extends BaseInspection { } final PsiReferenceExpression methodExpression = (PsiReferenceExpression)parent; final PsiExpression qualifier = methodExpression.getQualifierExpression(); - if (qualifier == null && ImportUtils.addStaticImport(JUnitCommonClassNames.ORG_JUNIT_ASSERT, "assertArrayEquals", methodExpression)) { + if (qualifier == null && ImportUtils.addStaticImport(myAssertClassName, "assertArrayEquals", methodExpression)) { PsiReplacementUtil.replaceExpression(methodExpression, "assertArrayEquals"); } else { - PsiReplacementUtil.replaceExpression(methodExpression, "org.junit.Assert.assertArrayEquals"); + PsiReplacementUtil.replaceExpression(methodExpression, myAssertClassName + ".assertArrayEquals"); } } } @@ -86,44 +92,19 @@ public class AssertEqualsCalledOnArrayInspection extends BaseInspection { @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); - final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - @NonNls final String methodName = methodExpression.getReferenceName(); - if (!"assertEquals".equals(methodName)) { + final AssertEqualsHint assertEqualsHint = AssertEqualsHint.create(expression); + if (assertEqualsHint == null) { return; } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); - final PsiType type1; - final PsiType type2; - if (arguments.length == 2) { - final PsiExpression argument0 = arguments[0]; - type1 = argument0.getType(); - final PsiExpression argument1 = arguments[1]; - type2 = argument1.getType(); - } - else if (arguments.length == 3) { - final PsiExpression argument0 = arguments[1]; - type1 = argument0.getType(); - final PsiExpression argument1 = arguments[2]; - type2 = argument1.getType(); - } - else { - return; - } + final int argIndex = assertEqualsHint.getArgIndex(); + final PsiType type1 = arguments[argIndex].getType(); + final PsiType type2 = arguments[argIndex + 1].getType(); if (!(type1 instanceof PsiArrayType) || !(type2 instanceof PsiArrayType)) { return; } - final PsiMethod method = expression.resolveMethod(); - if (method == null) { - return; - } - final PsiClass containingClass = method.getContainingClass(); - if (!InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.JUNIT_FRAMEWORK_ASSERT) && - !InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.ORG_JUNIT_ASSERT) && - !InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit")) { - return; - } - registerMethodCallError(expression); + registerMethodCallError(expression, assertEqualsHint.getAssertClassName()); } } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsHint.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsHint.java new file mode 100644 index 000000000000..2b326b80d647 --- /dev/null +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsHint.java @@ -0,0 +1,120 @@ +/* + * Copyright 2000-2016 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.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.psiutils.TypeUtils; +import org.jetbrains.annotations.NonNls; + +public class AssertEqualsHint { + private final int myArgIndex; + private final PsiMethod myMethod; + private final String myClassName; + + private AssertEqualsHint(int index, PsiMethod method, String className) { + myArgIndex = index; + myMethod = method; + myClassName = className; + } + + public String getAssertClassName() { + return myClassName; + } + + public int getArgIndex() { + return myArgIndex; + } + + public PsiMethod getMethod() { + return myMethod; + } + + public static AssertEqualsHint create(PsiMethodCallExpression expression) { + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + @NonNls final String methodName = methodExpression.getReferenceName(); + if (!"assertEquals".equals(methodName)) { + return null; + } + final PsiMethod method = expression.resolveMethod(); + if (method == null) { + return null; + } + final PsiClass containingClass = method.getContainingClass(); + final boolean messageOnLastPosition = InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.ORG_JUNIT_JUPITER_API_ASSERTIONS) || + InheritanceUtil.isInheritor(containingClass, "org.testng.Assert"); + if (!InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.JUNIT_FRAMEWORK_ASSERT) && + !InheritanceUtil.isInheritor(containingClass, JUnitCommonClassNames.ORG_JUNIT_ASSERT) && + !InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit") && + !messageOnLastPosition) { + return null; + } + final PsiParameterList parameterList = method.getParameterList(); + final PsiParameter[] parameters = parameterList.getParameters(); + if (parameters.length < 2) { + return null; + } + final PsiType firstParameterType = parameters[0].getType(); + final PsiExpressionList argumentList = expression.getArgumentList(); + final PsiExpression[] arguments = argumentList.getExpressions(); + final int argumentIndex; + if (!messageOnLastPosition && firstParameterType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + if (arguments.length < 3) { + return null; + } + argumentIndex = 1; + } + else { + if (arguments.length < 2) { + return null; + } + argumentIndex = 0; + } + return new AssertEqualsHint(argumentIndex, method, messageOnLastPosition ? JUnitCommonClassNames.ORG_JUNIT_JUPITER_API_ASSERTIONS : JUnitCommonClassNames.ORG_JUNIT_ASSERT); + } + + public static String areExpectedActualTypesCompatible(PsiMethodCallExpression expression) { + final AssertEqualsHint assertEqualsHint = create(expression); + if (assertEqualsHint == null) return null; + final PsiExpression[] arguments = expression.getArgumentList().getExpressions(); + final int argIndex = assertEqualsHint.getArgIndex(); + final PsiType type1 = arguments[argIndex].getType(); + if (type1 == null) { + return null; + } + final PsiType type2 = arguments[argIndex + 1].getType(); + if (type2 == null) { + return null; + } + final PsiParameter[] parameters = assertEqualsHint.getMethod().getParameterList().getParameters(); + final PsiType parameterType1 = parameters[argIndex].getType(); + final PsiType parameterType2 = parameters[argIndex + 1].getType(); + final PsiClassType objectType = TypeUtils.getObjectType(expression); + if (!objectType.equals(parameterType1) || !objectType.equals(parameterType2)) { + return null; + } + if (TypeUtils.areConvertible(type1, type2)) { + return null; + } + final String comparedTypeText = type1.getPresentableText(); + final String comparisonTypeText = type2.getPresentableText(); + return InspectionGadgetsBundle.message("assertequals.between.inconvertible.types.problem.descriptor", + StringUtil.escapeXml(comparedTypeText), + StringUtil.escapeXml(comparisonTypeText)); + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.after.java new file mode 100644 index 000000000000..e1790b544be4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.after.java @@ -0,0 +1,7 @@ +class MyTest { + void myTest(){ + Object[] a = {}; + Object[] e = {""}; + org.junit.jupiter.api.Assertions.assertArrayEquals(a, e, "message"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.java new file mode 100644 index 000000000000..fdb1e7516029 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/junit/assertEqualsOnArray/assertEqualsForJunit5.java @@ -0,0 +1,7 @@ +class MyTest { + void myTest(){ + Object[] a = {}; + Object[] e = {""}; + org.junit.jupiter.api.Assertions.assertEquals(a, e, "message"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/junit/AssertEqualsCalledOnArrayInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/junit/AssertEqualsCalledOnArrayInspectionTest.java new file mode 100644 index 000000000000..ae57eaf96289 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/junit/AssertEqualsCalledOnArrayInspectionTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2016 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.fixes.junit; + +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.IGQuickFixesTestCase; +import com.siyeh.ig.junit.AssertEqualsCalledOnArrayInspection; +import com.siyeh.ig.junit.UseOfObsoleteAssertInspection; + +public class AssertEqualsCalledOnArrayInspectionTest extends IGQuickFixesTestCase { + @Override + public void setUp() throws Exception { + super.setUp(); + + + myFixture.addClass("package org.junit.jupiter.api;\n" + + "import java.util.function.Supplier;\n" + + "public final class Assertions {\n" + + " public static void assertArrayEquals(Object[] expected, Object[] actual) {}\n" + + " public static void assertArrayEquals(Object[] expected, Object[] actual, String message) {}\n" + + " public static void assertEquals(Object expected, Object actual) {}\n" + + " public static void assertEquals(Object expected, Object actual, String message) {}\n" + + "}"); + + myFixture.enableInspections(new AssertEqualsCalledOnArrayInspection()); + } + + public void testAssertEqualsForJunit5() { + doFixTest(); + } + + private void doFixTest() { + doTest(getTestName(true), InspectionGadgetsBundle.message("assertequals.called.on.arrays.quickfix")); + } + + @Override + protected String getRelativePath() { + return "junit/assertEqualsOnArray"; + } +} diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/AssertEqualsBetweenInconvertibleTypesTestNGInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/AssertEqualsBetweenInconvertibleTypesTestNGInspection.java index 74c2f7a4c9a9..0e9f9b42af0f 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/inspection/AssertEqualsBetweenInconvertibleTypesTestNGInspection.java +++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/AssertEqualsBetweenInconvertibleTypesTestNGInspection.java @@ -17,12 +17,11 @@ package com.theoryinpractice.testng.inspection; import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.InheritanceUtil; -import com.siyeh.ig.psiutils.TypeUtils; -import org.jetbrains.annotations.NonNls; +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiMethodCallExpression; +import com.siyeh.ig.junit.AssertEqualsHint; import org.jetbrains.annotations.NotNull; /** @@ -32,95 +31,20 @@ public class AssertEqualsBetweenInconvertibleTypesTestNGInspection extends BaseJ @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { - return new AssertEqualsBetweenInconvertibleTypesVisitor(holder); - } + return new JavaElementVisitor() { + @Override + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + final String errorMessage = AssertEqualsHint.areExpectedActualTypesCompatible(expression); + if (errorMessage != null) { + final PsiElement referenceNameElement = expression.getMethodExpression().getReferenceNameElement(); + if (referenceNameElement == null) { + return; + } - private static class AssertEqualsBetweenInconvertibleTypesVisitor extends JavaElementVisitor { - - private final ProblemsHolder myProblemsHolder; - - public AssertEqualsBetweenInconvertibleTypesVisitor(ProblemsHolder problemsHolder) { - myProblemsHolder = problemsHolder; - } - - @Override - public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { - super.visitMethodCallExpression(expression); - final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - @NonNls final String methodName = methodExpression.getReferenceName(); - if (!"assertEquals".equals(methodName)) { - return; - } - final PsiMethod method = expression.resolveMethod(); - if (method == null) { - return; - } - final PsiClass containingClass = method.getContainingClass(); - final boolean junit; - if (InheritanceUtil.isInheritor(containingClass, "org.testng.Assert")) { - junit = false; - } - else if (InheritanceUtil.isInheritor(containingClass, "org.testng.AssertJUnit")) { - junit = true; - } - else { - return; - } - final PsiParameterList parameterList = method.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); - if (parameters.length < 2) { - return; - } - final PsiType firstParameterType = parameters[0].getType(); - final PsiExpressionList argumentList = expression.getArgumentList(); - final PsiExpression[] arguments = argumentList.getExpressions(); - final PsiExpression expression1; - final PsiExpression expression2; - final PsiType parameterType1; - final PsiType parameterType2; - if (junit && firstParameterType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { - if (arguments.length < 3) { - return; + holder.registerProblem(referenceNameElement, errorMessage); } - expression1 = arguments[1]; - expression2 = arguments[2]; - parameterType1 = parameters[1].getType(); - parameterType2 = parameters[2].getType(); } - else { - if (arguments.length < 2) { - return; - } - expression1 = arguments[0]; - expression2 = arguments[1]; - parameterType1 = parameters[0].getType(); - parameterType2 = parameters[1].getType(); - } - final PsiType type1 = expression1.getType(); - if (type1 == null) { - return; - } - final PsiType type2 = expression2.getType(); - if (type2 == null) { - return; - } - final PsiManager manager = expression.getManager(); - final GlobalSearchScope scope = expression.getResolveScope(); - final PsiClassType objectType = PsiType.getJavaLangObject(manager, scope); - if (!objectType.equals(parameterType1) || !objectType.equals(parameterType2)) { - return; - } - if (TypeUtils.areConvertible(type1, type2)) { - return; - } - final PsiElement referenceNameElement = methodExpression.getReferenceNameElement(); - if (referenceNameElement == null) { - return; - } - myProblemsHolder.registerProblem(referenceNameElement, - "#ref() between objects of inconvertible types '" + - StringUtil.escapeXml(type1.getPresentableText()) + "' and '" + - StringUtil.escapeXml(type2.getPresentableText()) + "' #loc"); - } + }; } } \ No newline at end of file