junit 5 tags support (IDEA-163481)
[idea/community.git] / plugins / junit / src / com / intellij / execution / junit2 / configuration / JUnitConfigurationModel.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.execution.junit2.configuration;
18
19 import com.intellij.execution.JavaExecutionUtil;
20 import com.intellij.execution.junit.JUnitConfiguration;
21 import com.intellij.execution.junit.JUnitUtil;
22 import com.intellij.openapi.command.WriteCommandAction;
23 import com.intellij.openapi.editor.Document;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.progress.ProcessCanceledException;
26 import com.intellij.openapi.project.IndexNotReadyException;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.psi.PsiClass;
30
31 import javax.swing.text.BadLocationException;
32 import javax.swing.text.PlainDocument;
33 import java.util.Arrays;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36
37 // Author: dyoma
38
39 public class JUnitConfigurationModel {
40   public static final int ALL_IN_PACKAGE = 0;
41   public static final int CLASS = 1;
42   public static final int METHOD = 2;
43   public static final int PATTERN = 3;
44   public static final int DIR = 4;
45   public static final int CATEGORY = 5;
46   public static final int UNIQUE_ID = 6;
47   public static final int TAGS = 7;
48   public static final int BY_SOURCE_POSITION = 8;
49   public static final int BY_SOURCE_CHANGES = 9;
50
51   private static final List<String> ourTestObjects;
52
53   static {
54     ourTestObjects = Arrays.asList(JUnitConfiguration.TEST_PACKAGE,
55                                    JUnitConfiguration.TEST_CLASS, 
56                                    JUnitConfiguration.TEST_METHOD,
57                                    JUnitConfiguration.TEST_PATTERN,
58                                    JUnitConfiguration.TEST_DIRECTORY,
59                                    JUnitConfiguration.TEST_CATEGORY,
60                                    JUnitConfiguration.TEST_UNIQUE_ID,
61                                    JUnitConfiguration.TEST_TAGS,
62                                    JUnitConfiguration.BY_SOURCE_POSITION,
63                                    JUnitConfiguration.BY_SOURCE_CHANGES);
64   }
65
66
67   private JUnitConfigurable myListener;
68   private int myType = -1;
69   private final Object[] myJUnitDocuments = new Object[6];
70   private final Project myProject;
71
72   public JUnitConfigurationModel(final Project project) {
73     myProject = project;
74   }
75
76   public boolean setType(int type) {
77     if (type == myType) return false;
78     if (type < 0 || type >= ourTestObjects.size()) type = CLASS;
79     myType = type;
80     fireTypeChanged(type);
81     return true;
82   }
83
84   private void fireTypeChanged(final int newType) {
85     myListener.onTypeChanged(newType);
86   }
87
88   public void setListener(final JUnitConfigurable listener) {
89     myListener = listener;
90   }
91
92   public Object getJUnitDocument(final int i) {
93     return myJUnitDocuments[i];
94   }
95
96   public void setJUnitDocument(final int i, Object doc) {
97      myJUnitDocuments[i] = doc;
98   }
99
100   public void apply(final Module module, final JUnitConfiguration configuration) {
101     final boolean shouldUpdateName = configuration.isGeneratedName();
102     applyTo(configuration.getPersistentData(), module);
103     if (shouldUpdateName && !JavaExecutionUtil.isNewName(configuration.getName())) {
104       configuration.setGeneratedName();
105     }
106   }
107
108   private void applyTo(final JUnitConfiguration.Data data, final Module module) {
109     final String testObject = getTestObject();
110     final String className = getJUnitTextValue(CLASS);
111     data.TEST_OBJECT = testObject;
112     if (testObject != JUnitConfiguration.TEST_PACKAGE &&
113         testObject != JUnitConfiguration.TEST_PATTERN &&
114         testObject != JUnitConfiguration.TEST_DIRECTORY &&
115         testObject != JUnitConfiguration.TEST_CATEGORY  &&
116         testObject != JUnitConfiguration.BY_SOURCE_CHANGES) {
117       try {
118         data.METHOD_NAME = getJUnitTextValue(METHOD);
119         final PsiClass testClass = !myProject.isDefault() && !StringUtil.isEmptyOrSpaces(className) ? JUnitUtil.findPsiClass(className, module, myProject) : null;
120         if (testClass != null && testClass.isValid()) {
121           data.setMainClass(testClass);
122         }
123         else {
124           data.MAIN_CLASS_NAME = className;
125         }
126       }
127       catch (ProcessCanceledException | IndexNotReadyException e) {
128         data.MAIN_CLASS_NAME = className;
129       }
130     }
131     else if (testObject != JUnitConfiguration.BY_SOURCE_CHANGES) {
132       if (testObject == JUnitConfiguration.TEST_PACKAGE) {
133         data.PACKAGE_NAME = getJUnitTextValue(ALL_IN_PACKAGE);
134       }
135       else if (testObject == JUnitConfiguration.TEST_DIRECTORY) {
136         data.setDirName(getJUnitTextValue(DIR));
137       }
138       else if (testObject == JUnitConfiguration.TEST_CATEGORY) {
139         data.setCategoryName(getJUnitTextValue(CATEGORY));
140       }
141       else {
142         final LinkedHashSet<String> set = new LinkedHashSet<>();
143         final String[] patterns = getJUnitTextValue(PATTERN).split("\\|\\|");
144         for (String pattern : patterns) {
145           if (pattern.length() > 0) {
146             set.add(pattern);
147           }
148         }
149         data.setPatterns(set);
150       }
151       data.MAIN_CLASS_NAME = "";
152       data.METHOD_NAME = "";
153     }
154   }
155
156   private String getTestObject() {
157     return ourTestObjects.get(myType);
158   }
159
160   private String getJUnitTextValue(final int index) {
161     return getDocumentText(index, myJUnitDocuments);
162   }
163
164   private static String getDocumentText(final int index, final Object[] documents) {
165     final Object document = documents[index];
166     if (document instanceof PlainDocument) {
167       try {
168         return ((PlainDocument)document).getText(0, ((PlainDocument)document).getLength());
169       }
170       catch (BadLocationException e) {
171         throw new RuntimeException(e);
172       }
173     }
174     return ((Document)document).getText();
175   }
176
177   public void reset(final JUnitConfiguration configuration) {
178     final JUnitConfiguration.Data data = configuration.getPersistentData();
179     setTestType(data.TEST_OBJECT);
180     setJUnitTextValue(ALL_IN_PACKAGE, data.getPackageName());
181     setJUnitTextValue(CLASS, data.getMainClassName() != null ? data.getMainClassName().replaceAll("\\$", "\\.") : "");
182     setJUnitTextValue(METHOD, data.getMethodNameWithSignature());
183     setJUnitTextValue(PATTERN, data.getPatternPresentation());
184     setJUnitTextValue(DIR, data.getDirName());
185     setJUnitTextValue(CATEGORY, data.getCategory());
186   }
187
188   private void setJUnitTextValue(final int index, final String text) {
189     setDocumentText(index, text, myJUnitDocuments);
190   }
191
192   private void setDocumentText(final int index, final String text, final Object[] documents) {
193     final Object document = documents[index];
194     if (document instanceof PlainDocument) {
195       try {
196         ((PlainDocument)document).remove(0, ((PlainDocument)document).getLength());
197         ((PlainDocument)document).insertString(0, text, null);
198       }
199       catch (BadLocationException e) {
200         throw new RuntimeException(e);
201       }
202     }
203     else {
204       WriteCommandAction.runWriteCommandAction(myProject, () -> ((Document)document).replaceString(0, ((Document)document).getTextLength(), text));
205     }
206   }
207
208   private void setTestType(final String testObject) {
209     setType(ourTestObjects.indexOf(testObject));
210   }
211 }
212