enhanced API for nullness
[fedora-idea.git] / java / java-impl / src / com / intellij / testIntegration / TestIntegrationUtils.java
blobab864f3aeece53a4071fa5ad31a6b015e055d047
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.testIntegration;
18 import com.intellij.codeInsight.TestUtil;
19 import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
20 import com.intellij.codeInsight.template.Expression;
21 import com.intellij.codeInsight.template.Template;
22 import com.intellij.codeInsight.template.TemplateEditingAdapter;
23 import com.intellij.codeInsight.template.TemplateManager;
24 import com.intellij.codeInsight.template.impl.ConstantNode;
25 import com.intellij.ide.fileTemplates.FileTemplate;
26 import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
27 import com.intellij.ide.fileTemplates.FileTemplateManager;
28 import com.intellij.openapi.application.ApplicationManager;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.editor.Editor;
31 import com.intellij.openapi.project.Project;
32 import com.intellij.openapi.util.TextRange;
33 import com.intellij.openapi.util.text.StringUtil;
34 import com.intellij.psi.*;
35 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
36 import com.intellij.psi.util.PsiTreeUtil;
37 import com.intellij.refactoring.util.classMembers.MemberInfo;
38 import com.intellij.util.IncorrectOperationException;
40 import java.io.IOException;
41 import java.util.ArrayList;
42 import java.util.List;
43 import java.util.Properties;
45 public class TestIntegrationUtils {
46 private static final Logger LOG = Logger.getInstance("#" + TestIntegrationUtils.class.getName());
48 public enum MethodKind {
49 SET_UP {
50 public FileTemplateDescriptor getFileTemplateDescriptor(TestFrameworkDescriptor frameworkDescriptor) {
51 return frameworkDescriptor.getSetUpMethodFileTemplateDescriptor();
52 }},
53 TEAR_DOWN {
54 public FileTemplateDescriptor getFileTemplateDescriptor(TestFrameworkDescriptor frameworkDescriptor) {
55 return frameworkDescriptor.getTearDownMethodFileTemplateDescriptor();
56 }},
57 TEST {
58 public FileTemplateDescriptor getFileTemplateDescriptor(TestFrameworkDescriptor frameworkDescriptor) {
59 return frameworkDescriptor.getTestMethodFileTemplateDescriptor();
60 }};
62 public abstract FileTemplateDescriptor getFileTemplateDescriptor(TestFrameworkDescriptor frameworkDescriptor);
65 public static boolean isTest(PsiElement element) {
66 PsiClass klass = findOuterClass(element);
67 return klass != null && TestUtil.isTestClass(klass);
70 public static PsiClass findOuterClass(PsiElement element) {
71 PsiClass result = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
72 if (result == null) return null;
74 do {
75 PsiClass nextParent = PsiTreeUtil.getParentOfType(result, PsiClass.class, true);
76 if (nextParent == null) return result;
77 result = nextParent;
79 while (true);
82 public static List<MemberInfo> extractClassMethods(PsiClass clazz, boolean includeInherited) {
83 List<MemberInfo> result = new ArrayList<MemberInfo>();
85 do {
86 MemberInfo.extractClassMembers(clazz, result, new MemberInfo.Filter<PsiMember>() {
87 public boolean includeMember(PsiMember member) {
88 if (!(member instanceof PsiMethod)) return false;
89 PsiModifierList list = member.getModifierList();
90 return list.hasModifierProperty(PsiModifier.PUBLIC);
92 }, false);
93 clazz = clazz.getSuperClass();
95 while (clazz != null
96 && clazz.getSuperClass() != null // not the Object
97 && includeInherited);
99 return result;
102 public static PsiMethod createMethod(PsiClass targetClass, String name, String annotation) throws IncorrectOperationException {
103 PsiElementFactory f = JavaPsiFacade.getInstance(targetClass.getProject()).getElementFactory();
104 PsiMethod result = f.createMethod(name, PsiType.VOID);
105 result.getBody().add(f.createCommentFromText("// Add your code here", result));
107 if (annotation != null) {
108 PsiAnnotation a = f.createAnnotationFromText("@" + annotation, result);
109 PsiModifierList modifiers = result.getModifierList();
110 PsiElement first = modifiers.getFirstChild();
111 if (first == null) {
112 modifiers.add(a);
114 else {
115 modifiers.addBefore(a, first);
118 JavaCodeStyleManager.getInstance(targetClass.getProject()).shortenClassReferences(modifiers);
121 return result;
124 public static void runTestMethodTemplate(MethodKind methodKind,
125 TestFrameworkDescriptor descriptor,
126 final Editor editor,
127 PsiClass targetClass,
128 final PsiMethod method,
129 String name,
130 boolean automatic) {
131 Template template = createTestMethodTemplate(methodKind, descriptor, targetClass, name, automatic);
133 final TextRange range = method.getTextRange();
134 editor.getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), "");
135 editor.getCaretModel().moveToOffset(range.getStartOffset());
137 final Project project = targetClass.getProject();
139 TemplateEditingAdapter adapter = null;
141 if (!automatic) {
142 adapter = new TemplateEditingAdapter() {
143 @Override
144 public void templateFinished(Template template) {
145 ApplicationManager.getApplication().runWriteAction(new Runnable() {
146 public void run() {
147 PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
148 PsiFile psi = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
149 PsiElement method = psi.findElementAt(range.getStartOffset());
151 if (method != null) {
152 method = PsiTreeUtil.getParentOfType(method, PsiMethod.class, false);
153 if (method != null) {
154 CreateFromUsageUtils.setupEditor((PsiMethod)method, editor);
163 TemplateManager.getInstance(project).startTemplate(editor, template, adapter);
164 PsiDocumentManager.getInstance(targetClass.getProject()).commitDocument(editor.getDocument());
167 private static Template createTestMethodTemplate(MethodKind methodKind,
168 TestFrameworkDescriptor descriptor,
169 PsiClass targetClass,
170 String name,
171 boolean automatic) {
172 FileTemplateDescriptor templateDesc = methodKind.getFileTemplateDescriptor(descriptor);
173 String templateName = templateDesc.getFileName();
174 FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(templateName);
175 Template template = TemplateManager.getInstance(targetClass.getProject()).createTemplate("", "");
177 String templateText;
178 try {
179 templateText = fileTemplate.getText(new Properties());
181 catch (IOException e) {
182 LOG.warn(e);
183 templateText = fileTemplate.getText();
186 int from = 0;
187 while(true) {
188 int index = templateText.indexOf("${NAME}", from);
189 if (index == -1) break;
191 template.addTextSegment(templateText.substring(from, index));
193 if (index > 0 && !Character.isWhitespace(templateText.charAt(index - 1))) {
194 name = StringUtil.capitalize(name);
196 else {
197 name = StringUtil.decapitalize(name);
199 if (from == 0) {
200 Expression nameExpr = new ConstantNode(name);
201 template.addVariable("name", nameExpr, nameExpr, !automatic);
202 } else {
203 template.addVariableSegment("name");
206 from = index + "${NAME}".length();
208 template.addTextSegment(templateText.substring(from, templateText.length()));
210 return template;
213 public static PsiMethod createDummyMethod(Project project) {
214 PsiElementFactory f = JavaPsiFacade.getInstance(project).getElementFactory();
215 return f.createMethod("dummy", PsiType.VOID);