diff --git a/build.gradle b/build.gradle index 6881923..3334112 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,7 @@ intellij { dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.10.0' // https://mvnrepository.com/artifact/org.assertj/assertj-core testCompile group: 'org.assertj', name: 'assertj-core', version: '3.12.2' diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/TestEngine.java b/src/main/java/com/bruce/intellijplugin/generatesetter/TestEngine.java new file mode 100644 index 0000000..68507b0 --- /dev/null +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/TestEngine.java @@ -0,0 +1,32 @@ +package com.bruce.intellijplugin.generatesetter; + +public enum TestEngine { + ASSERT("Plain java assert", "java.util", "Objects"), + JUNIT4("JUnit 4", "org.junit", "Assert"), + JUNIT5("JUnit 5", "org.junit.jupiter.api", "Assertions"), + TESTNG("TestNG", "org.testng.asserts", "Assertion"), + ASSERTJ("AssertJ", "org.assertj.core.api", "Assertions"), + HAMCREST("Hamcrest", "org.hamcrest.core", "MatcherAssert"); + + private final String formattedName; + private final String assertionsPackage; + private final String assertionsClassName; + + TestEngine(String formattedName, String assertionsPackage, String assertionsClassName) { + this.formattedName = formattedName; + this.assertionsPackage = assertionsPackage; + this.assertionsClassName = assertionsClassName; + } + + public String getFormattedName() { + return formattedName; + } + + public String getAssertionsPackage() { + return assertionsPackage; + } + + public String getAssertionsClassName() { + return assertionsClassName; + } +} diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertAllGetterAction.java b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertAllGetterAction.java index ad45fb2..0203225 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertAllGetterAction.java +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertAllGetterAction.java @@ -16,6 +16,10 @@ import com.bruce.intellijplugin.generatesetter.CommonConstants; import com.bruce.intellijplugin.generatesetter.GenerateAllHandlerAdapter; +import com.bruce.intellijplugin.generatesetter.TestEngine; +import com.bruce.intellijplugin.generatesetter.template.GenerateSetterService; +import com.bruce.intellijplugin.generatesetter.template.GenerateSetterState; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; @@ -23,40 +27,32 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiImportList; -import com.intellij.psi.PsiImportStatement; -import com.intellij.psi.PsiImportStaticStatement; -import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.compiled.ClsClassImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import org.jetbrains.annotations.NotNull; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.ASSERT; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.ASSERTJ; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.JUNIT4; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.JUNIT5; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.TESTNG; +import static com.bruce.intellijplugin.generatesetter.TestEngine.*; /** * @author bruce ge */ public class AssertAllGetterAction extends GenerateAllSetterBase { - enum TestEngine {ASSERT, JUNIT4, JUNIT5, TESTNG, ASSERTJ} // imports to add when generating asserts. - private static final Map engineImports = ImmutableMap.builder() - .put(JUNIT4, "static org.junit.Assert.assertEquals") - .put(JUNIT5, "static org.junit.jupiter.api.Assertions.assertEquals") - .put(TESTNG, "static org.testng.Assert.assertEquals") - .put(ASSERTJ, "static org.assertj.core.api.Assertions.assertThat") - .put(ASSERT, "java.util.Objects") + private static final Map> engineImports = ImmutableMap.>builder() + .put(JUNIT4, ImmutableList.of("static org.junit.Assert.assertEquals")) + .put(JUNIT5, ImmutableList.of("static org.junit.jupiter.api.Assertions.assertEquals")) + .put(TESTNG, ImmutableList.of("static org.testng.Assert.assertEquals")) + .put(ASSERTJ, ImmutableList.of("static org.assertj.core.api.Assertions.assertThat")) + .put(ASSERT, ImmutableList.of("java.util.Objects")) + .put(HAMCREST, ImmutableList.of("static org.hamcrest.MatcherAssert.assertThat", "org.hamcrest.Matchers.*")) .build(); // className like 'java.util.Objects' -> engine (only java.util.Objects) @@ -70,6 +66,7 @@ enum TestEngine {ASSERT, JUNIT4, JUNIT5, TESTNG, ASSERTJ} .put("org.junit.jupiter.api.Assertions", JUNIT5) .put("org.testng.Assert", TESTNG) .put("org.assertj.core.api.Assertions", ASSERTJ) + .put("org.hamcrest.MatcherAssert", HAMCREST) .build(); // engine -> assert static method @@ -78,6 +75,7 @@ enum TestEngine {ASSERT, JUNIT4, JUNIT5, TESTNG, ASSERTJ} .put(JUNIT5, "assertEquals") .put(TESTNG, "assertEquals") .put(ASSERTJ, "assertThat") + .put(HAMCREST, "assertThat") .build(); protected Project project; @@ -136,18 +134,25 @@ private TestEngine detectCurrentTestEngineInternal(Project project, PsiFile cont PsiJavaFile javaFile = (PsiJavaFile) containingFile; PsiImportList importList = javaFile.getImportList(); - // prefer AssertJ if it is in classpath + + // prefer TestEngine from settings if it is in classpath ProjectFileIndex index = ProjectFileIndex.getInstance(project); Module module = index.getModuleForFile(containingFile.getVirtualFile()); if (module != null) { + GenerateSetterState state = GenerateSetterService.getInstance().getState(); + TestEngine preferredTestEngine = state.getPreferredTestEngine(); + + String assertionsClassName = preferredTestEngine.getAssertionsClassName(); + GlobalSearchScope searchScope = GlobalSearchScope.moduleRuntimeScope(module, true); - PsiClass[] lists = PsiShortNamesCache.getInstance(project) - .getClassesByName("Assertions", searchScope); + PsiClass[] projectAssertionClasses = PsiShortNamesCache.getInstance(project) + .getClassesByName(assertionsClassName, searchScope); - for (PsiClass psiClass : lists) { - if ("org.assertj.core.api.Assertions".equals(psiClass.getName())) { + for (PsiClass psiClass : projectAssertionClasses) { + String psiClassQualifiedName = psiClass.getQualifiedName(); + if (String.format("%s.%s", preferredTestEngine.getAssertionsPackage(), preferredTestEngine.getAssertionsClassName()).equals(psiClassQualifiedName)) { detectImportedEngines(importList); - return ASSERTJ; + return preferredTestEngine; } } } @@ -165,22 +170,25 @@ private TestEngine detectCurrentTestEngineInternal(Project project, PsiFile cont } if (qualifiedName.startsWith("org.junit.jupiter.api.")) { - return TestEngine.JUNIT5; + return JUNIT5; } if (qualifiedName.startsWith("org.junit.")) { - return TestEngine.JUNIT4; + return JUNIT4; } if (qualifiedName.startsWith("org.assertj.")) { - return TestEngine.ASSERTJ; + return ASSERTJ; } if (qualifiedName.startsWith("org.testng.")) { - return TestEngine.TESTNG; + return TESTNG; + } + if (qualifiedName.startsWith("org.hamcrest.")) { + return HAMCREST; } } } } - return TestEngine.ASSERT; + return ASSERT; } private void detectImportedEngines(PsiImportList importList) { @@ -195,15 +203,27 @@ private void detectImportedEngines(PsiImportList importList) { for (PsiImportStaticStatement importStaticStatement : importStaticStatements) { PsiClass psiClass = importStaticStatement.resolveTargetClass(); if (psiClass == null) { - continue; - } - - String qualifiedName = psiClass.getQualifiedName(); - TestEngine testEngine = engineStaticImportsReversed.get(qualifiedName); - if (testEngine != null) { - String referenceName = importStaticStatement.getReferenceName(); // like assertEquals - if (referenceName == null || referenceName.equals(engineStaticImportsMethod.get(testEngine))) { - currentFileImportedEngines.add(testEngine); + //if it is a static import of a method from any testengine + PsiJavaCodeReferenceElement importReference = importStaticStatement.getImportReference(); + if (importReference == null || importReference.getQualifiedName() == null) { + continue; + } + String qualifiedName = importReference.getQualifiedName(); + engineStaticImportsReversed.entrySet() + .stream() + .filter(entry -> qualifiedName.startsWith(entry.getKey())) + .findFirst() + .ifPresent(entry -> currentFileImportedEngines.add(entry.getValue())); + + } else { + + String qualifiedName = psiClass.getQualifiedName(); + TestEngine testEngine = engineStaticImportsReversed.get(qualifiedName); + if (testEngine != null) { + String referenceName = importStaticStatement.getReferenceName(); // like assertEquals + if (referenceName == null || referenceName.equals(engineStaticImportsMethod.get(testEngine))) { + currentFileImportedEngines.add(testEngine); + } } } } @@ -263,6 +283,8 @@ public String formatLine(String line) { return "assertThat(" + getter + ").isEqualTo(" + value + ");"; case ASSERT: return "assert Objects.equals(" + value + ", " + getter + ");"; + case HAMCREST: + return "assertThat(" + value + ", equalTo(" + getter + ");"; default: throw new Error("Unknown case: " + currentFileTestEngine); } @@ -271,7 +293,7 @@ public String formatLine(String line) { @Override public void appendImportList(Set newImportList) { if (!currentFileImportedEngines.contains(currentFileTestEngine)) { - newImportList.add(engineImports.get(currentFileTestEngine)); + newImportList.addAll(engineImports.get(currentFileTestEngine)); } } } diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertNotNullAction.java b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertNotNullAction.java index 2ec7e80..f8d7680 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertNotNullAction.java +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/AssertNotNullAction.java @@ -1,6 +1,8 @@ package com.bruce.intellijplugin.generatesetter.actions; import com.bruce.intellijplugin.generatesetter.CommonConstants; +import com.bruce.intellijplugin.generatesetter.TestEngine; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.intellij.psi.PsiMethod; import org.jetbrains.annotations.NotNull; @@ -9,20 +11,15 @@ import java.util.Map; import java.util.Set; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.ASSERT; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.ASSERTJ; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.JUNIT4; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.JUNIT5; -import static com.bruce.intellijplugin.generatesetter.actions.AssertAllGetterAction.TestEngine.TESTNG; - public class AssertNotNullAction extends AssertAllGetterAction { // imports to add when generating asserts. - private static final Map engineImports = ImmutableMap.builder() - .put(JUNIT4, "static org.junit.Assert.assertNotNull") - .put(JUNIT5, "static org.junit.jupiter.api.Assertions.assertNotNull") - .put(TESTNG, "static org.testng.Assert.assertNotNull") - .put(ASSERTJ, "static org.assertj.core.api.Assertions.assertThat") - .put(ASSERT, "java.util.Objects") + private static final Map> engineImports = ImmutableMap.>builder() + .put(TestEngine.JUNIT4, ImmutableList.of("static org.junit.Assert.assertNotNull")) + .put(TestEngine.JUNIT5, ImmutableList.of("static org.junit.jupiter.api.Assertions.assertNotNull")) + .put(TestEngine.TESTNG, ImmutableList.of("static org.testng.Assert.assertNotNull")) + .put(TestEngine.ASSERTJ, ImmutableList.of("static org.assertj.core.api.Assertions.assertThat")) + .put(TestEngine.ASSERT, ImmutableList.of("java.util.Objects")) + .put(TestEngine.HAMCREST, ImmutableList.of("static org.hamcrest.MatcherAssert.assertThat", "org.hamcrest.Matchers.*")) .build(); private final GenerateAllAssertsHandlerAdapter generateAllHandler; @@ -48,7 +45,7 @@ protected String generateStringForNoParam(String generateName, Set currentFileImportedEngines = generateAllHandler.currentFileImportedEngines; if (!currentFileImportedEngines.contains(currentFileTestEngine)) { - newImportList.add(engineImports.get(currentFileTestEngine)); + newImportList.addAll(engineImports.get(currentFileTestEngine)); } switch (currentFileTestEngine) { @@ -60,6 +57,8 @@ protected String generateStringForNoParam(String generateName, return splitText + "assertThat(" + generateName + ").isNotNull();"; case ASSERT: return splitText + "assert " + generateName + " != null"; + case HAMCREST: + return splitText + "assertThat( " + generateName + ", notNullValue());"; default: throw new Error("Unknown case: " + currentFileTestEngine); } diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/GenerateAllSetterBase.java b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/GenerateAllSetterBase.java index 3657a25..fc51c32 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/actions/GenerateAllSetterBase.java +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/actions/GenerateAllSetterBase.java @@ -581,13 +581,12 @@ else if (psiClassOfParameter!=null && psiClassOfParameter.isEnum()) { } builder.append(");"); - generateAllHandler.appendImportList(newImportList); - if (generateAllHandler.forAssertWithDefaultValues()) { mainBuilder.append(generateAllHandler.formatLine(builder.toString())); } else { mainBuilder.append(builder); } + generateAllHandler.appendImportList(newImportList); } private static void appendCollectNotEmpty(StringBuilder builder, diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.form b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.form index 1cf6958..d2f67bc 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.form +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.form @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -124,6 +124,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.java b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.java index 9a55c39..913d301 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.java +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateAllSetterSettingForm.java @@ -14,6 +14,7 @@ package com.bruce.intellijplugin.generatesetter.template; +import com.bruce.intellijplugin.generatesetter.TestEngine; import com.intellij.icons.AllIcons; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.*; @@ -33,7 +34,10 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.ui.ClassNameReferenceEditor; import com.intellij.testFramework.LightVirtualFile; +import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.EditorTextField; +import com.intellij.ui.EnumComboBoxModel; +import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.components.JBList; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; @@ -46,6 +50,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.Arrays; import java.util.List; /** @@ -63,6 +68,8 @@ public class GenerateAllSetterSettingForm { private JPanel splitterPanel; private JCheckBox useOnlyJDKClassesCheckBox; private JPanel generateByTemplateSettings; + private JComboBox preferredTestEngineComboBox; + private JLabel preferAssertionsFromLabel; private GenerateSetterState myGenerateSetterState; private int currentSelectedIndex = -1; @@ -146,6 +153,16 @@ public void actionPerformed(ActionEvent e) { updateGenerateByTemplateCheckBoxState(); } }); + + preferredTestEngineComboBox.setModel(new EnumComboBoxModel<>(TestEngine.class)); + ListCellRendererWrapper aRenderer = new ListCellRendererWrapper() { + @Override + public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) { + setText(((TestEngine) value).getFormattedName()); + } + }; + preferredTestEngineComboBox.setRenderer(aRenderer); + } private void updateGenerateByTemplateCheckBoxState() { @@ -221,6 +238,9 @@ public void importFromSettings(GenerateSetterState state) { Boolean useJdkClassesOnly = state.getUseJdkClassesOnly(); useOnlyJDKClassesCheckBox.setSelected(useJdkClassesOnly); + TestEngine preferredTestEngine = state.getPreferredTestEngine(); + preferredTestEngineComboBox.setSelectedItem(preferredTestEngine); + Boolean generateByTemplate = state.getGenerateByTemplate(); enableGenerateByTemplateCheckBox.setSelected(generateByTemplate); updateGenerateByTemplateCheckBoxState(); @@ -252,6 +272,7 @@ public void importFromSettings(GenerateSetterState state) { public GenerateSetterState getTheState() { myGenerateSetterState.setGenerateByTemplate(enableGenerateByTemplateCheckBox.isSelected()); myGenerateSetterState.setUseJdkClassesOnly(useOnlyJDKClassesCheckBox.isSelected()); + myGenerateSetterState.setPreferredTestEngine(((TestEngine) preferredTestEngineComboBox.getSelectedItem())); return myGenerateSetterState; } diff --git a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateSetterState.java b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateSetterState.java index ca3fed4..1dad5d4 100644 --- a/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateSetterState.java +++ b/src/main/java/com/bruce/intellijplugin/generatesetter/template/GenerateSetterState.java @@ -15,6 +15,7 @@ package com.bruce.intellijplugin.generatesetter.template; +import com.bruce.intellijplugin.generatesetter.TestEngine; import org.apache.commons.compress.utils.Lists; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -28,6 +29,8 @@ public class GenerateSetterState { private Boolean useJdkClassesOnly = false; private Boolean generateByTemplate = false; + private TestEngine preferredTestEngine = TestEngine.ASSERTJ; + private List