diff --git a/README.MD b/README.MD index 076e842..ba1d636 100644 --- a/README.MD +++ b/README.MD @@ -1,5 +1,7 @@ Builder Generator Idea plugin ![Java CI with Gradle](https://github.com/mjedynak/builder-generator-idea-plugin/workflows/Java%20CI%20with%20Gradle/badge.svg?branch=master) =============== Plugin for IntelliJ IDEA that adds ability to generate builder for a class and switch between them. + Switching between builder and source class is similar to 'Go To Test' action. + Generated builder class does not use reflection, only setter methods or constructor. diff --git a/build.gradle.kts b/build.gradle.kts index 2b7f29a..ba8ff9b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } group = "pl.mjedynak" -version = "1.3.0" +version = "1.4.0" repositories { mavenCentral() diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/action/handler/DisplayChoosers.java b/src/main/java/pl/mjedynak/idea/plugins/builder/action/handler/DisplayChoosers.java index 5039ad5..de37eab 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/action/handler/DisplayChoosers.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/action/handler/DisplayChoosers.java @@ -65,7 +65,7 @@ private void writeBuilderIfNecessary( List selectedElements = memberChooserDialog.getSelectedElements(); PsiFieldsForBuilder psiFieldsForBuilder = psiFieldsForBuilderFactory.createPsiFieldsForBuilder(selectedElements, psiClassFromEditor); BuilderContext context = new BuilderContext( - project, psiFieldsForBuilder, targetDirectory, className, psiClassFromEditor, methodPrefix, createBuilderDialog.isInnerBuilder(), createBuilderDialog.hasButMethod(), createBuilderDialog.useSingleField()); + project, psiFieldsForBuilder, targetDirectory, className, psiClassFromEditor, methodPrefix, createBuilderDialog.isInnerBuilder(), createBuilderDialog.hasButMethod(), createBuilderDialog.useSingleField(), createBuilderDialog.hasAddCopyConstructor()); builderWriter.writeBuilder(context, existingBuilder); } } diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/gui/CreateBuilderDialog.java b/src/main/java/pl/mjedynak/idea/plugins/builder/gui/CreateBuilderDialog.java index e6076c4..de1e8b1 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/gui/CreateBuilderDialog.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/gui/CreateBuilderDialog.java @@ -53,18 +53,20 @@ public class CreateBuilderDialog extends DialogWrapper { private static BuilderGeneratorSettingsState defaultStates = BuilderGeneratorSettingsState.getInstance(); - private PsiHelper psiHelper; - private GuiHelper guiHelper; - private Project project; + private final PsiHelper psiHelper; + private final GuiHelper guiHelper; + private final Project project; + private final PsiClass sourceClass; + private final JTextField targetClassNameField; + private final JTextField targetMethodPrefix; + private final ReferenceEditorComboWithBrowseButton targetPackageField; + private final PsiClass existingBuilder; private PsiDirectory targetDirectory; - private PsiClass sourceClass; - private JTextField targetClassNameField; - private JTextField targetMethodPrefix; private JCheckBox innerBuilder; private JCheckBox butMethod; private JCheckBox useSingleField; - private ReferenceEditorComboWithBrowseButton targetPackageField; - private PsiClass existingBuilder; + private JCheckBox copyConstructor; + public CreateBuilderDialog(Project project, @@ -211,7 +213,6 @@ public void actionPerformed(ActionEvent e) { panel.add(innerBuilder, gbConstraints); // Inner builder - // but method gbConstraints.insets = new Insets(4, 8, 4, 8); gbConstraints.gridx = 0; @@ -232,7 +233,6 @@ public void actionPerformed(ActionEvent e) { panel.add(butMethod, gbConstraints); // but method - // useSingleField gbConstraints.insets = new Insets(4, 8, 4, 8); gbConstraints.gridx = 0; @@ -253,6 +253,26 @@ public void actionPerformed(ActionEvent e) { panel.add(useSingleField, gbConstraints); // useSingleField + // copy constructor + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridx = 0; + gbConstraints.weightx = 0; + gbConstraints.gridy = 7; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.anchor = GridBagConstraints.WEST; + panel.add(new JLabel("Add copy constructor"), gbConstraints); + + gbConstraints.insets = new Insets(4, 8, 4, 8); + gbConstraints.gridx = 1; + gbConstraints.weightx = 1; + gbConstraints.gridwidth = 1; + gbConstraints.fill = GridBagConstraints.HORIZONTAL; + gbConstraints.anchor = GridBagConstraints.WEST; + copyConstructor = new JCheckBox(); + copyConstructor.setSelected(defaultStates.isAddCopyConstructor); + panel.add(copyConstructor, gbConstraints); + // copy constructor + return panel; } @@ -347,6 +367,10 @@ public boolean useSingleField() { return useSingleField.isSelected(); } + public boolean hasAddCopyConstructor() { + return copyConstructor.isSelected(); + } + public PsiDirectory getTargetDirectory() { return targetDirectory; } diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilder.java b/src/main/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilder.java index 10c7411..ff5f570 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilder.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilder.java @@ -6,6 +6,7 @@ import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierList; import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiType; @@ -24,19 +25,17 @@ public class BuilderPsiClassBuilder { - private static final String PRIVATE_STRING = "private"; private static final String SPACE = " "; private static final String A_PREFIX = " a"; private static final String AN_PREFIX = " an"; private static final String SEMICOLON = ","; - static final String STATIC_MODIFIER = "static"; - static final String FINAL_MODIFIER = "final"; - private PsiHelper psiHelper = new PsiHelper(); - private PsiFieldsModifier psiFieldsModifier = new PsiFieldsModifier(); - private PsiFieldVerifier psiFieldVerifier = new PsiFieldVerifier(); - private CodeStyleSettings codeStyleSettings = new CodeStyleSettings(); + private final PsiHelper psiHelper = new PsiHelper(); + private final PsiFieldsModifier psiFieldsModifier = new PsiFieldsModifier(); + private final PsiFieldVerifier psiFieldVerifier = new PsiFieldVerifier(); + private final CodeStyleSettings codeStyleSettings = new CodeStyleSettings(); private ButMethodCreator butMethodCreator; + private CopyConstructorCreator copyConstructorCreator; private MethodCreator methodCreator; private PsiClass srcClass = null; @@ -54,13 +53,14 @@ public class BuilderPsiClassBuilder { private boolean useSingleField = false; private boolean isInline = false; + private boolean copyConstructor = false; public BuilderPsiClassBuilder aBuilder(BuilderContext context) { initializeFields(context); JavaDirectoryService javaDirectoryService = psiHelper.getJavaDirectoryService(); builderClass = javaDirectoryService.createClass(context.getTargetDirectory(), builderClassName); PsiModifierList modifierList = builderClass.getModifierList(); - modifierList.setModifierProperty(FINAL_MODIFIER, true); + modifierList.setModifierProperty(PsiModifier.FINAL, true); return this; } @@ -68,8 +68,8 @@ public BuilderPsiClassBuilder anInnerBuilder(BuilderContext context) { initializeFields(context); builderClass = elementFactory.createClass(builderClassName); PsiModifierList modifierList = builderClass.getModifierList(); - modifierList.setModifierProperty(FINAL_MODIFIER, true); - modifierList.setModifierProperty(STATIC_MODIFIER, true); + modifierList.setModifierProperty(PsiModifier.FINAL, true); + modifierList.setModifierProperty(PsiModifier.STATIC, true); return this; } @@ -87,7 +87,9 @@ private void initializeFields(BuilderContext context) { bestConstructor = context.getPsiFieldsForBuilder().getBestConstructor(); methodCreator = new MethodCreator(elementFactory, builderClassName); butMethodCreator = new ButMethodCreator(elementFactory); + copyConstructorCreator = new CopyConstructorCreator(elementFactory); isInline = allSelectedPsiFields.size() == psiFieldsForConstructor.size(); + copyConstructor = context.hasAddCopyConstructor(); } public BuilderPsiClassBuilder withFields() { @@ -103,14 +105,17 @@ public BuilderPsiClassBuilder withFields() { return this; } - public BuilderPsiClassBuilder withPrivateConstructor() { + public BuilderPsiClassBuilder withConstructor() { PsiMethod constructor; if (useSingleField) { constructor = elementFactory.createMethodFromText(builderClassName + "(){ " + srcClassFieldName + " = new " + srcClassName + "(); }", srcClass); } else { constructor = elementFactory.createConstructor(); } - constructor.getModifierList().setModifierProperty(PRIVATE_STRING, true); + + constructor.getModifierList().setModifierProperty(copyConstructor ? PsiModifier.PUBLIC : PsiModifier.PRIVATE, true); + + builderClass.add(constructor); return this; } @@ -140,7 +145,7 @@ public BuilderPsiClassBuilder withSetMethods(String methodPrefix) { } private boolean isInnerBuilder(PsiClass aClass) { - return aClass.hasModifierProperty("static"); + return aClass.hasModifierProperty(PsiModifier.STATIC); } public BuilderPsiClassBuilder withButMethod() { @@ -149,6 +154,12 @@ public BuilderPsiClassBuilder withButMethod() { return this; } + public BuilderPsiClassBuilder withCopyConstructor() { + final PsiMethod method = copyConstructorCreator.copyConstructor(builderClass, srcClass, isInnerBuilder(builderClass), useSingleField); + builderClass.add(method); + return this; + } + private void createAndAddMethod(PsiField psiField, String methodPrefix) { builderClass.add(methodCreator.createMethod(psiField, methodPrefix, srcClassFieldName, useSingleField)); } diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/psi/CopyConstructorCreator.java b/src/main/java/pl/mjedynak/idea/plugins/builder/psi/CopyConstructorCreator.java new file mode 100644 index 0000000..750b294 --- /dev/null +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/psi/CopyConstructorCreator.java @@ -0,0 +1,59 @@ +package pl.mjedynak.idea.plugins.builder.psi; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PropertyUtilBase; +import com.intellij.util.IncorrectOperationException; + +import static java.util.Objects.nonNull; + +public class CopyConstructorCreator { + + private final PsiElementFactory elementFactory; + + public CopyConstructorCreator(PsiElementFactory elementFactory) { + this.elementFactory = elementFactory; + } + + public PsiMethod copyConstructor(PsiClass builderClass, PsiClass srcClass, boolean isInnerBuilder, boolean useSingleField) { + PsiField[] fields = builderClass.getAllFields(); + StringBuilder text = new StringBuilder( + "public " + builderClass.getNameIdentifier().getText() + "(" + srcClass.getQualifiedName() + " other) { "); + + for (PsiField field : fields) { + text.append("this.").append(field.getName()).append(" = other"); + + if (srcClass.isRecord()) { + text.append(".").append(field.getName()).append("();"); + } else if (isInnerBuilder) { + if (useSingleField) { + text.append(";"); + } else { + text.append(".").append(field.getName()).append(";"); + } + } else { + if (useSingleField) { + text.append(";"); + } else { + text.append(".").append(findFieldGetter(srcClass, field).getName()).append("();"); + } + } + } + text.append(" }"); + + return elementFactory.createMethodFromText(text.toString(), srcClass); + } + + private PsiMethod findFieldGetter(final PsiClass srcClass, final PsiField field) { + PsiMethod method = srcClass.findMethodBySignature(PropertyUtilBase.generateGetterPrototype(field), true); + + if (nonNull(method)) { + return method; + } + + throw new IncorrectOperationException("Could not create copy constructor as cannot get field getters"); + } + +} diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsComponent.java b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsComponent.java index 63c1b84..6217e77 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsComponent.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsComponent.java @@ -11,60 +11,71 @@ public class BuilderGeneratorSettingsComponent { - private final JPanel myMainPanel; - private final JBTextField defaultMethodPrefixText = new JBTextField(); - private final JBCheckBox innerBuilderCheckBox = new JBCheckBox("Inner builder"); - private final JBCheckBox butMethodCheckBox = new JBCheckBox("'but' method'"); - private final JBCheckBox useSinglePrefixCheckBox = new JBCheckBox("Use single prefix"); - - public BuilderGeneratorSettingsComponent() { - myMainPanel = FormBuilder.createFormBuilder() - .addLabeledComponent(new JBLabel("Default prefix: "), defaultMethodPrefixText, 1, false) - .addComponent(innerBuilderCheckBox, 1) - .addComponent(butMethodCheckBox, 1) - .addComponent(useSinglePrefixCheckBox, 1) - .addComponentFillVertically(new JPanel(), 0) - .getPanel(); - } - - public JPanel getPanel() { - return myMainPanel; - } - - public JComponent getPreferredFocusedComponent() { - return defaultMethodPrefixText; - } - - @NotNull - public String getDefaultMethodPrefixText() { - return defaultMethodPrefixText.getText(); - } - - public void setDefaultMethodPrefixText(@NotNull String newText) { - defaultMethodPrefixText.setText(newText); - } - - public boolean isInnerBuilder() { - return innerBuilderCheckBox.isSelected(); - } - - public void setInnerBuilder(boolean isInnerBuilder) { - innerBuilderCheckBox.setSelected(isInnerBuilder); - } - - public boolean isButMethod() { - return butMethodCheckBox.isSelected(); - } - - public void setButMethod(boolean isButMethod) { - butMethodCheckBox.setSelected(isButMethod); - } - - public boolean isUseSinglePrefix() { - return useSinglePrefixCheckBox.isSelected(); - } - - public void setUseSinglePrefix(boolean isUseSinglePrefix) { - useSinglePrefixCheckBox.setSelected(isUseSinglePrefix); - } + private final JPanel myMainPanel; + private final JBTextField defaultMethodPrefixText = new JBTextField(); + private final JBCheckBox innerBuilderCheckBox = new JBCheckBox("Inner builder"); + private final JBCheckBox butMethodCheckBox = new JBCheckBox("'but' method'"); + private final JBCheckBox useSinglePrefixCheckBox = new JBCheckBox("Use single prefix"); + private final JBCheckBox addCopyConstructorCheckBox = new JBCheckBox("Add copy constructor"); + + public BuilderGeneratorSettingsComponent() { + myMainPanel = FormBuilder.createFormBuilder() + .addLabeledComponent(new JBLabel("Default prefix: "), defaultMethodPrefixText, 1, false) + .addComponent(innerBuilderCheckBox, 1) + .addComponent(butMethodCheckBox, 1) + .addComponent(useSinglePrefixCheckBox, 1) + .addComponent(addCopyConstructorCheckBox, 1) + .addComponentFillVertically(new JPanel(), 0) + .getPanel(); } + + public JPanel getPanel() { + return myMainPanel; + } + + public JComponent getPreferredFocusedComponent() { + return defaultMethodPrefixText; + } + + @NotNull + public String getDefaultMethodPrefixText() { + return defaultMethodPrefixText.getText(); + } + + public void setDefaultMethodPrefixText(@NotNull String newText) { + defaultMethodPrefixText.setText(newText); + } + + public boolean isInnerBuilder() { + return innerBuilderCheckBox.isSelected(); + } + + public void setInnerBuilder(boolean isInnerBuilder) { + innerBuilderCheckBox.setSelected(isInnerBuilder); + } + + public boolean isButMethod() { + return butMethodCheckBox.isSelected(); + } + + public void setButMethod(boolean isButMethod) { + butMethodCheckBox.setSelected(isButMethod); + } + + public boolean isUseSinglePrefix() { + return useSinglePrefixCheckBox.isSelected(); + } + + public void setUseSinglePrefix(boolean isUseSinglePrefix) { + useSinglePrefixCheckBox.setSelected(isUseSinglePrefix); + } + + public boolean isAddCopyConstructor() { + return addCopyConstructorCheckBox.isSelected(); + } + + public void setAddCopyConstructor(boolean addCopyConstructor) { + addCopyConstructorCheckBox.setSelected(addCopyConstructor); + } + +} diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsConfigurable.java b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsConfigurable.java index 37f36e7..d0c4cc4 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsConfigurable.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsConfigurable.java @@ -38,6 +38,7 @@ public boolean isModified() { modified |= mySettingsComponent.isInnerBuilder() != settings.isInnerBuilder; modified |= mySettingsComponent.isButMethod() != settings.isButMethod; modified |= mySettingsComponent.isUseSinglePrefix() != settings.isUseSinglePrefix; + modified |= mySettingsComponent.isAddCopyConstructor() != settings.isAddCopyConstructor; return modified; } @@ -48,6 +49,7 @@ public void apply() { settings.isInnerBuilder = mySettingsComponent.isInnerBuilder(); settings.isButMethod = mySettingsComponent.isButMethod(); settings.isUseSinglePrefix = mySettingsComponent.isUseSinglePrefix(); + settings.isAddCopyConstructor = mySettingsComponent.isAddCopyConstructor(); } @Override @@ -57,6 +59,7 @@ public void reset() { mySettingsComponent.setInnerBuilder(settings.isInnerBuilder); mySettingsComponent.setButMethod(settings.isButMethod); mySettingsComponent.setUseSinglePrefix(settings.isUseSinglePrefix); + mySettingsComponent.setAddCopyConstructor(settings.isAddCopyConstructor); } @Override diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsState.java b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsState.java index 4a624c6..7be62e2 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsState.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/settings/BuilderGeneratorSettingsState.java @@ -23,6 +23,7 @@ public class BuilderGeneratorSettingsState implements PersistentStateComponent { - private GuiHelper guiHelper = new GuiHelper(); - private PsiHelper psiHelper = new PsiHelper(); - private BuilderPsiClassBuilder builderPsiClassBuilder; - private BuilderContext context; - private PsiClass existingBuilder; + private final GuiHelper guiHelper = new GuiHelper(); + private final PsiHelper psiHelper = new PsiHelper(); + private final BuilderPsiClassBuilder builderPsiClassBuilder; + private final BuilderContext context; + private final PsiClass existingBuilder; BuilderWriterComputable(BuilderPsiClassBuilder builderPsiClassBuilder, BuilderContext context, PsiClass existingBuilder) { this.builderPsiClassBuilder = builderPsiClassBuilder; @@ -45,7 +45,7 @@ private PsiElement createBuilder() { } return targetClass; } catch (IncorrectOperationException e) { - showErrorMessage(context.getProject(), context.getClassName()); + showErrorMessage(context.getProject(), context.getClassName(), e.getMessage()); e.printStackTrace(); return null; } @@ -54,20 +54,22 @@ private PsiElement createBuilder() { private PsiClass getInnerBuilderPsiClass() { BuilderPsiClassBuilder builder = builderPsiClassBuilder.anInnerBuilder(context) .withFields() - .withPrivateConstructor() + .withConstructor() .withInitializingMethod() .withSetMethods(context.getMethodPrefix()); addButMethodIfNecessary(builder); + addCopyConstructorIfNecessary(builder); return builder.build(); } private PsiClass getBuilderPsiClass() { BuilderPsiClassBuilder builder = builderPsiClassBuilder.aBuilder(context) .withFields() - .withPrivateConstructor() + .withConstructor() .withInitializingMethod() .withSetMethods(context.getMethodPrefix()); addButMethodIfNecessary(builder); + addCopyConstructorIfNecessary(builder); return builder.build(); } @@ -77,12 +79,22 @@ private void addButMethodIfNecessary(BuilderPsiClassBuilder builder) { } } + private void addCopyConstructorIfNecessary(BuilderPsiClassBuilder builder) { + if (context.hasAddCopyConstructor()) { + builder.withCopyConstructor(); + } + } + private void navigateToClassAndPositionCursor(Project project, PsiClass targetClass) { guiHelper.positionCursor(project, targetClass.getContainingFile(), targetClass.getLBrace()); } - private void showErrorMessage(Project project, String className) { + private void showErrorMessage(Project project, String className, String message) { + BuilderWriterErrorRunnable builderWriterErrorRunnable = + message == null ? new BuilderWriterErrorRunnable(project, className) + : new BuilderWriterErrorRunnable(project, className, message); + Application application = psiHelper.getApplication(); - application.invokeLater(new BuilderWriterErrorRunnable(project, className)); + application.invokeLater(builderWriterErrorRunnable); } } \ No newline at end of file diff --git a/src/main/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterErrorRunnable.java b/src/main/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterErrorRunnable.java index 8529211..086b727 100644 --- a/src/main/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterErrorRunnable.java +++ b/src/main/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterErrorRunnable.java @@ -11,16 +11,24 @@ public class BuilderWriterErrorRunnable implements Runnable { private Project project; private String className; + private String message; public BuilderWriterErrorRunnable(Project project, String className) { this.project = project; this.className = className; + this.message = INTENTION_ERROR_CANNOT_CREATE_CLASS_MESSAGE; + } + + public BuilderWriterErrorRunnable(Project project, String className, String message) { + this.project = project; + this.className = className; + this.message = message; } @Override public void run() { Messages.showErrorDialog(project, - CodeInsightBundle.message(INTENTION_ERROR_CANNOT_CREATE_CLASS_MESSAGE, className), + CodeInsightBundle.message(message, className), CodeInsightBundle.message(INTENTION_ERROR_CANNOT_CREATE_CLASS_TITLE)); } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b747e93..81c4ed3 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -26,16 +26,22 @@ ]]> - 1.3.0 + 1.4.0 +
    +
  • Added ability to generate builder with copy constructor + (contribution by c-mansfield)
  • +
version 1.3.0
  • Added ability to store default settings (contribution by NexRX)
- version 1.3.0 + version 1.2.0
  • Added ability to generate builder for Java records and lombok @Value types diff --git a/src/test/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilderTest.java b/src/test/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilderTest.java deleted file mode 100644 index 0e28949..0000000 --- a/src/test/java/pl/mjedynak/idea/plugins/builder/psi/BuilderPsiClassBuilderTest.java +++ /dev/null @@ -1,607 +0,0 @@ -package pl.mjedynak.idea.plugins.builder.psi; - -import com.google.common.collect.Lists; -import com.intellij.openapi.project.Project; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiModifierList; -import com.intellij.psi.PsiParameter; -import com.intellij.psi.PsiParameterList; -import com.intellij.psi.PsiType; -import com.intellij.psi.impl.source.PsiFieldImpl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.quality.Strictness; -import pl.mjedynak.idea.plugins.builder.psi.model.PsiFieldsForBuilder; -import pl.mjedynak.idea.plugins.builder.settings.CodeStyleSettings; -import pl.mjedynak.idea.plugins.builder.verifier.PsiFieldVerifier; -import pl.mjedynak.idea.plugins.builder.writer.BuilderContext; - -import java.util.List; - -import static org.apache.commons.lang.StringUtils.EMPTY; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.withSettings; -import static org.springframework.test.util.ReflectionTestUtils.getField; -import static org.springframework.test.util.ReflectionTestUtils.setField; - - -@ExtendWith(MockitoExtension.class) -public class BuilderPsiClassBuilderTest { - private static final PsiParameter[] EMPTY_PSI_PARAMETERS = {}; - - @InjectMocks private BuilderPsiClassBuilder psiClassBuilder; - @Mock(strictness = Mock.Strictness.LENIENT) private CodeStyleSettings settings; - @Mock(strictness = Mock.Strictness.LENIENT) private PsiHelper psiHelper; - @Mock private ButMethodCreator butMethodCreator; - @Mock private MethodCreator methodCreator; - @Mock private PsiFieldsModifier psiFieldsModifier; - @Mock private Project project; - @Mock private PsiDirectory targetDirectory; - @Mock private PsiClass srcClass; - @Mock(strictness = Mock.Strictness.LENIENT) private JavaDirectoryService javaDirectoryService; - @Mock(strictness = Mock.Strictness.LENIENT) private PsiClass builderClass; - @Mock private JavaPsiFacade javaPsiFacade; - @Mock(strictness = Mock.Strictness.LENIENT) private PsiElementFactory elementFactory; - @Mock private PsiFieldsForBuilder psiFieldsForBuilder; - @Mock private PsiMethod psiMethod; - @Mock private PsiModifierList psiModifierList; - @Mock private PsiMethod bestConstructor; - @Mock(strictness = Mock.Strictness.LENIENT) private PsiFieldVerifier psiFieldVerifier; - - @Captor private ArgumentCaptor stringCaptor; - - private BuilderContext createBuilderContext(boolean useSingleField) { - return new BuilderContext(project, psiFieldsForBuilder, targetDirectory, builderClassName, srcClass, "anyPrefix", false, false, useSingleField); - } - - private void mockCodeStyleManager() { - setField(psiClassBuilder, "codeStyleSettings", settings); - given(settings.getFieldNamePrefix()).willReturn("m_"); - given(settings.getParameterNamePrefix()).willReturn(EMPTY); - } - - private BuilderContext context; - private final List psiFieldsForSetters = Lists.newArrayList(); - private final List psiFieldsForConstructor = Lists.newArrayList(); - private final List allSelectedPsiFields = Lists.newArrayList(); - - private final String builderClassName = "BuilderClassName"; - private final String srcClassName = "ClassName"; - private final String srcClassFieldName = "className"; - - @BeforeEach - public void setUp() { - setField(psiClassBuilder, "psiFieldsModifier", psiFieldsModifier); - setField(psiClassBuilder, "psiHelper", psiHelper); - given(psiHelper.getJavaDirectoryService()).willReturn(javaDirectoryService); - given(javaDirectoryService.createClass(targetDirectory, builderClassName)).willReturn(builderClass); - given(psiHelper.getJavaPsiFacade(project)).willReturn(javaPsiFacade); - given(javaPsiFacade.getElementFactory()).willReturn(elementFactory); - given(srcClass.getName()).willReturn(srcClassName); - given(psiFieldsForBuilder.getFieldsForConstructor()).willReturn(psiFieldsForConstructor); - given(psiFieldsForBuilder.getFieldsForSetters()).willReturn(psiFieldsForSetters); - given(psiFieldsForBuilder.getAllSelectedFields()).willReturn(allSelectedPsiFields); - given(psiFieldsForBuilder.getBestConstructor()).willReturn(bestConstructor); - given(elementFactory.createClass(builderClassName)).willReturn(builderClass); - given(builderClass.getModifierList()).willReturn(psiModifierList); - context = createBuilderContext(false); - mockCodeStyleManager(); - } - - @Test - void shouldSetPassedFieldsAndCreateRequiredOnes() { - // when - BuilderPsiClassBuilder result = psiClassBuilder.aBuilder(context); - - // then - assertFieldsAreSet(result); - verify(psiModifierList).setModifierProperty(PsiModifier.FINAL, true); - } - - @Test - void shouldSetPassedFieldsAndCreateRequiredOnesForInnerBuilder() { - // when - BuilderPsiClassBuilder result = psiClassBuilder.anInnerBuilder(context); - - // then - assertFieldsAreSet(result); - verify(psiModifierList).setModifierProperty(PsiModifier.STATIC, true); - verify(psiModifierList).setModifierProperty(PsiModifier.FINAL, true); - } - - @Test - void shouldDelegatePsiFieldsModification() { - // when - BuilderPsiClassBuilder result = psiClassBuilder.aBuilder(context).withFields(); - - // then - assertThat(result).isSameAs(psiClassBuilder); - verify(psiFieldsModifier).modifyFields(psiFieldsForSetters, psiFieldsForConstructor, builderClass); - } - - @Test - void shouldNotDelegatePsiFieldsModificationButDirectlyCreateFieldWhenUsingSingleField() { - // given - context = createBuilderContext(true); - String fieldText = "private " + srcClassName + " " + srcClassFieldName + ";"; - PsiField singleField = mock(PsiField.class); - given(elementFactory.createFieldFromText(fieldText, srcClass)).willReturn(singleField); - - // when - BuilderPsiClassBuilder result = psiClassBuilder.aBuilder(context).withFields(); - - // then - assertThat(result).isSameAs(psiClassBuilder); - verify(psiFieldsModifier, never()).modifyFields(psiFieldsForSetters, psiFieldsForConstructor, builderClass); - verify(builderClass).add(singleField); - } - - @Test - void shouldAddPrivateConstructorToBuildClass() { - // given - PsiMethod constructor = mock(PsiMethod.class); - PsiModifierList modifierList = mock(PsiModifierList.class); - given(constructor.getModifierList()).willReturn(modifierList); - given(elementFactory.createConstructor()).willReturn(constructor); - - // when - psiClassBuilder.aBuilder(context).withPrivateConstructor(); - - // then - verify(modifierList).setModifierProperty(PsiModifier.PRIVATE, true); - verify(builderClass).add(constructor); - } - - @Test - void shouldAddPrivateConstructorToBuildClassWithBuildingObjectInstantiationWhenUsingSingleField() { - // given - context = createBuilderContext(true); - String constructorText = builderClassName + "(){ " + srcClassFieldName + " = new " + srcClassName + "(); }"; - PsiMethod constructor = mock(PsiMethod.class); - PsiModifierList modifierList = mock(PsiModifierList.class); - given(constructor.getModifierList()).willReturn(modifierList); - given(elementFactory.createMethodFromText(constructorText, srcClass)).willReturn(constructor); - - // when - psiClassBuilder.aBuilder(context).withPrivateConstructor(); - - // then - verify(modifierList).setModifierProperty(PsiModifier.PRIVATE, true); - verify(builderClass).add(constructor); - } - - @Test - void shouldAddInitializingMethod() { - // given - PsiMethod method = mock(PsiMethod.class); - given(elementFactory.createMethodFromText( - "public static " + builderClassName + " a" + srcClassName + "() { return new " + builderClassName + "(); }", srcClass)).willReturn(method); - - // when - psiClassBuilder.aBuilder(context).withInitializingMethod(); - - // then - verify(builderClass).add(method); - } - - @Test - void shouldAddInitializingMethodStartingWithAnIfSourceClassNameStartsWithVowel() { - // given - PsiMethod method = mock(PsiMethod.class); - String srcClassNameStartingWithVowel = "Inventory"; - given(srcClass.getName()).willReturn(srcClassNameStartingWithVowel); - given(elementFactory.createMethodFromText( - "public static " + builderClassName + " an" + srcClassNameStartingWithVowel + "() { return new " + builderClassName + "(); }", srcClass)).willReturn(method); - - // when - psiClassBuilder.aBuilder(context).withInitializingMethod(); - - // then - verify(builderClass).add(method); - } - - @Test - void shouldAddSetMethodsForFieldsFromBothLists() { - // given - PsiFieldImpl psiFieldForSetter = mock(PsiFieldImpl.class); - psiFieldsForSetters.add(psiFieldForSetter); - PsiFieldImpl psiFieldForConstructor = mock(PsiFieldImpl.class); - psiFieldsForConstructor.add(psiFieldForConstructor); - String methodPrefix = "with"; - PsiMethod methodForFieldForSetter = mock(PsiMethod.class); - PsiMethod methodForFieldForConstructor = mock(PsiMethod.class); - given(methodCreator.createMethod(psiFieldForSetter, methodPrefix, srcClassFieldName, false)).willReturn(methodForFieldForSetter); - given(methodCreator.createMethod(psiFieldForConstructor, methodPrefix, srcClassFieldName, false)).willReturn(methodForFieldForConstructor); - BuilderPsiClassBuilder builder = psiClassBuilder.aBuilder(context); - setField(builder, "methodCreator", methodCreator); - - // when - builder.withSetMethods(methodPrefix); - - // then - verify(builderClass).add(methodForFieldForSetter); - verify(builderClass).add(methodForFieldForConstructor); - } - - @Test - void shouldAddAllSelectedFieldAsSetterInInnerBuilder() { - // giver - PsiField selectedField = mock(PsiField.class); - allSelectedPsiFields.add(selectedField); - - String methodPrefix = "with"; - - PsiMethod setterMethod = mock(PsiMethod.class); - given(methodCreator.createMethod(selectedField, methodPrefix, srcClassFieldName, false)).willReturn(setterMethod); - - BuilderPsiClassBuilder builder = psiClassBuilder.anInnerBuilder(context); - setField(builder, "methodCreator", methodCreator); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - // when - builder.withSetMethods(methodPrefix); - - // then - verify(builderClass).add(setterMethod); - } - - @Test - void shouldAddAllSelectedFieldAsSetterWhenUsingSingleField() { - // given - context = createBuilderContext(true); - PsiField selectedField = mock(PsiField.class); - allSelectedPsiFields.add(selectedField); - - String methodPrefix = "with"; - - PsiMethod setterMethod = mock(PsiMethod.class); - given(methodCreator.createMethod(selectedField, methodPrefix, srcClassFieldName, true)).willReturn(setterMethod); - - BuilderPsiClassBuilder builder = psiClassBuilder.anInnerBuilder(context); - setField(builder, "methodCreator", methodCreator); - - // when - builder.withSetMethods(methodPrefix); - - // then - verify(builderClass).add(setterMethod); - } - - @Test - void shouldAddButMethod() { - // given - given(butMethodCreator.butMethod(builderClassName, builderClass, srcClass, srcClassFieldName, false)).willReturn(psiMethod); - BuilderPsiClassBuilder builder = psiClassBuilder.aBuilder(context); - setField(builder, "butMethodCreator", butMethodCreator); - - // when - BuilderPsiClassBuilder result = builder.withButMethod(); - - // then - assertThat(result).isSameAs(psiClassBuilder); - verify(builderClass).add(psiMethod); - } - - @Test - void shouldAddButMethodWhenUsingSingleField() { - // given - context = createBuilderContext(true); - given(butMethodCreator.butMethod(builderClassName, builderClass, srcClass, srcClassFieldName, true)).willReturn(psiMethod); - BuilderPsiClassBuilder builder = psiClassBuilder.aBuilder(context); - setField(builder, "butMethodCreator", butMethodCreator); - - // when - BuilderPsiClassBuilder result = builder.withButMethod(); - - // then - assertThat(result).isSameAs(psiClassBuilder); - verify(builderClass).add(psiMethod); - } - - @Test - void shouldReturnBuilderObjectWithBuildMethodUsingSetterAndConstructor() { - // given - PsiField psiFieldForSetter = mock(PsiField.class); - psiFieldsForSetters.add(psiFieldForSetter); - - PsiField psiFieldForConstructor = mock(PsiField.class); - psiFieldsForConstructor.add(psiFieldForConstructor); - given(psiFieldForConstructor.getName()).willReturn("age"); - - given(psiFieldForSetter.getName()).willReturn("name"); - PsiMethod method = mock(PsiMethod.class); - given(elementFactory.createMethodFromText("public " + srcClassName + " build() { " + srcClassName + " " + srcClassFieldName + " = new " + srcClassName + "(age);" - + srcClassFieldName + ".setName(name);return " + srcClassFieldName + "; }", srcClass)).willReturn(method); - - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - PsiParameter psiParameter = mock(PsiParameter.class); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{psiParameter}); - given(psiFieldVerifier.areNameAndTypeEqual(psiFieldForConstructor, psiParameter)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.aBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(builderClass).add(method); - } - - @Test - void shouldReturnBuilderObjectWithBuildMethodUsingSetterAndConstructorWhenUsingSingleField() { - // given - context = createBuilderContext(true); - PsiField psiFieldForSetter = mock(PsiField.class, withSettings().strictness(Strictness.LENIENT)); - psiFieldsForSetters.add(psiFieldForSetter); - - PsiField psiFieldForConstructor = mock(PsiField.class, withSettings().strictness(Strictness.LENIENT)); - psiFieldsForConstructor.add(psiFieldForConstructor); - given(psiFieldForConstructor.getName()).willReturn("age"); - - given(psiFieldForSetter.getName()).willReturn("name"); - PsiMethod method = mock(PsiMethod.class); - given(elementFactory.createMethodFromText("public " + srcClassName + " build() { return " + srcClassFieldName + "; }", srcClass)).willReturn(method); - - // when - PsiClass result = psiClassBuilder.aBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(builderClass).add(method); - } - - @Test - void constructorShouldHavePriorityOverSetter() { - // given - PsiField nameField = mock(PsiField.class); - PsiField ageField = mock(PsiField.class); - given(nameField.getName()).willReturn("name"); - given(ageField.getName()).willReturn("age"); - - psiFieldsForConstructor.add(nameField); - psiFieldsForSetters.add(ageField); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + srcClassName + " " + srcClassFieldName + " = new " + srcClassName + "(name);" - + srcClassFieldName + ".setAge(age);return " + srcClassFieldName + "; }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - PsiParameter nameParameter = mock(PsiParameter.class); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{nameParameter}); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, nameParameter)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - @Test - void setterShouldHavePriorityOverField() { - // given - PsiField nameField = mock(PsiField.class); - PsiField ageField = mock(PsiField.class); - given(nameField.getName()).willReturn("name"); - given(ageField.getName()).willReturn("age"); - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - given(psiParameterList.getParameters()).willReturn(EMPTY_PSI_PARAMETERS); - - psiFieldsForSetters.add(nameField); - allSelectedPsiFields.add(nameField); - allSelectedPsiFields.add(ageField); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + srcClassName + " " + srcClassFieldName + " = new " + srcClassName + "();" - + srcClassFieldName + ".setName(name);" - + srcClassFieldName + ".age=this.age;return " + srcClassFieldName + "; }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - @Test - void shouldHavePriorityOverSetter() { - // given - PsiField nameField = mock(PsiField.class); - PsiField ageField = mock(PsiField.class); - given(nameField.getName()).willReturn("name"); - given(ageField.getName()).willReturn("age"); - - psiFieldsForConstructor.add(nameField); - psiFieldsForSetters.add(ageField); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + srcClassName + " " + srcClassFieldName + " = new " + srcClassName + "(name);" - + srcClassFieldName + ".setAge(age);return " + srcClassFieldName + "; }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - PsiParameter nameParameter = mock(PsiParameter.class); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{nameParameter}); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, nameParameter)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - @Test - void shouldOutputInlineConstructor() { - // given - PsiField nameField = mock(PsiField.class); - PsiField ageField = mock(PsiField.class); - given(nameField.getName()).willReturn("name"); - given(ageField.getName()).willReturn("age"); - allSelectedPsiFields.add(nameField); - allSelectedPsiFields.add(ageField); - psiFieldsForConstructor.add(nameField); - psiFieldsForConstructor.add(ageField); - - PsiParameter nameParameter = mock(PsiParameter.class); - PsiParameter ageParameter = mock(PsiParameter.class); - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{nameParameter, ageParameter}); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, nameParameter)).willReturn(true); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, ageParameter)).willReturn(false); - given(psiFieldVerifier.areNameAndTypeEqual(ageField, nameParameter)).willReturn(false); - given(psiFieldVerifier.areNameAndTypeEqual(ageField, ageParameter)).willReturn(true); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + "return new " + srcClassName + "(name,age); }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - @Test - void shouldSortConstructorParameters() { - // given - PsiField nameField = mock(PsiField.class); - PsiField ageField = mock(PsiField.class); - given(nameField.getName()).willReturn("name"); - given(ageField.getName()).willReturn("age"); - psiFieldsForConstructor.add(nameField); - psiFieldsForConstructor.add(ageField); - - PsiParameter nameParameter = mock(PsiParameter.class); - PsiParameter ageParameter = mock(PsiParameter.class); - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{ageParameter, nameParameter}); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, nameParameter)).willReturn(true); - given(psiFieldVerifier.areNameAndTypeEqual(nameField, ageParameter)).willReturn(false); - given(psiFieldVerifier.areNameAndTypeEqual(ageField, nameParameter)).willReturn(false); - given(psiFieldVerifier.areNameAndTypeEqual(ageField, ageParameter)).willReturn(true); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + srcClassName + " " + srcClassFieldName + " = new " + srcClassName + "(age,name);return className; }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - @Test - void shouldAddDefaultValueWhenNeeded() { - // given - PsiParameterList psiParameterList = mock(PsiParameterList.class); - given(bestConstructor.getParameterList()).willReturn(psiParameterList); - PsiParameter booleanParameter = createPsiParameter(PsiType.BOOLEAN); - PsiParameter byteParameter = createPsiParameter(PsiType.BYTE); - PsiParameter shortParameter = createPsiParameter(PsiType.SHORT); - PsiParameter intParameter = createPsiParameter(PsiType.INT); - PsiParameter longParameter = createPsiParameter(PsiType.LONG); - PsiParameter floatParameter = createPsiParameter(PsiType.FLOAT); - PsiParameter doubleParameter = createPsiParameter(PsiType.DOUBLE); - PsiParameter charParameter = createPsiParameter(PsiType.CHAR); - PsiParameter otherParameter = createPsiParameter(PsiType.VOID); - given(psiParameterList.getParameters()).willReturn(new PsiParameter[]{ - booleanParameter, byteParameter, shortParameter, intParameter, longParameter, - floatParameter, doubleParameter, charParameter, otherParameter - }); - - PsiMethod method = mock(PsiMethod.class); - String expectedCode = "public " + srcClassName + " build() { " - + "return new " + srcClassName + "(false,0,0,0,0L,0.0f,0.0d,'\\u0000',null); }"; - given(elementFactory.createMethodFromText(expectedCode, srcClass)).willReturn(method); - - given(builderClass.hasModifierProperty(PsiModifier.STATIC)).willReturn(true); - - // when - PsiClass result = psiClassBuilder.anInnerBuilder(context).build(); - - // then - assertThat(result).isNotNull(); - verify(elementFactory).createMethodFromText(stringCaptor.capture(), eq(srcClass)); - assertThat(stringCaptor.getValue()).isEqualTo(expectedCode); - verify(builderClass).add(method); - } - - private PsiParameter createPsiParameter(PsiType parameterType) { - PsiParameter psiParameter = mock(PsiParameter.class); - given(psiParameter.getType()).willReturn(parameterType); - return psiParameter; - } - - private void assertFieldsAreSet(BuilderPsiClassBuilder result) { - assertThat(result).isSameAs(psiClassBuilder); - assertThat(getField(psiClassBuilder, "elementFactory")).isEqualTo(elementFactory); - assertThat(getField(psiClassBuilder, "srcClass")).isEqualTo(srcClass); - assertThat(getField(psiClassBuilder, "builderClassName")).isEqualTo(builderClassName); - assertThat(getField(psiClassBuilder, "srcClassName")).isEqualTo(srcClassName); - assertThat(getField(psiClassBuilder, "srcClassFieldName")).isEqualTo(srcClassFieldName); - assertThat(getField(psiClassBuilder, "psiFieldsForSetters")).isEqualTo(psiFieldsForSetters); - assertThat(getField(psiClassBuilder, "psiFieldsForConstructor")).isEqualTo(psiFieldsForConstructor); - assertThat(getField(psiClassBuilder, "allSelectedPsiFields")).isEqualTo(allSelectedPsiFields); - assertThat(getField(psiClassBuilder, "bestConstructor")).isEqualTo(bestConstructor); - assertThat(getField(psiClassBuilder, "builderClass")).isEqualTo(builderClass); - } -} diff --git a/src/test/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterComputableTest.java b/src/test/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterComputableTest.java index 38db6da..21823ec 100644 --- a/src/test/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterComputableTest.java +++ b/src/test/java/pl/mjedynak/idea/plugins/builder/writer/BuilderWriterComputableTest.java @@ -100,7 +100,7 @@ void shouldInvokeBuilderWriterErrorRunnableWhenExceptionOccurs() { private void mockBuilder() { given(builderPsiClassBuilder.withFields()).willReturn(builderPsiClassBuilder); - given(builderPsiClassBuilder.withPrivateConstructor()).willReturn(builderPsiClassBuilder); + given(builderPsiClassBuilder.withConstructor()).willReturn(builderPsiClassBuilder); given(builderPsiClassBuilder.withInitializingMethod()).willReturn(builderPsiClassBuilder); given(builderPsiClassBuilder.withSetMethods(METHOD_PREFIX)).willReturn(builderPsiClassBuilder); given(builderPsiClassBuilder.build()).willReturn(builderClass);