diff --git a/java/typeMigration/resources/messages/TypeMigrationBundle.properties b/java/typeMigration/resources/messages/TypeMigrationBundle.properties
index 5fa641407def..57f2277a0f38 100644
--- a/java/typeMigration/resources/messages/TypeMigrationBundle.properties
+++ b/java/typeMigration/resources/messages/TypeMigrationBundle.properties
@@ -1,6 +1,5 @@
change.class.parameter.incorrect.type.error.hint=Incorrect type
change.class.type.parameter.family.name=Change class type parameter
-checkbox.statically.import.matcher.methods=Statically import matcher's methods
convert.to.atomic.family.name=Convert to atomic
convert.to.longadder.family.name=Convert to 'LongAdder'
convert.to.threadlocal.family.name=Convert to 'ThreadLocal'
@@ -9,9 +8,7 @@ inspection.guava.erase.option=Erase @javax.annotations.Nullable from converted f
inspection.guava.method.chains.option=Report method chains
inspection.guava.return.types.option=Report return types
inspection.guava.variables.option=Report variables
-inspection.migrate.assert.to.matcher.description=Assert expression #ref can be replaced with ''{0}'' call #loc
migrate.fix.text=Migrate ''{0}'' type to ''{1}''
migrate.guava.to.java.family.name=Migrate Guava type to Java
migrate.method.chain.fix.text=Migrate method chain type to ''{0}''
-inspection.guava.name=Guava's functional primitives can be replaced with Java
-inspection.assertion.name=JUnit assertion can be 'assertThat()' call
\ No newline at end of file
+inspection.guava.name=Guava's functional primitives can be replaced with Java
\ No newline at end of file
diff --git a/java/typeMigration/src/META-INF/TypeMigration.xml b/java/typeMigration/src/META-INF/TypeMigration.xml
index 4e4f1fff4404..e3ca04d68481 100644
--- a/java/typeMigration/src/META-INF/TypeMigration.xml
+++ b/java/typeMigration/src/META-INF/TypeMigration.xml
@@ -42,12 +42,6 @@
groupKey="group.names.language.level.specific.issues.and.migration.aids8" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.refactoring.typeMigration.inspections.GuavaInspection"
bundle="messages.TypeMigrationBundle" key="inspection.guava.name"/>
-
-
-
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/MigrateAssertToMatcherAssertInspection.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/MigrateAssertToMatcherAssertInspection.java
deleted file mode 100644
index b5afa76d1a22..000000000000
--- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/MigrateAssertToMatcherAssertInspection.java
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package com.intellij.refactoring.typeMigration.inspections;
-
-import com.intellij.codeInsight.intention.impl.AddOnDemandStaticImportAction;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
-import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiTypesUtil;
-import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
-import com.intellij.refactoring.typeMigration.TypeMigrationBundle;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Dmitry Batkovich
- */
-public class MigrateAssertToMatcherAssertInspection extends AbstractBaseJavaLocalInspectionTool {
-
- private final static Logger LOG = Logger.getInstance(MigrateAssertToMatcherAssertInspection.class);
- private final static Map> ASSERT_METHODS = new HashMap<>();
-
- static {
- ASSERT_METHODS.put("assertArrayEquals", Pair.create("$expected$, $actual$", "$actual$, {0}.is($expected$)"));
- ASSERT_METHODS.put("assertEquals", Pair.create("$expected$, $actual$", "$actual$, {0}.is($expected$)"));
- ASSERT_METHODS.put("assertNotEquals", Pair.create("$expected$, $actual$", "$actual$, {0}.not({0}.is($expected$))"));
- ASSERT_METHODS.put("assertSame", Pair.create("$expected$, $actual$", "$actual$, {0}.sameInstance($expected$)"));
- ASSERT_METHODS.put("assertNotSame", Pair.create("$expected$, $actual$", "$actual$, {0}.not({0}.sameInstance($expected$))"));
- ASSERT_METHODS.put("assertNotNull", Pair.create("$obj$", "$obj$, {0}.notNullValue()"));
- ASSERT_METHODS.put("assertNull", Pair.create("$obj$", "$obj$, {0}.nullValue()"));
- ASSERT_METHODS.put("assertTrue", Pair.create("$cond$", "$cond$, {0}.is(true)"));
- ASSERT_METHODS.put("assertFalse", Pair.create("$cond$", "$cond$, {0}.is(false)"));
- }
-
- private static final String CORE_MATCHERS_CLASS_NAME = "org.hamcrest.CoreMatchers";
- private static final String MATCHERS_CLASS_NAME = "org.hamcrest.Matchers";
- private static final String ORDERING_COMPARISON_NAME = "org.hamcrest.number.OrderingComparison";
-
- public boolean myStaticallyImportMatchers = true;
-
- @Nullable
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(TypeMigrationBundle.message("checkbox.statically.import.matcher.methods"), this,
- "myStaticallyImportMatchers");
- }
-
- @NotNull
- @Override
- public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
- final GlobalSearchScope resolveScope = holder.getFile().getResolveScope();
- final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(holder.getProject());
- final PsiClass coreMatchersClass = javaPsiFacade.findClass(CORE_MATCHERS_CLASS_NAME, resolveScope);
- final PsiClass matchersClass = javaPsiFacade.findClass(MATCHERS_CLASS_NAME, resolveScope);
- if (coreMatchersClass == null && matchersClass == null) {
- return PsiElementVisitor.EMPTY_VISITOR;
- }
- return new JavaElementVisitor() {
- @Override
- public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression = expression.getMethodExpression();
- final String methodName = methodExpression.getReferenceName();
- if (!ASSERT_METHODS.containsKey(methodName)) return;
- final PsiClass assertClass;
- final PsiMethod assertMethod = expression.resolveMethod();
- if (assertMethod == null || (assertClass = assertMethod.getContainingClass()) == null) {
- return;
- }
- if (!"junit.framework.Assert".equals(assertClass.getQualifiedName()) &&
- !"org.junit.Assert".equals(assertClass.getQualifiedName())) {
- return;
- }
-
- if (isBooleanAssert(assertMethod.getName())) {
- PsiExpression[] args = expression.getArgumentList().getExpressions();
- if (args[args.length - 1] instanceof PsiBinaryExpression &&
- javaPsiFacade.findClass(ORDERING_COMPARISON_NAME, expression.getResolveScope()) == null) {
- return;
- }
- }
-
- final PsiElement referenceNameElement = methodExpression.getReferenceNameElement();
- if (referenceNameElement != null) {
- holder.registerProblem(referenceNameElement,
- TypeMigrationBundle.message("inspection.migrate.assert.to.matcher.description", "assertThat()"),
- new MigrateAssertToMatcherAssertFix(
- matchersClass != null ? MATCHERS_CLASS_NAME : CORE_MATCHERS_CLASS_NAME));
- }
- }
- };
- }
-
- public class MigrateAssertToMatcherAssertFix implements LocalQuickFix {
- private final String myMatchersClassName;
-
- public MigrateAssertToMatcherAssertFix(String name) {
- myMatchersClassName = name;
- }
-
- @Nls
- @NotNull
- @Override
- public String getFamilyName() {
- return CommonQuickFixBundle.message("fix.replace.with.x", "assertThat()");
- }
-
- @Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- final PsiElement element = descriptor.getPsiElement();
- final PsiElement grandParent = element.getParent().getParent();
- if (!(grandParent instanceof PsiMethodCallExpression)) {
- return;
- }
- final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)grandParent;
- final PsiMethod method = methodCall.resolveMethod();
- if (method == null) {
- return;
- }
- final String methodName = method.getName();
- Pair templatePair = null;
- if (isBooleanAssert(methodName)) {
- final PsiExpression[] expressions = methodCall.getArgumentList().getExpressions();
- final PsiExpression conditionExpression = expressions[expressions.length - 1];
- final boolean negate = methodName.contains("False");
- if (conditionExpression instanceof PsiBinaryExpression) {
- templatePair = getSuitableMatcherForBinaryExpressionInsideBooleanAssert((PsiBinaryExpression)conditionExpression, negate);
- }
- else if (conditionExpression instanceof PsiMethodCallExpression) {
- templatePair = getSuitableMatcherForMethodCallInsideBooleanAssert((PsiMethodCallExpression)conditionExpression, negate);
- }
- }
- if (templatePair == null) {
- templatePair = ASSERT_METHODS.get(methodName);
- }
- LOG.assertTrue(templatePair != null);
- templatePair = buildFullTemplate(templatePair, method);
- final PsiExpression replaced;
- try {
- replaced = TypeConversionDescriptor.replaceExpression(methodCall, templatePair.getFirst(), MessageFormat.format(templatePair.getSecond(), myMatchersClassName));
- }
- catch (IncorrectOperationException e) {
- LOG.error("Replacer can't match expression:\n" +
- methodCall.getText() +
- "\nwith replacement template:\n(" +
- templatePair.getFirst() +
- ", " +
- templatePair.getSecond() +
- ")");
- throw e;
- }
-
- if (myStaticallyImportMatchers) {
- for (PsiJavaCodeReferenceElement ref : ContainerUtil.reverse(
- new ArrayList<>(PsiTreeUtil.findChildrenOfType(replaced, PsiJavaCodeReferenceElement.class)))) {
- if (!ref.isValid()) continue;
- final PsiElement resolvedElement = ref.resolve();
- if (resolvedElement instanceof PsiClass) {
- final String qName = ((PsiClass)resolvedElement).getQualifiedName();
- if (qName != null && qName.startsWith("org.hamcrest")) {
- final PsiIdentifier identifier = PsiTreeUtil.getChildOfType(ref, PsiIdentifier.class);
- if (identifier != null) {
- AddOnDemandStaticImportAction.invoke(project, replaced.getContainingFile(), null, identifier);
- }
- }
- }
- }
- }
- }
-
- private Pair<@NonNls String, @NonNls String> buildFullTemplate(Pair templatePair, PsiMethod method) {
- if (templatePair == null) {
- return null;
- }
- final boolean hasMessage = hasMessage(method);
- final String searchTemplate = "'_Assert?." + method.getName() + "(" + (hasMessage ? "$msg$, " : "") + templatePair.getFirst() + ")";
- final String replaceTemplate = "org.hamcrest.MatcherAssert.assertThat(" + (hasMessage ? "$msg$, " : "") + templatePair.getSecond() + ")";
- return Pair.create(searchTemplate, replaceTemplate);
- }
-
- @Nullable
- private Pair<@NonNls String, @NonNls String> getSuitableMatcherForBinaryExpressionInsideBooleanAssert(PsiBinaryExpression expression, boolean negate) {
- final PsiJavaToken sign = expression.getOperationSign();
- IElementType tokenType = sign.getTokenType();
- if (negate) {
- tokenType = negate(tokenType);
- }
- final @NonNls String fromTemplate = "$left$ " + sign.getText() + " $right$";
- if (JavaTokenType.EQEQ.equals(tokenType) || JavaTokenType.NE.equals(tokenType)) {
- boolean isEqEqForPrimitives = true;
- for (PsiExpression operand : Arrays.asList(expression.getLOperand(), expression.getROperand())) {
- if (!(operand.getType() instanceof PsiPrimitiveType)) {
- isEqEqForPrimitives = false;
- break;
- }
- }
- @NonNls String rightPartOfAfterTemplate =
- isEqEqForPrimitives ? "{0}.is($right$)" : "{0}.sameInstance($right$)";
- if (JavaTokenType.NE.equals(tokenType)) {
- rightPartOfAfterTemplate = "{0}.not(" + rightPartOfAfterTemplate + ")";
- }
- return Pair.create(fromTemplate,
- "$left$, " + rightPartOfAfterTemplate);
- }
- @NonNls String replaceTemplate = null;
- if (JavaTokenType.GT.equals(tokenType)) {
- replaceTemplate = "greaterThan($right$)";
- }
- else if (JavaTokenType.LT.equals(tokenType)) {
- replaceTemplate = "lessThan($right$)";
- }
- else if (JavaTokenType.GE.equals(tokenType)) {
- replaceTemplate = "greaterThanOrEqualTo($right$)";
- }
- else if (JavaTokenType.LE.equals(tokenType)) {
- replaceTemplate = "lessThanOrEqualTo($right$)";
- }
- if (replaceTemplate == null) {
- return null;
- }
- replaceTemplate = ORDERING_COMPARISON_NAME + "." + replaceTemplate;
- return Pair.create(fromTemplate, "$left$, " + replaceTemplate);
- }
- }
-
- private static boolean isBooleanAssert(String methodName) {
- return "assertFalse".equals(methodName) || "assertTrue".equals(methodName);
- }
-
- private static IElementType negate(IElementType tokenType) {
- if (JavaTokenType.GT.equals(tokenType)) {
- return JavaTokenType.LE;
- }
- else if (JavaTokenType.LT.equals(tokenType)) {
- return JavaTokenType.GE;
- }
- else if (JavaTokenType.GE.equals(tokenType)) {
- return JavaTokenType.LT;
- }
- else if (JavaTokenType.LE.equals(tokenType)) {
- return JavaTokenType.GT;
- }
- return null;
- }
-
- @Nullable
- private static Pair getSuitableMatcherForMethodCallInsideBooleanAssert(PsiMethodCallExpression expression, boolean negate) {
- final String methodName = expression.getMethodExpression().getReferenceName();
- @NonNls String fromTemplate = null;
- @NonNls String toLeftPart = null;
- @NonNls String toRightPart = null;
- if ("contains".equals(methodName)) {
- final PsiMethod method = expression.resolveMethod();
- final PsiClass containingClass;
- if (method != null &&
- (containingClass = method.getContainingClass()) != null) {
-
- if (CommonClassNames.JAVA_LANG_STRING.equals(containingClass.getQualifiedName())) {
- fromTemplate = "$str$.contains($sub$)";
- toLeftPart = "$str$, ";
- toRightPart = "{0}.containsString($sub$)";
- } else if (InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_COLLECTION)) {
- fromTemplate = "$collection$.contains($element$)";
- toLeftPart = "$collection$, ";
- toRightPart = "{0}.hasItem($element$)";
- }
- }
- }
- else if ("equals".equals(methodName)) {
- final PsiMethod method = expression.resolveMethod();
- if (method != null && isUniqueObjectParameter(method.getParameterList())) {
- fromTemplate = "$left$.equals($right$)";
- toLeftPart = "$left$, ";
- toRightPart = "{0}.is($right$)";
- }
- }
- if (fromTemplate == null) {
- return null;
- }
- if (negate) {
- toRightPart = "{0}.not(" + toRightPart + ")";
- }
- return Pair.create(fromTemplate, toLeftPart + toRightPart);
- }
-
- private static boolean isUniqueObjectParameter(PsiParameterList parameters) {
- if (parameters.getParametersCount() != 1) {
- return false;
- }
- final PsiParameter parameter = parameters.getParameters()[0];
- final PsiClass parameterClass = PsiTypesUtil.getPsiClass(parameter.getType());
- return parameterClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(parameterClass.getQualifiedName());
- }
-
- private static boolean hasMessage(PsiMethod method) {
- final PsiParameter maybeMessage = method.getParameterList().getParameters()[0];
- final PsiClass maybeString = PsiTypesUtil.getPsiClass(maybeMessage.getType());
- return maybeString != null && CommonClassNames.JAVA_LANG_STRING.equals(maybeString.getQualifiedName());
- }
-}
\ No newline at end of file
diff --git a/java/typeMigration/test/com/intellij/codeInsight/inspections/MigrateAssertToMatcherAssertTest.java b/java/typeMigration/test/com/intellij/codeInsight/inspections/MigrateAssertToMatcherAssertTest.java
deleted file mode 100644
index 5a2cbd32fdbe..000000000000
--- a/java/typeMigration/test/com/intellij/codeInsight/inspections/MigrateAssertToMatcherAssertTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package com.intellij.codeInsight.inspections;
-
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ex.QuickFixWrapper;
-import com.intellij.project.IntelliJProjectConfiguration;
-import com.intellij.refactoring.typeMigration.inspections.MigrateAssertToMatcherAssertInspection;
-import com.intellij.testFramework.PlatformTestUtil;
-import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
-import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
-import com.intellij.util.ArrayUtilRt;
-
-/**
- * @author Dmitry Batkovich
- */
-public class MigrateAssertToMatcherAssertTest extends JavaCodeInsightFixtureTestCase {
- @Override
- protected String getTestDataPath() {
- return PlatformTestUtil.getCommunityPath() + "/java/typeMigration/testData/inspections/migrateAssertsToAssertThat";
- }
-
- @Override
- protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) {
- moduleBuilder.addLibrary("test-env",
- ArrayUtilRt.toStringArray(IntelliJProjectConfiguration.getProjectLibraryClassesRootPaths("JUnit4")));
- moduleBuilder.addLibrary("test-env",
- ArrayUtilRt.toStringArray(IntelliJProjectConfiguration.getProjectLibraryClassesRootPaths("hamcrest")));
- }
-
- public void testMigrateAssertToMatcherAssert() {
- myFixture.configureByFile(getTestName(false) + ".java");
- myFixture.enableInspections(new MigrateAssertToMatcherAssertInspection());
- myFixture.checkHighlighting();
- for (IntentionAction wrapper : myFixture.getAllQuickFixes()) {
- if (wrapper instanceof QuickFixWrapper) {
- final LocalQuickFix fix = ((QuickFixWrapper)wrapper).getFix();
- if (fix instanceof MigrateAssertToMatcherAssertInspection.MigrateAssertToMatcherAssertFix) {
- myFixture.launchAction(wrapper);
- }
- }
- }
- myFixture.checkResultByFile(getTestName(false) + "_after.java");
- }
-
-}
diff --git a/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert.java b/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert.java
deleted file mode 100644
index e3e293ccaaad..000000000000
--- a/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert.java
+++ /dev/null
@@ -1,39 +0,0 @@
-import org.junit.Assert;
-import java.util.Collection;
-
-public class MigrateAssertToMatcherAssert {
- void m() {
- Assert.assertTrue(2 != 3);
- Assert.assertTrue(2 == 3);
- Assert.assertTrue(2 > 3);
- Assert.assertTrue(2 < 3);
- Assert.assertTrue(2 >= 3);
- Assert.assertTrue(2 <= 3);
-
- Assert.assertFalse(2 != 3);
- Assert.assertFalse(2 == 3);
- Assert.assertFalse(2 > 3);
- Assert.assertFalse(2 < 3);
- Assert.assertFalse(2 >= 3);
- Assert.assertFalse(2 <= 3);
- }
-
- void m2() {
- Assert.assertTrue("asd".equals("zxc"));
- Assert.assertTrue("asd" == "zxc");
- Assert.assertTrue("asd".contains("qwe"));
- }
-
- void m3(Collection c, String o) {
- Assert.assertTrue(c.contains(o));
- Assert.assertEquals(c, o);
- Assert.assertEquals("msg", c, o);
- Assert.assertNotNull(c);
- Assert.assertNull(c);
- Assert.assertFalse(c.contains(o));
- }
-
- void m(int[] a, int[] b) {
- Assert.assertArrayEquals(a, b);
- }
-}
\ No newline at end of file
diff --git a/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert_after.java b/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert_after.java
deleted file mode 100644
index 42f05a9f9d47..000000000000
--- a/java/typeMigration/testData/inspections/migrateAssertsToAssertThat/MigrateAssertToMatcherAssert_after.java
+++ /dev/null
@@ -1,46 +0,0 @@
-import org.hamcrest.MatcherAssert;
-import org.hamcrest.Matchers;
-import org.hamcrest.number.OrderingComparison;
-import org.junit.Assert;
-import java.util.Collection;
-
-import static org.hamcrest.MatcherAssert.*;
-import static org.hamcrest.Matchers.*;
-import static org.hamcrest.number.OrderingComparison.*;
-
-public class MigrateAssertToMatcherAssert {
- void m() {
- assertThat(2, not(is(3)));
- assertThat(2, is(3));
- assertThat(2, greaterThan(3));
- assertThat(2, lessThan(3));
- assertThat(2, greaterThanOrEqualTo(3));
- assertThat(2, lessThanOrEqualTo(3));
-
- assertThat(2 != 3, is(false));
- assertThat(2 == 3, is(false));
- assertThat(2, lessThanOrEqualTo(3));
- assertThat(2, greaterThanOrEqualTo(3));
- assertThat(2, lessThan(3));
- assertThat(2, greaterThan(3));
- }
-
- void m2() {
- assertThat("asd", is("zxc"));
- assertThat("asd", sameInstance("zxc"));
- assertThat("asd", containsString("qwe"));
- }
-
- void m3(Collection c, String o) {
- assertThat(c, hasItem(o));
- assertThat(o, is(c));
- assertThat("msg", o, is(c));
- assertThat(c, notNullValue());
- assertThat(c, nullValue());
- assertThat(c, not(hasItem(o)));
- }
-
- void m(int[] a, int[] b) {
- assertThat(b, is(a));
- }
-}
\ No newline at end of file
diff --git a/jvm/jvm-analysis-impl/resources/META-INF/JvmAnalysisPlugin.xml b/jvm/jvm-analysis-impl/resources/META-INF/JvmAnalysisPlugin.xml
index 1e1e30eb3c7a..0bc88e403d9c 100644
--- a/jvm/jvm-analysis-impl/resources/META-INF/JvmAnalysisPlugin.xml
+++ b/jvm/jvm-analysis-impl/resources/META-INF/JvmAnalysisPlugin.xml
@@ -23,6 +23,11 @@
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
key="jvm.inspection.test.failed.line.display.name"
implementationClass="com.intellij.codeInspection.test.TestFailedLineInspection"/>
+
#ref()#ref() may be 'assertSame()' #loc
+jvm.inspections.migrate.assertion.name=JUnit assertion can be 'assertThat()' call
+jvm.inspections.migrate.assert.to.matcher.option=Statically import matcher's methods
+jvm.inspections.migrate.assert.to.matcher.description=Assert expression #ref can be replaced with ''{0}'' call #loc
+
jvm.inspection.test.failed.line.display.name=Failed line in test
jvm.inspections.thread.run.display.name=Call to 'Thread.run()'
diff --git a/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestAssertionsConverterInspection.kt b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestAssertionsConverterInspection.kt
new file mode 100644
index 000000000000..54947e596654
--- /dev/null
+++ b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestAssertionsConverterInspection.kt
@@ -0,0 +1,209 @@
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.codeInspection.test.junit
+
+import com.intellij.analysis.JvmAnalysisBundle
+import com.intellij.codeInspection.*
+import com.intellij.codeInspection.test.junit.HamcrestCommonClassNames.*
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel
+import com.intellij.openapi.project.Project
+import com.intellij.psi.*
+import com.intellij.psi.CommonClassNames.*
+import com.intellij.uast.UastHintedVisitorAdapter
+import com.intellij.util.castSafelyTo
+import com.siyeh.ig.junit.JUnitCommonClassNames.*
+import com.siyeh.ig.psiutils.TypeUtils
+import org.jetbrains.uast.*
+import org.jetbrains.uast.generate.UastElementFactory
+import org.jetbrains.uast.generate.getUastElementFactory
+import org.jetbrains.uast.generate.replace
+import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
+import javax.swing.JComponent
+
+class HamcrestAssertionsConverterInspection : AbstractBaseUastLocalInspectionTool() {
+ @JvmField
+ var myStaticallyImportMatchers = true
+
+ override fun createOptionsPanel(): JComponent = SingleCheckboxOptionsPanel(
+ JvmAnalysisBundle.message("jvm.inspections.migrate.assert.to.matcher.option"), this, "myStaticallyImportMatchers"
+ )
+
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ val matcherFqn =
+ JavaPsiFacade.getInstance(holder.project).findClass(ORG_HAMCREST_MATCHERS, holder.file.resolveScope)?.qualifiedName
+ ?: JavaPsiFacade.getInstance(holder.project).findClass(ORG_HAMCREST_CORE_MATCHERS, holder.file.resolveScope)?.qualifiedName
+ ?: return PsiElementVisitor.EMPTY_VISITOR
+
+ return UastHintedVisitorAdapter.create(
+ holder.file.language,
+ HamcrestAssertionsConverterVisitor(holder, matcherFqn),
+ arrayOf(UCallExpression::class.java),
+ directOnly = true
+ )
+ }
+}
+
+private class HamcrestAssertionsConverterVisitor(
+ private val holder: ProblemsHolder,
+ private val matcherFqn: String
+) : AbstractUastNonRecursiveVisitor() {
+ private fun isBooleanAssert(methodName: String) = methodName == "assertTrue" || methodName == "assertFalse"
+
+ override fun visitCallExpression(node: UCallExpression): Boolean {
+ val methodName = node.methodName ?: return true
+ if (!JUNIT_ASSERT_METHODS.contains(methodName)) return true
+ val method = node.resolveToUElement() ?: return true
+ val methodClass = method.getContainingUClass() ?: return true
+ if (methodClass.qualifiedName != ORG_JUNIT_ASSERT && methodClass.qualifiedName != JUNIT_FRAMEWORK_ASSERT) return true
+ if (isBooleanAssert(methodName)) {
+ val args = node.valueArguments
+ val resolveScope = node.sourcePsi?.resolveScope ?: return true
+ val psiFacade = JavaPsiFacade.getInstance(holder.project)
+ if (args.last() is UBinaryExpression && psiFacade.findClass(ORG_HAMCREST_NUMBER_ORDERING_COMPARISON, resolveScope) == null) return true
+ }
+ val message = JvmAnalysisBundle.message("jvm.inspections.migrate.assert.to.matcher.description", "assertThat()")
+ holder.registerUProblem(node, message, MigrateToAssertThatQuickFix(matcherFqn))
+ return true
+ }
+
+ companion object {
+ private val JUNIT_ASSERT_METHODS = listOf(
+ "assertArrayEquals",
+ "assertEquals", "assertNotEquals",
+ "assertSame", "assertNotSame",
+ "assertNotNull", "assertNull",
+ "assertTrue", "assertFalse"
+ )
+ }
+}
+
+private class MigrateToAssertThatQuickFix(val matcherClassFqn: String) : LocalQuickFix {
+ override fun getFamilyName(): String = CommonQuickFixBundle.message("fix.replace.with.x", "assertThat()")
+
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val element = descriptor.psiElement ?: return
+ val call = element.getUastParentOfType() ?: return
+ val factory = call.getUastElementFactory(project) ?: return
+ val methodName = call.methodName ?: return
+ val arguments = call.valueArguments.toMutableList()
+ val method = call.resolveToUElement()?.castSafelyTo() ?: return
+ val message = if (TypeUtils.typeEquals(JAVA_LANG_STRING, method.uastParameters.first().type)) {
+ arguments.removeFirst()
+ } else null
+ val (left, right) = when (methodName) {
+ "assertTrue", "assertFalse" -> {
+ val conditionArgument = arguments.lastOrNull() ?: return
+ when (conditionArgument) {
+ is UBinaryExpression -> {
+ val operator = conditionArgument.operator.normalize(methodName)
+ val matchExpression = factory.buildMatchExpression(operator, conditionArgument.rightOperand) ?: return
+ conditionArgument.leftOperand to matchExpression
+ }
+ is UQualifiedReferenceExpression -> {
+ val conditionCall = conditionArgument.selector.castSafelyTo() ?: return
+ val conditionMethodName = conditionCall.methodName ?: return
+ val matchExpression = if (methodName.contains("False")) {
+ factory.createMatchExpression(
+ "not", factory.buildMatchExpression(conditionMethodName, conditionArgument.receiver, conditionCall.valueArguments.first())
+ )
+ } else {
+ factory.buildMatchExpression(conditionMethodName, conditionArgument.receiver, conditionCall.valueArguments.first())
+ } ?: return
+ conditionArgument.receiver to matchExpression
+ }
+ else -> return
+ }
+ }
+ "assertEquals", "assertArrayEquals" -> {
+ val matchExpression = factory.createMatchExpression("is", arguments.first()) ?: return
+ arguments.last() to matchExpression
+ }
+ "assertNotEquals" -> {
+ val matchExpression = factory.createMatchExpression(
+ "not", factory.createMatchExpression("is", arguments.first())
+ ) ?: return
+ arguments.last() to matchExpression
+ }
+ "assertSame" -> {
+ val matchExpression = factory.createMatchExpression("sameInstance", arguments.first()) ?: return
+ arguments.last() to matchExpression
+ }
+ "assertNotSame" -> {
+ val matchExpression = factory.createMatchExpression(
+ "not", factory.createMatchExpression("sameInstance", arguments.first())
+ ) ?: return
+ arguments.last() to matchExpression
+ }
+ "assertNull" -> {
+ val matchExpression = factory.createMatchExpression("nullValue") ?: return
+ arguments.first() to matchExpression
+ }
+ "assertNotNull" -> {
+ val matchExpression = factory.createMatchExpression("notNullValue") ?: return
+ arguments.first() to matchExpression
+ }
+ else -> return
+ }
+
+ val assertThatCall = factory.createAssertThat(listOfNotNull(message, left, right)) ?: return
+ call.getQualifiedParentOrThis().replace(assertThatCall)
+ }
+
+ private fun UastElementFactory.createAssertThat(params: List): UExpression? {
+ val matchAssert = createQualifiedReference("org.hamcrest.MatcherAssert", null) ?: return null
+ return createCallExpression(matchAssert, "assertThat", params, null, UastCallKind.METHOD_CALL)
+ ?.getQualifiedParentOrThis()
+ }
+
+ private fun UastElementFactory.createMatchExpression(name: String, parameter: UExpression? = null): UExpression? {
+ val paramList = if (parameter == null) emptyList() else listOf(parameter)
+ val matcher = createQualifiedReference(matcherClassFqn, null) ?: return null
+ return createCallExpression(matcher, name, paramList, null, UastCallKind.METHOD_CALL)?.getQualifiedParentOrThis()
+ }
+
+ private fun UExpression.isPrimitiveType() = getExpressionType() is PsiPrimitiveType
+
+ private fun UastElementFactory.createIdEqualsExpression(param: UExpression) =
+ if (param.isPrimitiveType()) createMatchExpression("is", param) else createMatchExpression("sameInstance", param)
+
+ private fun UastBinaryOperator.inverse(): UastBinaryOperator = when (this) {
+ UastBinaryOperator.EQUALS -> UastBinaryOperator.NOT_EQUALS
+ UastBinaryOperator.NOT_EQUALS -> UastBinaryOperator.EQUALS
+ UastBinaryOperator.IDENTITY_EQUALS -> UastBinaryOperator.IDENTITY_NOT_EQUALS
+ UastBinaryOperator.IDENTITY_NOT_EQUALS -> UastBinaryOperator.IDENTITY_EQUALS
+ UastBinaryOperator.GREATER -> UastBinaryOperator.LESS_OR_EQUALS
+ UastBinaryOperator.LESS -> UastBinaryOperator.GREATER_OR_EQUALS
+ UastBinaryOperator.GREATER_OR_EQUALS -> UastBinaryOperator.LESS
+ UastBinaryOperator.LESS_OR_EQUALS -> UastBinaryOperator.GREATER
+ else -> this
+ }
+
+ fun UastBinaryOperator.normalize(methodName: String): UastBinaryOperator = if (methodName.contains("False")) inverse() else this
+
+ private fun UastElementFactory.buildMatchExpression(operator: UastBinaryOperator, param: UExpression): UExpression? = when (operator) {
+ UastBinaryOperator.EQUALS -> createMatchExpression("is", param)
+ UastBinaryOperator.NOT_EQUALS -> createMatchExpression("not", createMatchExpression("is", param))
+ UastBinaryOperator.IDENTITY_EQUALS -> createIdEqualsExpression(param)
+ UastBinaryOperator.IDENTITY_NOT_EQUALS -> createMatchExpression("not", createIdEqualsExpression(param))
+ UastBinaryOperator.GREATER -> createMatchExpression("greaterThan", param)
+ UastBinaryOperator.LESS -> createMatchExpression("lessThan", param)
+ UastBinaryOperator.GREATER_OR_EQUALS -> createMatchExpression("greaterThanOrEqualTo", param)
+ UastBinaryOperator.LESS_OR_EQUALS -> createMatchExpression("lessThanOrEqualTo", param)
+ else -> null
+ }
+
+ private fun UastElementFactory.buildMatchExpression(methodName: String, receiver: UExpression, param: UExpression): UExpression? {
+ return when (methodName) {
+ "contains" -> {
+ if (receiver.getExpressionType()?.isInheritorOf(JAVA_UTIL_COLLECTION) == true) {
+ return createMatchExpression("hasItem", param)
+ }
+ if (TypeUtils.typeEquals(JAVA_LANG_STRING, param.getExpressionType())) {
+ return createMatchExpression("containsString", param)
+ }
+ return createMatchExpression("contains", param)
+ }
+ "equals" -> createMatchExpression("is", param)
+ else -> null
+ }
+ }
+}
\ No newline at end of file
diff --git a/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestCommonClassNames.java b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestCommonClassNames.java
new file mode 100644
index 000000000000..4b3dddac293d
--- /dev/null
+++ b/jvm/jvm-analysis-impl/src/com/intellij/codeInspection/test/junit/HamcrestCommonClassNames.java
@@ -0,0 +1,8 @@
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.codeInspection.test.junit;
+
+public class HamcrestCommonClassNames {
+ public static final String ORG_HAMCREST_NUMBER_ORDERING_COMPARISON = "org.hamcrest.number.OrderingComparison";
+ public static final String ORG_HAMCREST_CORE_MATCHERS = "org.hamcrest.CoreMatchers";
+ public static final String ORG_HAMCREST_MATCHERS = "org.hamcrest.Matchers";
+}
diff --git a/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/tests/java/test/JavaHamcrestAssertionsConverterInspectionTest.kt b/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/tests/java/test/JavaHamcrestAssertionsConverterInspectionTest.kt
new file mode 100644
index 000000000000..a4c2b81218e8
--- /dev/null
+++ b/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/tests/java/test/JavaHamcrestAssertionsConverterInspectionTest.kt
@@ -0,0 +1,176 @@
+package com.intellij.codeInspection.tests.java.test
+
+import com.intellij.codeInspection.tests.ULanguage
+import com.intellij.codeInspection.tests.test.HamcrestAssertionsConverterInspectionTestBase
+
+class JavaHamcrestAssertionsConverterInspectionTest : HamcrestAssertionsConverterInspectionTestBase() {
+ fun `test highlighting`() {
+ myFixture.testHighlighting(ULanguage.JAVA, """
+ import org.junit.Assert;
+ import java.util.Collection;
+
+ class Foo {
+ void m() {
+ Assert.assertTrue(2 != 3);
+ Assert.assertTrue(2 == 3);
+ Assert.assertTrue(2 > 3);
+ Assert.assertTrue(2 < 3);
+ Assert.assertTrue(2 >= 3);
+ Assert.assertTrue(2 <= 3);
+
+ Assert.assertFalse(2 != 3);
+ Assert.assertFalse(2 == 3);
+ Assert.assertFalse(2 > 3);
+ Assert.assertFalse(2 < 3);
+ Assert.assertFalse(2 >= 3);
+ Assert.assertFalse(2 <= 3);
+ }
+
+ void m2() {
+ Assert.assertTrue("asd".equals("zxc"));
+ Assert.assertTrue("asd" == "zxc");
+ Assert.assertTrue("asd".contains("qwe"));
+ }
+
+ void m3(Collection c, String o) {
+ Assert.assertTrue(c.contains(o));
+ Assert.assertEquals(c, o);
+ Assert.assertEquals("msg", c, o);
+ Assert.assertNotNull(c);
+ Assert.assertNull(c);
+ Assert.assertFalse(c.contains(o));
+ }
+
+ void m(int[] a, int[] b) {
+ Assert.assertArrayEquals(a, b);
+ }
+ }
+ """.trimIndent())
+ }
+
+ fun `test quickfix binary expression`() {
+ myFixture.testAllQuickfixes(ULanguage.JAVA, """
+ import org.junit.Assert;
+
+ class MigrationTest {
+ void migrate() {
+ Assert.assertTrue(2 != 3);
+ Assert.assertTrue(2 == 3);
+ Assert.assertTrue(2 > 3);
+ Assert.assertTrue(2 < 3);
+ Assert.assertTrue(2 >= 3);
+ Assert.assertTrue(2 <= 3);
+ Assert.assertFalse(2 != 3);
+ Assert.assertFalse(2 == 3);
+ Assert.assertFalse(2 > 3);
+ Assert.assertFalse(2 < 3);
+ Assert.assertFalse(2 >= 3);
+ Assert.assertFalse(2 <= 3);
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert;
+ import org.hamcrest.Matchers;
+ import org.junit.Assert;
+
+ class MigrationTest {
+ void migrate() {
+ MatcherAssert.assertThat(2, Matchers.not(Matchers.is(3)));
+ MatcherAssert.assertThat(2, Matchers.is(3));
+ MatcherAssert.assertThat(2, Matchers.greaterThan(3));
+ MatcherAssert.assertThat(2, Matchers.lessThan(3));
+ MatcherAssert.assertThat(2, Matchers.greaterThanOrEqualTo(3));
+ MatcherAssert.assertThat(2, Matchers.lessThanOrEqualTo(3));
+ MatcherAssert.assertThat(2, Matchers.is(3));
+ MatcherAssert.assertThat(2, Matchers.not(Matchers.is(3)));
+ MatcherAssert.assertThat(2, Matchers.lessThanOrEqualTo(3));
+ MatcherAssert.assertThat(2, Matchers.greaterThanOrEqualTo(3));
+ MatcherAssert.assertThat(2, Matchers.lessThan(3));
+ MatcherAssert.assertThat(2, Matchers.greaterThan(3));
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix string`() {
+ myFixture.testAllQuickfixes(ULanguage.JAVA, """
+ import org.junit.Assert;
+
+ class Foo {
+ void migrate() {
+ Assert.assertTrue("asd".equals("zxc"));
+ Assert.assertTrue("asd" == "zxc");
+ Assert.assertTrue("asd".contains("qwe"));
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert;
+ import org.hamcrest.Matchers;
+ import org.junit.Assert;
+
+ class Foo {
+ void migrate() {
+ MatcherAssert.assertThat("asd", Matchers.is("zxc"));
+ MatcherAssert.assertThat("asd", Matchers.sameInstance("zxc"));
+ MatcherAssert.assertThat("asd", Matchers.containsString("qwe"));
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix collection`() {
+ myFixture.testAllQuickfixes(ULanguage.JAVA, """
+ import org.junit.Assert;
+ import java.util.Collection;
+
+ class Foo {
+ void migrate(Collection c, String o) {
+ Assert.assertTrue(c.contains(o));
+ Assert.assertEquals(c, o);
+ Assert.assertEquals("msg", c, o);
+ Assert.assertNotNull(c);
+ Assert.assertNull(c);
+ Assert.assertFalse(c.contains(o));
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert;
+ import org.hamcrest.Matchers;
+ import org.junit.Assert;
+ import java.util.Collection;
+
+ class Foo {
+ void migrate(Collection c, String o) {
+ MatcherAssert.assertThat(c, Matchers.hasItem(o));
+ MatcherAssert.assertThat(o, Matchers.is(c));
+ MatcherAssert.assertThat("msg", o, Matchers.is(c));
+ MatcherAssert.assertThat(c, Matchers.notNullValue());
+ MatcherAssert.assertThat(c, Matchers.nullValue());
+ MatcherAssert.assertThat(c, Matchers.not(Matchers.hasItem(o)));
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix array`() {
+ myFixture.testAllQuickfixes(ULanguage.JAVA, """
+ import org.junit.Assert;
+
+ class Foo {
+ void migrate(int[] a, int[] b) {
+ Assert.assertArrayEquals(a, b);
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert;
+ import org.hamcrest.Matchers;
+ import org.junit.Assert;
+
+ class Foo {
+ void migrate(int[] a, int[] b) {
+ MatcherAssert.assertThat(b, Matchers.is(a));
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+}
\ No newline at end of file
diff --git a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/test/KotlinHamcrestAssertionsConverterInspectionTest.kt b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/test/KotlinHamcrestAssertionsConverterInspectionTest.kt
new file mode 100644
index 000000000000..b7cdeb53774e
--- /dev/null
+++ b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/test/KotlinHamcrestAssertionsConverterInspectionTest.kt
@@ -0,0 +1,187 @@
+package com.intellij.codeInspection.tests.kotlin.test
+
+import com.intellij.codeInspection.tests.ULanguage
+import com.intellij.codeInspection.tests.test.HamcrestAssertionsConverterInspectionTestBase
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.roots.ContentEntry
+import com.intellij.openapi.roots.ModifiableRootModel
+import com.intellij.testFramework.LightProjectDescriptor
+import com.intellij.testFramework.PsiTestUtil
+import com.intellij.util.PathUtil
+import java.io.File
+
+class KotlinHamcrestAssertionsConverterInspectionTest : HamcrestAssertionsConverterInspectionTestBase() {
+ override fun getProjectDescriptor(): LightProjectDescriptor = object : JUnitProjectDescriptor(languageLevel) {
+ override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) {
+ super.configureModule(module, model, contentEntry)
+ val jar = File(PathUtil.getJarPathForClass(JvmStatic::class.java))
+ PsiTestUtil.addLibrary(model, "kotlin-stdlib", jar.parent, jar.name)
+ }
+ }
+
+ fun `test highlighting`() {
+ myFixture.testHighlighting(ULanguage.KOTLIN, """
+ import org.junit.Assert
+
+ class Foo {
+ fun m() {
+ Assert.assertTrue(2 != 3)
+ Assert.assertTrue(2 == 3)
+ Assert.assertTrue(2 > 3)
+ Assert.assertTrue(2 < 3)
+ Assert.assertTrue(2 >= 3)
+ Assert.assertTrue(2 <= 3)
+
+ Assert.assertFalse(2 != 3)
+ Assert.assertFalse(2 == 3)
+ Assert.assertFalse(2 > 3)
+ Assert.assertFalse(2 < 3)
+ Assert.assertFalse(2 >= 3)
+ Assert.assertFalse(2 <= 3)
+ }
+
+ fun m2() {
+ Assert.assertTrue("asd".equals("zxc"))
+ Assert.assertTrue("asd" == "zxc")
+ }
+
+ fun m3(c: Collection, o: String) {
+ Assert.assertTrue(c.contains(o))
+ Assert.assertEquals(c, o)
+ Assert.assertEquals("msg", c, o)
+ Assert.assertNotNull(c)
+ Assert.assertNull(c)
+ Assert.assertFalse(c.contains(o))
+ }
+
+ fun m(a: IntArray, b: IntArray) {
+ Assert.assertArrayEquals(a, b)
+ }
+ }
+ """.trimIndent())
+ }
+
+ fun `test quickfix binary expression`() {
+ myFixture.testAllQuickfixes(ULanguage.KOTLIN, """
+ import org.junit.Assert
+
+ class MigrationTest {
+ fun migrate() {
+ Assert.assertTrue(2 != 3)
+ Assert.assertTrue(2 == 3)
+ Assert.assertTrue(2 > 3)
+ Assert.assertTrue(2 < 3)
+ Assert.assertTrue(2 >= 3)
+ Assert.assertTrue(2 <= 3)
+ Assert.assertFalse(2 != 3)
+ Assert.assertFalse(2 == 3)
+ Assert.assertFalse(2 > 3)
+ Assert.assertFalse(2 < 3)
+ Assert.assertFalse(2 >= 3)
+ Assert.assertFalse(2 <= 3)
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert
+ import org.hamcrest.Matchers
+ import org.junit.Assert
+
+ class MigrationTest {
+ fun migrate() {
+ MatcherAssert.assertThat(2, Matchers.not(Matchers.`is`(3)))
+ MatcherAssert.assertThat(2, Matchers.`is`(3))
+ MatcherAssert.assertThat(2, Matchers.greaterThan(3))
+ MatcherAssert.assertThat(2, Matchers.lessThan(3))
+ MatcherAssert.assertThat(2, Matchers.greaterThanOrEqualTo(3))
+ MatcherAssert.assertThat(2, Matchers.lessThanOrEqualTo(3))
+ MatcherAssert.assertThat(2, Matchers.`is`(3))
+ MatcherAssert.assertThat(2, Matchers.not(Matchers.`is`(3)))
+ MatcherAssert.assertThat(2, Matchers.lessThanOrEqualTo(3))
+ MatcherAssert.assertThat(2, Matchers.greaterThanOrEqualTo(3))
+ MatcherAssert.assertThat(2, Matchers.lessThan(3))
+ MatcherAssert.assertThat(2, Matchers.greaterThan(3))
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix string`() {
+ myFixture.testAllQuickfixes(ULanguage.KOTLIN, """
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate() {
+ Assert.assertTrue("asd".equals("zxc"))
+ Assert.assertTrue("asd" === "zxc")
+ Assert.assertTrue("asd".contains("zxc"))
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert
+ import org.hamcrest.Matchers
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate() {
+ MatcherAssert.assertThat("asd", Matchers.`is`("zxc"))
+ MatcherAssert.assertThat("asd", Matchers.sameInstance("zxc"))
+ MatcherAssert.assertThat("asd", Matchers.containsString("zxc"))
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix collection`() {
+ myFixture.testAllQuickfixes(ULanguage.KOTLIN, """
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate(c: Collection, o: String) {
+ Assert.assertTrue(c.contains(o))
+ Assert.assertEquals(c, o)
+ Assert.assertEquals("msg", c, o)
+ Assert.assertNotNull(c)
+ Assert.assertNull(c)
+ Assert.assertFalse(c.contains(o))
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert
+ import org.hamcrest.Matchers
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate(c: Collection, o: String) {
+ MatcherAssert.assertThat(c, Matchers.hasItem(o))
+ MatcherAssert.assertThat(o, Matchers.`is`(c))
+ MatcherAssert.assertThat("msg", o, Matchers.`is`(c))
+ MatcherAssert.assertThat(c, Matchers.notNullValue())
+ MatcherAssert.assertThat(c, Matchers.nullValue())
+ MatcherAssert.assertThat(c, Matchers.not(Matchers.hasItem(o)))
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+
+ fun `test quickfix array`() {
+ myFixture.testAllQuickfixes(ULanguage.KOTLIN, """
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate(a: IntArray, b: IntArray) {
+ Assert.assertArrayEquals(a, b)
+ }
+ }
+ """.trimIndent(), """
+ import org.hamcrest.MatcherAssert
+ import org.hamcrest.Matchers
+ import org.junit.Assert
+
+ class Foo {
+ fun migrate(a: IntArray, b: IntArray) {
+ MatcherAssert.assertThat(b, Matchers.`is`(a))
+ }
+ }
+ """.trimIndent(), "Replace with 'assertThat()'")
+ }
+}
\ No newline at end of file
diff --git a/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/test/HamcrestAssertionsConverterInspectionTestBase.kt b/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/test/HamcrestAssertionsConverterInspectionTestBase.kt
new file mode 100644
index 000000000000..7b7257d61054
--- /dev/null
+++ b/jvm/jvm-analysis-tests/src/com/intellij/codeInspection/tests/test/HamcrestAssertionsConverterInspectionTestBase.kt
@@ -0,0 +1,25 @@
+package com.intellij.codeInspection.tests.test
+
+import com.intellij.codeInspection.test.junit.HamcrestAssertionsConverterInspection
+import com.intellij.codeInspection.tests.UastInspectionTestBase
+import com.intellij.codeInspection.tests.test.junit.addHamcrestLibrary
+import com.intellij.codeInspection.tests.test.junit.addJUnit4Library
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.roots.ContentEntry
+import com.intellij.openapi.roots.ModifiableRootModel
+import com.intellij.pom.java.LanguageLevel
+import com.intellij.testFramework.LightProjectDescriptor
+
+abstract class HamcrestAssertionsConverterInspectionTestBase : UastInspectionTestBase() {
+ override val inspection = HamcrestAssertionsConverterInspection()
+
+ protected open class JUnitProjectDescriptor(languageLevel: LanguageLevel) : ProjectDescriptor(languageLevel) {
+ override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) {
+ super.configureModule(module, model, contentEntry)
+ model.addJUnit4Library()
+ model.addHamcrestLibrary()
+ }
+ }
+
+ override fun getProjectDescriptor(): LightProjectDescriptor = JUnitProjectDescriptor(sdkLevel)
+}
\ No newline at end of file