mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
'generate test' improvements for Groovy
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.ide.util.TreeClassChooser;
|
||||
import com.intellij.ide.util.TreeClassChooserFactory;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -56,6 +58,7 @@ import com.intellij.testIntegration.TestIntegrationUtils;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -70,7 +73,6 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
private static final String RECENTS_KEY = "CreateTestDialog.RecentsKey";
|
||||
private static final String DEFAULT_LIBRARY_NAME_PROPERTY = CreateTestDialog.class.getName() + ".defaultLibrary";
|
||||
private static final String SHOW_INHERITED_MEMBERS_PROPERTY = CreateTestDialog.class.getName() + ".includeInheritedMembers";
|
||||
private static final String DEFAULT_LANGUAGE = CreateTestDialog.class.getName() + ".defaultLanguage";
|
||||
|
||||
private final Project myProject;
|
||||
private final PsiClass myTargetClass;
|
||||
@@ -171,20 +173,18 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
|
||||
TestGenerator[] generators = TestGenerator.EP_NAME.getExtensions();
|
||||
myLanguageCombo = new ComboBox(generators, -1);
|
||||
final String defaultLanguage = getDefaultLanguage();
|
||||
if (defaultLanguage != null) {
|
||||
for (TestGenerator generator : generators) {
|
||||
if (defaultLanguage.equals(generator.toString())) {
|
||||
myLanguageCombo.setSelectedItem(generator);
|
||||
break;
|
||||
}
|
||||
final Language curLang = myTargetClass.getLanguage();
|
||||
for (TestGenerator generator : generators) {
|
||||
if (curLang == generator.getLanguage()) {
|
||||
myLanguageCombo.setSelectedItem(generator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
myTargetClassNameField = new EditorTextField(targetClass.getName() + "Test");
|
||||
myTargetClassNameField.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) {
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
getOKAction().setEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getClassName()));
|
||||
}
|
||||
});
|
||||
@@ -249,14 +249,6 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
getProperties().setValue(DEFAULT_LIBRARY_NAME_PROPERTY, mySelectedFramework.getName());
|
||||
}
|
||||
|
||||
private String getDefaultLanguage() {
|
||||
return getProperties().getValue(DEFAULT_LANGUAGE);
|
||||
}
|
||||
|
||||
private void saveDefaultLanguage() {
|
||||
getProperties().setValue(DEFAULT_LANGUAGE, myLanguageCombo.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
private void restoreShowInheritedMembersStatus() {
|
||||
String v = getProperties().getValue(SHOW_INHERITED_MEMBERS_PROPERTY);
|
||||
myShowInheritedMethodsBox.setSelected(v != null && v.equals("true"));
|
||||
@@ -416,6 +408,7 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
return myTargetClassNameField.getText();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getSuperClassName() {
|
||||
String result = mySuperClassField.getText().trim();
|
||||
if (result.length() == 0) return null;
|
||||
@@ -461,10 +454,10 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
|
||||
saveDefaultLibraryName();
|
||||
saveShowInheritedMembersStatus();
|
||||
saveDefaultLanguage();
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDirectory selectTargetDirectory() throws IncorrectOperationException {
|
||||
final String packageName = getPackageName();
|
||||
final PackageWrapper targetPackage = new PackageWrapper(PsiManager.getInstance(myProject), packageName);
|
||||
@@ -493,6 +486,7 @@ public class CreateTestDialog extends DialogWrapper {
|
||||
}.execute().getResultObject();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDirectory chooseDefaultDirectory(String packageName) {
|
||||
for (ContentEntry e : ModuleRootManager.getInstance(myTargetModule).getContentEntries()) {
|
||||
for (SourceFolder f : e.getSourceFolders()) {
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.intellij.testIntegration.createTest;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
@@ -34,7 +36,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class JavaTestGenerator implements TestGenerator{
|
||||
public class JavaTestGenerator implements TestGenerator {
|
||||
public JavaTestGenerator() {
|
||||
}
|
||||
|
||||
@@ -91,11 +93,11 @@ public class JavaTestGenerator implements TestGenerator{
|
||||
}
|
||||
|
||||
private static void addTestMethods(Editor editor,
|
||||
PsiClass targetClass,
|
||||
TestFramework descriptor,
|
||||
Collection<MemberInfo> methods,
|
||||
boolean generateBefore,
|
||||
boolean generateAfter) throws IncorrectOperationException {
|
||||
PsiClass targetClass,
|
||||
TestFramework descriptor,
|
||||
Collection<MemberInfo> methods,
|
||||
boolean generateBefore,
|
||||
boolean generateAfter) throws IncorrectOperationException {
|
||||
if (generateBefore) {
|
||||
generateMethod(TestIntegrationUtils.MethodKind.SET_UP, descriptor, targetClass, editor, null);
|
||||
}
|
||||
@@ -117,7 +119,11 @@ public class JavaTestGenerator implements TestGenerator{
|
||||
});
|
||||
}
|
||||
|
||||
private static void generateMethod(TestIntegrationUtils.MethodKind methodKind, TestFramework descriptor, PsiClass targetClass, Editor editor, String name) {
|
||||
private static void generateMethod(TestIntegrationUtils.MethodKind methodKind,
|
||||
TestFramework descriptor,
|
||||
PsiClass targetClass,
|
||||
Editor editor,
|
||||
@Nullable String name) {
|
||||
PsiMethod method = (PsiMethod)targetClass.add(TestIntegrationUtils.createDummyMethod(targetClass.getProject()));
|
||||
PsiDocumentManager.getInstance(targetClass.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true);
|
||||
@@ -127,4 +133,9 @@ public class JavaTestGenerator implements TestGenerator{
|
||||
public String toString() {
|
||||
return CodeInsightBundle.message("intention.create.test.dialog.java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return JavaLanguage.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.testIntegration.createTest;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -37,4 +38,6 @@ public interface TestGenerator {
|
||||
* should return text to show in dialog
|
||||
*/
|
||||
String toString();
|
||||
|
||||
Language getLanguage();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
void setUp() {
|
||||
${BODY}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<html>
|
||||
<body>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">
|
||||
This is a template used by <b>IDEA</b> to create a setUp method in a Groovy JUnit test class.
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">Predefined variables will take the following values:</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${NAME}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">name of the created method.</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${BODY}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">generated method body.</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
void tearDown() {
|
||||
${BODY}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<html>
|
||||
<body>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">
|
||||
This is a template used by <b>IDEA</b> to create a tearDown method in a Groovy JUnit test class.
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">Predefined variables will take the following values:</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${NAME}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">name of the created method.</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${BODY}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">generated method body.</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
void test${NAME}() {
|
||||
${BODY}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<html>
|
||||
<body>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">
|
||||
This is a template used by <b>IDEA</b> to create a test method in a JUnit 3 test class.
|
||||
</font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td colspan="3"><font face="verdana" size="-1">Predefined variables will take the following values:</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${NAME}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">name of the created method.</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${BODY}</i></b></font></nobr></td>
|
||||
<td width="10"> </td>
|
||||
<td valign="top"><font face="verdana" size="-1">generated method body.</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -121,6 +121,7 @@
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<testFramework implementation="org.jetbrains.plugins.groovy.testIntegration.GroovyTestFramework"/>
|
||||
<testCreator language="Groovy" implementationClass="com.intellij.testIntegration.JavaTestCreator"/>
|
||||
<testGenerator implementation="org.jetbrains.plugins.groovy.testIntegration.GroovyTestGenerator"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.plugins.groovy.annotator.ConfigureGroovyLibraryNotificationProvider"/>
|
||||
|
||||
+44
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,14 +17,15 @@
|
||||
package org.jetbrains.plugins.groovy.annotator.intentions;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -75,47 +76,49 @@ public abstract class CreateClassActionBase implements IntentionAction {
|
||||
public static PsiClass createClassByType(final PsiDirectory directory,
|
||||
final String name,
|
||||
final PsiManager manager,
|
||||
final PsiElement contextElement, final String templateName) {
|
||||
return ApplicationManager.getApplication().runWriteAction(
|
||||
new Computable<PsiClass>() {
|
||||
public PsiClass compute() {
|
||||
try {
|
||||
PsiClass targetClass = null;
|
||||
try {
|
||||
PsiFile file = GroovyTemplatesFactory.createFromTemplate(directory, name, name + ".groovy", templateName);
|
||||
for (PsiElement element : file.getChildren()) {
|
||||
if (element instanceof PsiClass) {
|
||||
targetClass = ((PsiClass) element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetClass == null) {
|
||||
throw new IncorrectOperationException(GroovyBundle.message("no.class.in.file.template"));
|
||||
}
|
||||
}
|
||||
catch (final IncorrectOperationException e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(
|
||||
GroovyBundle.message("cannot.create.class.error.text", name, e.getLocalizedMessage()),
|
||||
GroovyBundle.message("cannot.create.class.error.title"));
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
PsiModifierList modifiers = targetClass.getModifierList();
|
||||
if (!JavaPsiFacade.getInstance(manager.getProject()).getResolveHelper().isAccessible(targetClass, contextElement, null) &&
|
||||
modifiers != null) {
|
||||
modifiers.setModifierProperty(PsiKeyword.PUBLIC, true);
|
||||
}
|
||||
return targetClass;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
@Nullable final PsiElement contextElement,
|
||||
final String templateName) {
|
||||
AccessToken accessToken = WriteAction.start();
|
||||
|
||||
try {
|
||||
PsiClass targetClass = null;
|
||||
try {
|
||||
PsiFile file = GroovyTemplatesFactory.createFromTemplate(directory, name, name + ".groovy", templateName);
|
||||
for (PsiElement element : file.getChildren()) {
|
||||
if (element instanceof PsiClass) {
|
||||
targetClass = ((PsiClass)element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetClass == null) {
|
||||
throw new IncorrectOperationException(GroovyBundle.message("no.class.in.file.template"));
|
||||
}
|
||||
}
|
||||
catch (final IncorrectOperationException e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(
|
||||
GroovyBundle.message("cannot.create.class.error.text", name, e.getLocalizedMessage()),
|
||||
GroovyBundle.message("cannot.create.class.error.title"));
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
PsiModifierList modifiers = targetClass.getModifierList();
|
||||
if (contextElement != null &&
|
||||
!JavaPsiFacade.getInstance(manager.getProject()).getResolveHelper().isAccessible(targetClass, contextElement, null) &&
|
||||
modifiers != null) {
|
||||
modifiers.setModifierProperty(PsiKeyword.PUBLIC, true);
|
||||
}
|
||||
return targetClass;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -59,6 +59,10 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory {
|
||||
|
||||
@NonNls public static final String DUMMY_FILE_NAME = "DUMMY__";
|
||||
|
||||
public abstract GrCodeReferenceElement createCodeReferenceElementFromClass(PsiClass aClass);
|
||||
|
||||
public abstract GrCodeReferenceElement createCodeReferenceElementFromText(String text);
|
||||
|
||||
public static GroovyPsiElementFactory getInstance(Project project) {
|
||||
return ServiceManager.getService(project, GroovyPsiElementFactory.class);
|
||||
}
|
||||
|
||||
+23
-1
@@ -465,7 +465,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
return createAnnotationFromText(annoText, null);
|
||||
}
|
||||
|
||||
public PsiFile createGroovyFile(String idText) {
|
||||
public GroovyFile createGroovyFile(String idText) {
|
||||
return createGroovyFile(idText, false, null);
|
||||
}
|
||||
|
||||
@@ -553,6 +553,28 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
return ((GrMethodCallExpression)file.getChildren()[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrCodeReferenceElement createCodeReferenceElementFromClass(PsiClass aClass) {
|
||||
if (aClass instanceof PsiAnonymousClass) {
|
||||
throw new IncorrectOperationException("cannot create code reference element for anonymous class " + aClass.getText());
|
||||
}
|
||||
|
||||
return createCodeReferenceElementFromText(aClass.getQualifiedName());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrCodeReferenceElement createCodeReferenceElementFromText(String text) {
|
||||
GroovyFile file = createGroovyFile("class X extends " + text + "{}");
|
||||
PsiClass[] classes = file.getClasses();
|
||||
if (classes.length != 1) throw new IncorrectOperationException("cannot create code reference element for class" + text);
|
||||
GrExtendsClause extendsClause = ((GrTypeDefinition)classes[0]).getExtendsClause();
|
||||
if (extendsClause == null) throw new IncorrectOperationException("cannot create code reference element for class" + text);
|
||||
GrCodeReferenceElement[] refElements = extendsClause.getReferenceElements();
|
||||
if (refElements.length != 1) throw new IncorrectOperationException("cannot create code reference element for class" + text);
|
||||
return refElements[0];
|
||||
}
|
||||
|
||||
public GrImportStatement createImportStatementFromText(String qName, boolean isStatic, boolean isOnDemand, String alias) {
|
||||
final String text = "import " + (isStatic ? "static " : "") + qName + (isOnDemand ? ".*" : "") +
|
||||
(alias != null && alias.length() > 0 ? " as " + alias : "");
|
||||
|
||||
+1
@@ -48,6 +48,7 @@ public final class GroovyCommonClassNames {
|
||||
@NonNls public static final String GROOVY_LANG_CATEGORY = "groovy.lang.Category";
|
||||
@NonNls public static final String GROOVY_LANG_USE = "groovy.lang.Use";
|
||||
@NonNls public static final String GROOVY_LANG_MIXIN = "groovy.lang.Mixin";
|
||||
@NonNls public static final String GROOVY_UTIL_TEST_CASE = "groovy.util.GroovyTestCase";
|
||||
|
||||
|
||||
private GroovyCommonClassNames() {
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.testIntegration;
|
||||
|
||||
import com.intellij.execution.junit.JUnitUtil;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.testIntegration.JavaTestFramework;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GroovyTestFramework extends JavaTestFramework {
|
||||
private static final Logger LOG = Logger.getInstance(GroovyTestFramework.class);
|
||||
|
||||
@Override
|
||||
protected String getMarkerClassFQName() {
|
||||
return GroovyCommonClassNames.GROOVY_UTIL_TEST_CASE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isTestClass(PsiClass clazz, boolean canBePotential) {
|
||||
return clazz.getLanguage() == GroovyFileType.GROOVY_LANGUAGE &&
|
||||
JUnitUtil.isTestClass(clazz) &&
|
||||
InheritanceUtil.isInheritor(clazz, GroovyCommonClassNames.GROOVY_UTIL_TEST_CASE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) {
|
||||
for (PsiMethod method : clazz.getMethods()) {
|
||||
if (method.getName().equals("setUp")) return method;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) {
|
||||
for (PsiMethod method : clazz.getMethods()) {
|
||||
if (method.getName().equals("tearDown")) return method;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiMethod findOrCreateSetUpMethod(PsiClass clazz) throws IncorrectOperationException {
|
||||
LOG.assertTrue(clazz.getLanguage() == GroovyFileType.GROOVY_LANGUAGE);
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(clazz.getProject());
|
||||
|
||||
final PsiMethod patternMethod = factory.createMethodFromText("protected void setUp() {\nsuper.setUp()\n}", null);
|
||||
|
||||
final PsiClass baseClass = clazz.getSuperClass();
|
||||
if (baseClass != null) {
|
||||
final PsiMethod baseMethod = baseClass.findMethodBySignature(patternMethod, false);
|
||||
if (baseMethod != null && baseMethod.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
PsiUtil.setModifierProperty(patternMethod, PsiModifier.PROTECTED, false);
|
||||
PsiUtil.setModifierProperty(patternMethod, PsiModifier.PUBLIC, true);
|
||||
}
|
||||
}
|
||||
|
||||
PsiMethod inClass = clazz.findMethodBySignature(patternMethod, false);
|
||||
if (inClass == null) {
|
||||
PsiMethod testMethod = JUnitUtil.findFirstTestMethod(clazz);
|
||||
if (testMethod != null) {
|
||||
return (PsiMethod)clazz.addBefore(patternMethod, testMethod);
|
||||
}
|
||||
return (PsiMethod)clazz.add(patternMethod);
|
||||
}
|
||||
else if (inClass.getBody() == null) {
|
||||
return (PsiMethod)inClass.replace(patternMethod);
|
||||
}
|
||||
return inClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Groovy JUnit";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return GroovyIcons.GROOVY_ICON_16x16;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLibraryPath() {
|
||||
return JavaSdkUtil.getJunit3JarPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultSuperClass() {
|
||||
return GroovyCommonClassNames.GROOVY_UTIL_TEST_CASE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
|
||||
return new FileTemplateDescriptor("Groovy JUnit SetUp Method.groovy");
|
||||
}
|
||||
|
||||
public FileTemplateDescriptor getTearDownMethodFileTemplateDescriptor() {
|
||||
return new FileTemplateDescriptor("Groovy JUnit TearDown Method.groovy");
|
||||
}
|
||||
|
||||
public FileTemplateDescriptor getTestMethodFileTemplateDescriptor() {
|
||||
return new FileTemplateDescriptor("Groovy JUnit Test Method.groovy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTestMethod(PsiElement element) {
|
||||
return element instanceof PsiMethod && JUnitUtil.getTestMethod(element) != null;
|
||||
}
|
||||
}
|
||||
+121
-30
@@ -16,25 +16,38 @@
|
||||
package org.jetbrains.plugins.groovy.testIntegration;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.testIntegration.TestFramework;
|
||||
import com.intellij.testIntegration.TestIntegrationUtils;
|
||||
import com.intellij.testIntegration.createTest.CreateTestDialog;
|
||||
import com.intellij.testIntegration.createTest.JavaTestGenerator;
|
||||
import com.intellij.testIntegration.createTest.TestGenerator;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportPass;
|
||||
import org.jetbrains.plugins.groovy.actions.NewGroovyClassAction;
|
||||
import org.jetbrains.plugins.groovy.annotator.intentions.CreateClassActionBase;
|
||||
import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
@@ -44,35 +57,42 @@ public class GroovyTestGenerator implements TestGenerator {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement generateTest(final Project project, final CreateTestDialog d) {
|
||||
final PsiClass test = (PsiClass)new JavaTestGenerator().generateTest(project, d);
|
||||
if (test == null) return null;
|
||||
|
||||
AccessToken accessToken = WriteAction.start();
|
||||
|
||||
try {
|
||||
final PsiFile file = test.getContainingFile();
|
||||
final String name = file.getName();
|
||||
final String newName = FileUtil.getNameWithoutExtension(name) + "." + GroovyFileType.DEFAULT_EXTENSION;
|
||||
final PsiClass test = (PsiClass)PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(
|
||||
new Computable<PsiElement>() {
|
||||
public PsiElement compute() {
|
||||
try {
|
||||
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
|
||||
|
||||
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
|
||||
try {
|
||||
final PsiElement element = file.setName(newName);
|
||||
GrTypeDefinition targetClass = (GrTypeDefinition)CreateClassActionBase.createClassByType(
|
||||
d.getTargetDirectory(),
|
||||
d.getClassName(),
|
||||
PsiManager.getInstance(project),
|
||||
null,
|
||||
NewGroovyClassAction.GROOVY_CLASS);
|
||||
|
||||
final GroovyFile newFile = (GroovyFile)codeStyleManager.reformat(element);
|
||||
GroovyUnusedImportPass.optimizeImports(project, newFile);
|
||||
return newFile.getClasses()[0];
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
file.delete();
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(project,
|
||||
CodeInsightBundle.message("intention.error.cannot.create.class.message", d.getClassName()),
|
||||
CodeInsightBundle.message("intention.error.cannot.create.class.title"));
|
||||
addSuperClass(targetClass, project, d.getSuperClassName());
|
||||
|
||||
Editor editor = CodeInsightUtil.positionCursor(project, targetClass.getContainingFile(), targetClass.getLBrace());
|
||||
addTestMethods(editor,
|
||||
targetClass,
|
||||
d.getSelectedTestFrameworkDescriptor(),
|
||||
d.getSelectedMethods(),
|
||||
d.shouldGeneratedBefore(),
|
||||
d.shouldGeneratedAfter());
|
||||
return targetClass;
|
||||
}
|
||||
catch (IncorrectOperationException e1) {
|
||||
showErrorLater(project, d.getClassName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
if (test == null) return null;
|
||||
GrReferenceAdjuster.shortenReferences(test);
|
||||
CodeStyleManager.getInstance(project).reformat(test);
|
||||
return test;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
@@ -83,4 +103,75 @@ public class GroovyTestGenerator implements TestGenerator {
|
||||
public String toString() {
|
||||
return GroovyIntentionsBundle.message("intention.crete.test.groovy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return GroovyFileType.GROOVY_LANGUAGE;
|
||||
}
|
||||
|
||||
private static void addSuperClass(GrTypeDefinition targetClass, Project project, @Nullable String superClassName)
|
||||
throws IncorrectOperationException {
|
||||
if (superClassName == null) return;
|
||||
|
||||
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
|
||||
|
||||
PsiClass superClass = findClass(project, superClassName);
|
||||
GrCodeReferenceElement superClassRef;
|
||||
if (superClass != null) {
|
||||
superClassRef = factory.createCodeReferenceElementFromClass(superClass);
|
||||
}
|
||||
else {
|
||||
superClassRef = factory.createCodeReferenceElementFromText(superClassName);
|
||||
}
|
||||
GrExtendsClause extendsClause = targetClass.getExtendsClause();
|
||||
if (extendsClause == null) {
|
||||
extendsClause = (GrExtendsClause)targetClass.addAfter(factory.createExtendsClause(), targetClass.getNameIdentifierGroovy());
|
||||
}
|
||||
|
||||
extendsClause.add(superClassRef);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass findClass(Project project, String fqName) {
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
return JavaPsiFacade.getInstance(project).findClass(fqName, scope);
|
||||
}
|
||||
|
||||
private static void addTestMethods(Editor editor,
|
||||
PsiClass targetClass,
|
||||
TestFramework descriptor,
|
||||
Collection<MemberInfo> methods,
|
||||
boolean generateBefore,
|
||||
boolean generateAfter) throws IncorrectOperationException {
|
||||
if (generateBefore) {
|
||||
generateMethod(TestIntegrationUtils.MethodKind.SET_UP, descriptor, targetClass, editor, null);
|
||||
}
|
||||
if (generateAfter) {
|
||||
generateMethod(TestIntegrationUtils.MethodKind.TEAR_DOWN, descriptor, targetClass, editor, null);
|
||||
}
|
||||
for (MemberInfo m : methods) {
|
||||
generateMethod(TestIntegrationUtils.MethodKind.TEST, descriptor, targetClass, editor, m.getMember().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void showErrorLater(final Project project, final String targetClassName) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(project,
|
||||
CodeInsightBundle.message("intention.error.cannot.create.class.message", targetClassName),
|
||||
CodeInsightBundle.message("intention.error.cannot.create.class.title"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void generateMethod(TestIntegrationUtils.MethodKind methodKind,
|
||||
TestFramework descriptor,
|
||||
PsiClass targetClass,
|
||||
Editor editor,
|
||||
@Nullable String name) {
|
||||
GroovyPsiElementFactory f = GroovyPsiElementFactory.getInstance(targetClass.getProject());
|
||||
PsiMethod method = (PsiMethod)targetClass.add(f.createMethod("dummy", PsiType.VOID));
|
||||
PsiDocumentManager.getInstance(targetClass.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user