junit 5 tags support (IDEA-163481)
[idea/community.git] / plugins / junit / src / com / intellij / execution / junit / JUnitConfiguration.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
3  */
4
5 package com.intellij.execution.junit;
6
7 import com.intellij.codeInsight.MetaAnnotationUtil;
8 import com.intellij.diagnostic.logging.LogConfigurationPanel;
9 import com.intellij.execution.*;
10 import com.intellij.execution.actions.RunConfigurationProducer;
11 import com.intellij.execution.configuration.EnvironmentVariablesComponent;
12 import com.intellij.execution.configurations.*;
13 import com.intellij.execution.executors.DefaultRunExecutor;
14 import com.intellij.execution.junit2.configuration.JUnitConfigurable;
15 import com.intellij.execution.junit2.info.MethodLocation;
16 import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties;
17 import com.intellij.execution.runners.ExecutionEnvironment;
18 import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
19 import com.intellij.execution.testframework.TestSearchScope;
20 import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties;
21 import com.intellij.openapi.module.Module;
22 import com.intellij.openapi.module.ModuleManager;
23 import com.intellij.openapi.options.SettingsEditor;
24 import com.intellij.openapi.options.SettingsEditorGroup;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.Comparing;
27 import com.intellij.openapi.util.DefaultJDOMExternalizer;
28 import com.intellij.openapi.util.InvalidDataException;
29 import com.intellij.openapi.util.WriteExternalException;
30 import com.intellij.openapi.util.io.FileUtil;
31 import com.intellij.openapi.util.text.StringUtil;
32 import com.intellij.psi.*;
33 import com.intellij.psi.util.ClassUtil;
34 import com.intellij.refactoring.listeners.RefactoringElementListener;
35 import com.intellij.rt.execution.junit.RepeatCount;
36 import com.intellij.util.ArrayUtil;
37 import org.jdom.Element;
38 import org.jetbrains.annotations.NonNls;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41
42 import java.util.*;
43
44 public class JUnitConfiguration extends JavaTestConfigurationBase {
45   public static final String DEFAULT_PACKAGE_NAME = ExecutionBundle.message("default.package.presentable.name");
46
47   @NonNls public static final String TEST_CLASS = "class";
48   @NonNls public static final String TEST_PACKAGE = "package";
49   @NonNls public static final String TEST_DIRECTORY = "directory";
50   @NonNls public static final String TEST_CATEGORY = "category";
51   @NonNls public static final String TEST_METHOD = "method";
52   @NonNls public static final String TEST_UNIQUE_ID = "uniqueId";
53   @NonNls public static final String TEST_TAGS = "tags";
54   @NonNls public static final String BY_SOURCE_POSITION = "source location";
55   @NonNls public static final String BY_SOURCE_CHANGES = "changes";
56
57   //fork modes
58   @NonNls public static final String FORK_NONE = "none";
59   @NonNls public static final String FORK_METHOD = "method";
60   @NonNls public static final String FORK_KLASS = "class";
61   @NonNls public static final String FORK_REPEAT = "repeat";
62   // See #26522
63   @NonNls public static final String JUNIT_START_CLASS = "com.intellij.rt.execution.junit.JUnitStarter";
64   @NonNls private static final String PATTERN_EL_NAME = "pattern";
65   @NonNls public static final String TEST_PATTERN = PATTERN_EL_NAME;
66   @NonNls private static final String TEST_CLASS_ATT_NAME = "testClass";
67   @NonNls private static final String PATTERNS_EL_NAME = "patterns";
68   private final Data myData;
69   final RefactoringListeners.Accessor<PsiPackage> myPackage = new RefactoringListeners.Accessor<PsiPackage>() {
70     @Override
71     public void setName(final String qualifiedName) {
72       final boolean generatedName = isGeneratedName();
73       myData.PACKAGE_NAME = qualifiedName;
74       if (generatedName) setGeneratedName();
75     }
76
77     @Override
78     public PsiPackage getPsiElement() {
79       final String qualifiedName = myData.getPackageName();
80       return qualifiedName != null ? JavaPsiFacade.getInstance(getProject()).findPackage(qualifiedName)
81                                    : null;
82     }
83
84     @Override
85     public void setPsiElement(final PsiPackage psiPackage) {
86       setName(psiPackage.getQualifiedName());
87     }
88   };
89   final RefactoringListeners.Accessor<PsiClass> myClass = new RefactoringListeners.Accessor<PsiClass>() {
90     @Override
91     public void setName(@NotNull final String qualifiedName) {
92       final boolean generatedName = isGeneratedName();
93       myData.MAIN_CLASS_NAME = qualifiedName;
94       if (generatedName) setGeneratedName();
95     }
96
97     @Override
98     public PsiClass getPsiElement() {
99       return getConfigurationModule().findClass(myData.getMainClassName());
100     }
101
102     @Override
103     public void setPsiElement(final PsiClass psiClass) {
104       final Module originalModule = getConfigurationModule().getModule();
105       setMainClass(psiClass);
106       restoreOriginalModule(originalModule);
107     }
108   };
109   
110   final RefactoringListeners.Accessor<PsiClass> myCategory = new RefactoringListeners.Accessor<PsiClass>() {
111     @Override
112     public void setName(@NotNull final String qualifiedName) {
113       setCategory(qualifiedName);
114     }
115
116     @Override
117     public PsiClass getPsiElement() {
118       return getConfigurationModule().findClass(myData.getCategory());
119     }
120
121     @Override
122     public void setPsiElement(final PsiClass psiClass) {
123       setCategory(JavaExecutionUtil.getRuntimeQualifiedName(psiClass));
124     }
125   };
126   public boolean ALTERNATIVE_JRE_PATH_ENABLED;
127   public String ALTERNATIVE_JRE_PATH;
128
129   public JUnitConfiguration(final String name, final Project project, ConfigurationFactory configurationFactory) {
130     this(name, project, new Data(), configurationFactory);
131   }
132
133   protected JUnitConfiguration(final String name, final Project project, final Data data, ConfigurationFactory configurationFactory) {
134     super(name, new JavaRunConfigurationModule(project, false), configurationFactory);
135     myData = data;
136   }
137
138   @Override
139   public TestObject getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
140     return TestObject.fromString(myData.TEST_OBJECT, this, env);
141   }
142
143   @Override
144   @NotNull
145   public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
146     SettingsEditorGroup<JUnitConfiguration> group = new SettingsEditorGroup<>();
147     group.addEditor(ExecutionBundle.message("run.configuration.configuration.tab.title"), new JUnitConfigurable(getProject()));
148     JavaRunConfigurationExtensionManager.getInstance().appendEditors(this, group);
149     group.addEditor(ExecutionBundle.message("logs.tab.title"), new LogConfigurationPanel<>());
150     return group;
151   }
152
153   public Data getPersistentData() {
154     return myData;
155   }
156
157   @Override
158   public RefactoringElementListener getRefactoringElementListener(final PsiElement element) {
159     final RefactoringElementListener listener = getTestObject().getListener(element, this);
160     return RunConfigurationExtension.wrapRefactoringElementListener(element, this, listener);
161   }
162
163   @Override
164   public void checkConfiguration() throws RuntimeConfigurationException {
165     getTestObject().checkConfiguration();
166     JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
167   }
168
169   @Override
170   public Collection<Module> getValidModules() {
171     if (TEST_PACKAGE.equals(myData.TEST_OBJECT) || TEST_PATTERN.equals(myData.TEST_OBJECT)) {
172       return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
173     }
174     try {
175       getTestObject().checkConfiguration();
176     }
177     catch (RuntimeConfigurationError e) {
178       return Arrays.asList(ModuleManager.getInstance(getProject()).getModules());
179     }
180     catch (RuntimeConfigurationException e) {
181       //ignore
182     }
183
184     return JavaRunConfigurationModule.getModulesForClass(getProject(), myData.getMainClassName());
185   }
186
187   @Override
188   public String suggestedName() {
189     String repeat;
190     switch (getRepeatMode()) {
191       case RepeatCount.UNLIMITED :
192       case RepeatCount.UNTIL_FAILURE :
193         repeat = " [*]";
194         break;
195       case RepeatCount.N:
196         repeat = " [" + getRepeatCount() + "]";
197         break;
198       default:
199         repeat = "";
200     }
201     return myData.getGeneratedName(getConfigurationModule()) + repeat;
202   }
203
204   @Override
205   public String getActionName() {
206     return getTestObject().suggestActionName();
207   }
208
209   @Override
210   public String getVMParameters() {
211     return myData.getVMParameters();
212   }
213
214   @Override
215   public void setVMParameters(@Nullable String value) {
216     myData.setVMParameters(value);
217   }
218
219   @Override
220   public String getProgramParameters() {
221     return myData.getProgramParameters();
222   }
223
224   @Override
225   public void setProgramParameters(String value) {
226     myData.setProgramParameters(value);
227   }
228
229   @Override
230   public String getWorkingDirectory() {
231     return myData.getWorkingDirectory();
232   }
233
234   @Override
235   public void setWorkingDirectory(String value) {
236     myData.setWorkingDirectory(value);
237   }
238
239   @Override
240   @NotNull
241   public Map<String, String> getEnvs() {
242     return myData.getEnvs();
243   }
244
245   @Override
246   public void setEnvs(@NotNull Map<String, String> envs) {
247     myData.setEnvs(envs);
248   }
249
250   @Override
251   public boolean isPassParentEnvs() {
252     return myData.PASS_PARENT_ENVS;
253   }
254
255   @Override
256   public void setPassParentEnvs(boolean passParentEnvs) {
257     myData.PASS_PARENT_ENVS = passParentEnvs;
258   }
259
260   @Override
261   public boolean isAlternativeJrePathEnabled() {
262     return ALTERNATIVE_JRE_PATH_ENABLED;
263   }
264
265   @Override
266   public void setAlternativeJrePathEnabled(boolean enabled) {
267     ALTERNATIVE_JRE_PATH_ENABLED = enabled;
268   }
269
270   @Override
271   public String getAlternativeJrePath() {
272     return ALTERNATIVE_JRE_PATH;
273   }
274
275   @Override
276   public void setAlternativeJrePath(String path) {
277     ALTERNATIVE_JRE_PATH = path;
278   }
279
280   @Override
281   public String getRunClass() {
282     final Data data = getPersistentData();
283     return !Comparing.strEqual(data.TEST_OBJECT, TEST_CLASS) &&
284            !Comparing.strEqual(data.TEST_OBJECT, TEST_METHOD) ? null : data.getMainClassName();
285   }
286
287   @Override
288   public String getPackage() {
289     final Data data = getPersistentData();
290     return !Comparing.strEqual(data.TEST_OBJECT, TEST_PACKAGE) ? null : data.getPackageName();
291   }
292
293   public void beClassConfiguration(final PsiClass testClass) {
294     if (FORK_KLASS.equals(getForkMode())) {
295       setForkMode(FORK_NONE);
296     }
297     setMainClass(testClass);
298     myData.TEST_OBJECT = TEST_CLASS;
299     setGeneratedName();
300   }
301
302   @Override
303   public boolean isConfiguredByElement(PsiElement element) {
304     final PsiClass testClass = JUnitUtil.getTestClass(element);
305     final PsiMethod testMethod = JUnitUtil.getTestMethod(element, false);
306     final PsiPackage testPackage;
307     if (element instanceof PsiPackage) {
308       testPackage = (PsiPackage)element;
309     } else if (element instanceof PsiDirectory){
310       testPackage = JavaDirectoryService.getInstance().getPackage(((PsiDirectory)element));
311     } else {
312       testPackage = null;
313     }
314     PsiDirectory testDir = element instanceof PsiDirectory ? (PsiDirectory)element : null;
315
316     return getTestObject().isConfiguredByElement(this, testClass, testMethod, testPackage, testDir);
317   }
318
319   @Override
320   public TestSearchScope getTestSearchScope() {
321     return getPersistentData().getScope();
322   }
323
324   public void beFromSourcePosition(PsiLocation<PsiMethod> sourceLocation) {
325     myData.setTestMethod(sourceLocation);
326     myData.TEST_OBJECT = BY_SOURCE_POSITION;
327   }
328
329   public void setMainClass(final PsiClass testClass) {
330     final boolean shouldUpdateName = isGeneratedName();
331     setModule(myData.setMainClass(testClass));
332     if (shouldUpdateName) setGeneratedName();
333   }
334
335   public void setCategory(String categoryName) {
336     final boolean shouldUpdateName = isGeneratedName();
337     myData.setCategoryName(categoryName);
338     if (shouldUpdateName) setGeneratedName();
339   }
340
341   public void beMethodConfiguration(final Location<PsiMethod> methodLocation) {
342     setForkMode(FORK_NONE);
343     setModule(myData.setTestMethod(methodLocation));
344     setGeneratedName();
345   }
346
347   @Override
348   @NotNull
349   public Module[] getModules() {
350     if (TEST_PACKAGE.equals(myData.TEST_OBJECT) &&
351         getPersistentData().getScope() == TestSearchScope.WHOLE_PROJECT) {
352       return Module.EMPTY_ARRAY;
353     }
354     return super.getModules();
355   }
356
357   public TestObject getTestObject() {
358     return myData.getTestObject(this);
359   }
360
361   @Override
362   public void readExternal(@NotNull final Element element) throws InvalidDataException {
363     super.readExternal(element);
364     JavaRunConfigurationExtensionManager.getInstance().readExternal(this, element);
365     DefaultJDOMExternalizer.readExternal(this, element);
366     DefaultJDOMExternalizer.readExternal(getPersistentData(), element);
367     EnvironmentVariablesComponent.readExternal(element, getPersistentData().getEnvs());
368     final Element patternsElement = element.getChild(PATTERNS_EL_NAME);
369     if (patternsElement != null) {
370       final LinkedHashSet<String> tests = new LinkedHashSet<>();
371       for (Element patternElement : patternsElement.getChildren(PATTERN_EL_NAME)) {
372         tests.add(patternElement.getAttributeValue(TEST_CLASS_ATT_NAME));
373       }
374       myData.setPatterns(tests);
375     }
376     final Element forkModeElement = element.getChild("fork_mode");
377     if (forkModeElement != null) {
378       final String mode = forkModeElement.getAttributeValue("value");
379       if (mode != null) {
380         setForkMode(mode);
381       }
382     }
383     final String count = element.getAttributeValue("repeat_count");
384     if (count != null) {
385       try {
386         setRepeatCount(Integer.parseInt(count));
387       }
388       catch (NumberFormatException e) {
389         setRepeatCount(1);
390       }
391     }
392     final String repeatMode = element.getAttributeValue("repeat_mode");
393     if (repeatMode != null) {
394       setRepeatMode(repeatMode);
395     }
396     final Element dirNameElement = element.getChild("dir");
397     if (dirNameElement != null) {
398       final String dirName = dirNameElement.getAttributeValue("value");
399       getPersistentData().setDirName(FileUtil.toSystemDependentName(dirName));
400     }
401
402     final Element categoryNameElement = element.getChild("category");
403     if (categoryNameElement != null) {
404       final String categoryName = categoryNameElement.getAttributeValue("value");
405       getPersistentData().setCategoryName(categoryName);
406     }
407
408     Element idsElement = element.getChild("uniqueIds");
409     if (idsElement != null) {
410       List<String> ids = new ArrayList<>();
411       idsElement.getChildren("uniqueId").forEach(uniqueIdElement -> ids.add(uniqueIdElement.getAttributeValue("value")));
412       getPersistentData().setUniqueIds(ArrayUtil.toStringArray(ids));
413     }
414   }
415
416   @Override
417   public void writeExternal(@NotNull final Element element) throws WriteExternalException {
418     super.writeExternal(element);
419     JavaRunConfigurationExtensionManager.getInstance().writeExternal(this, element);
420     DefaultJDOMExternalizer.writeExternal(this, element);
421     final Data persistentData = getPersistentData();
422     DefaultJDOMExternalizer.writeExternal(persistentData, element);
423
424     if (!persistentData.getEnvs().isEmpty()) {
425       EnvironmentVariablesComponent.writeExternal(element, persistentData.getEnvs());
426     }
427
428     final String dirName = persistentData.getDirName();
429     if (!dirName.isEmpty()) {
430       final Element dirNameElement = new Element("dir");
431       dirNameElement.setAttribute("value", FileUtil.toSystemIndependentName(dirName));
432       element.addContent(dirNameElement);
433     }
434
435     final String categoryName = persistentData.getCategory();
436     if (!categoryName.isEmpty()) {
437       final Element categoryNameElement = new Element("category");
438       categoryNameElement.setAttribute("value", categoryName);
439       element.addContent(categoryNameElement);
440     }
441
442     final Element patternsElement = new Element(PATTERNS_EL_NAME);
443     for (String o : persistentData.getPatterns()) {
444       final Element patternElement = new Element(PATTERN_EL_NAME);
445       patternElement.setAttribute(TEST_CLASS_ATT_NAME, o);
446       patternsElement.addContent(patternElement);
447     }
448     element.addContent(patternsElement);
449     final String forkMode = getForkMode();
450     if (!forkMode.equals("none")) {
451       final Element forkModeElement = new Element("fork_mode");
452       forkModeElement.setAttribute("value", forkMode);
453       element.addContent(forkModeElement);
454     }
455     if (getRepeatCount() != 1) {
456       element.setAttribute("repeat_count", String.valueOf(getRepeatCount()));
457     }
458     final String repeatMode = getRepeatMode();
459     if (!RepeatCount.ONCE.equals(repeatMode)) {
460       element.setAttribute("repeat_mode", repeatMode);
461     }
462     String[] ids = persistentData.getUniqueIds();
463     if (ids != null) {
464       Element uniqueIds = new Element("uniqueIds");
465       Arrays.stream(ids).forEach(id -> uniqueIds.addContent(new Element("uniqueId").setAttribute("value", id)));
466       element.addContent(uniqueIds);
467     }
468   }
469
470   public String getForkMode() {
471     return myData.FORK_MODE;
472   }
473
474   public void setForkMode(@NotNull String forkMode) {
475     myData.FORK_MODE = forkMode;
476   }
477
478   @Override
479   public boolean collectOutputFromProcessHandler() {
480     return false;
481   }
482
483   public void bePatternConfiguration(List<PsiClass> classes, PsiMethod method) {
484     myData.TEST_OBJECT = TEST_PATTERN;
485     final LinkedHashSet<String> patterns = new LinkedHashSet<>();
486     final String methodSufiix;
487     if (method != null) {
488       myData.METHOD_NAME = Data.getMethodPresentation(method);
489       methodSufiix = "," + myData.METHOD_NAME;
490     } else {
491       methodSufiix = "";
492     }
493     for (PsiClass pattern : classes) {
494       patterns.add(JavaExecutionUtil.getRuntimeQualifiedName(pattern) + methodSufiix);
495     }
496     myData.setPatterns(patterns);
497     final Module module = RunConfigurationProducer.getInstance(PatternConfigurationProducer.class).findModule(this, getConfigurationModule()
498       .getModule(), patterns);
499     if (module == null) {
500       myData.setScope(TestSearchScope.WHOLE_PROJECT);
501       setModule(null);
502     } else {
503       setModule(module);
504     }
505     setGeneratedName();
506   }
507
508   public int getRepeatCount() {
509     return myData.REPEAT_COUNT;
510   }
511
512   public void setRepeatCount(int repeatCount) {
513     myData.REPEAT_COUNT = repeatCount;
514   }
515
516   public String getRepeatMode() {
517     return myData.REPEAT_MODE;
518   }
519
520   public void setRepeatMode(String repeatMode) {
521     myData.REPEAT_MODE = repeatMode;
522   }
523
524   @Override
525   public SMTRunnerConsoleProperties createTestConsoleProperties(Executor executor) {
526     return new JUnitConsoleProperties(this, executor);
527   }
528
529   @NotNull
530   @Override
531   public String getFrameworkPrefix() {
532     return "j";
533   }
534
535   public static class Data implements Cloneable {
536     public String PACKAGE_NAME;
537     public String MAIN_CLASS_NAME;
538     public String METHOD_NAME;
539     private String[] UNIQUE_ID;
540     private String[] TAGS;
541     public String TEST_OBJECT = TEST_CLASS;
542     public String VM_PARAMETERS;
543     public String PARAMETERS;
544     public String WORKING_DIRECTORY;
545     public boolean PASS_PARENT_ENVS = true;
546     public TestSearchScope.Wrapper TEST_SEARCH_SCOPE = new TestSearchScope.Wrapper();
547     private String DIR_NAME;
548     private String CATEGORY_NAME;
549     private String FORK_MODE = FORK_NONE;
550     private int REPEAT_COUNT = 1;
551     private String REPEAT_MODE = RepeatCount.ONCE;
552     private LinkedHashSet<String> myPattern = new LinkedHashSet<>();
553     private Map<String, String> myEnvs = new LinkedHashMap<>();
554     private String myChangeList = "All";
555
556     public boolean equals(final Object object) {
557       if (!(object instanceof Data)) return false;
558       final Data second = (Data)object;
559       return Comparing.equal(TEST_OBJECT, second.TEST_OBJECT) &&
560              Comparing.equal(getMainClassName(), second.getMainClassName()) &&
561              Comparing.equal(getPackageName(), second.getPackageName()) &&
562              Comparing.equal(getMethodNameWithSignature(), second.getMethodNameWithSignature()) &&
563              Comparing.equal(getWorkingDirectory(), second.getWorkingDirectory()) &&
564              Comparing.equal(VM_PARAMETERS, second.VM_PARAMETERS) &&
565              Comparing.equal(PARAMETERS, second.PARAMETERS) &&
566              Comparing.equal(myPattern, second.myPattern) &&
567              Comparing.equal(FORK_MODE, second.FORK_MODE) &&
568              Comparing.equal(DIR_NAME, second.DIR_NAME) &&
569              Comparing.equal(CATEGORY_NAME, second.CATEGORY_NAME) &&
570              Comparing.equal(UNIQUE_ID, second.UNIQUE_ID) &&
571              Comparing.equal(TAGS, second.TAGS) &&
572              Comparing.equal(REPEAT_MODE, second.REPEAT_MODE) &&
573              REPEAT_COUNT == second.REPEAT_COUNT;
574     }
575
576     public int hashCode() {
577       return Comparing.hashcode(TEST_OBJECT) ^
578              Comparing.hashcode(getMainClassName()) ^
579              Comparing.hashcode(getPackageName()) ^
580              Comparing.hashcode(getMethodNameWithSignature()) ^
581              Comparing.hashcode(getWorkingDirectory()) ^
582              Comparing.hashcode(VM_PARAMETERS) ^
583              Comparing.hashcode(PARAMETERS) ^
584              Comparing.hashcode(myPattern) ^
585              Comparing.hashcode(FORK_MODE) ^
586              Comparing.hashcode(DIR_NAME) ^
587              Comparing.hashcode(CATEGORY_NAME) ^
588              Comparing.hashcode(UNIQUE_ID) ^
589              Comparing.hashcode(TAGS) ^
590              Comparing.hashcode(REPEAT_MODE) ^
591              Comparing.hashcode(REPEAT_COUNT);
592     }
593
594     public TestSearchScope getScope() {
595       return TEST_SEARCH_SCOPE.getScope();
596     }
597
598     public void setScope(final TestSearchScope scope) {
599       TEST_SEARCH_SCOPE.setScope(scope);
600     }
601
602     @Override
603     public Data clone() {
604       try {
605         Data data = (Data)super.clone();
606         data.TEST_SEARCH_SCOPE = new TestSearchScope.Wrapper();
607         data.setScope(getScope());
608         data.myEnvs = new LinkedHashMap<>(myEnvs);
609         return data;
610       }
611       catch (CloneNotSupportedException e) {
612         throw new RuntimeException(e);
613       }
614     }
615
616     public String getVMParameters() {
617       return VM_PARAMETERS;
618     }
619
620     public void setVMParameters(String value) {
621       VM_PARAMETERS = value;
622     }
623
624     public String getProgramParameters() {
625       return PARAMETERS;
626     }
627
628     public void setProgramParameters(String value) {
629       PARAMETERS = value;
630     }
631
632     public String getWorkingDirectory() {
633       return ExternalizablePath.localPathValue(WORKING_DIRECTORY);
634     }
635
636     public void setWorkingDirectory(String value) {
637       WORKING_DIRECTORY = ExternalizablePath.urlValue(value);
638     }
639
640     public void setUniqueIds(String... uniqueId) {
641       UNIQUE_ID = uniqueId;
642     }
643
644     public String[] getUniqueIds() {
645       return UNIQUE_ID;
646     }
647
648     public Module setTestMethod(final Location<PsiMethod> methodLocation) {
649       final PsiMethod method = methodLocation.getPsiElement();
650       METHOD_NAME = getMethodPresentation(method);
651       TEST_OBJECT = TEST_METHOD;
652       return setMainClass(methodLocation instanceof MethodLocation ? ((MethodLocation)methodLocation).getContainingClass() : method.getContainingClass());
653     }
654
655     public String[] getTags() {
656       return TAGS;
657     }
658
659     public void setTags(String[] tags) {
660       TAGS = tags;
661     }
662
663     public static String getMethodPresentation(PsiMethod method) {
664       if (method.getParameterList().getParametersCount() > 0 && MetaAnnotationUtil.isMetaAnnotated(method, JUnitUtil.TEST5_ANNOTATIONS)) {
665         return method.getName() + "(" + ClassUtil.getVMParametersMethodSignature(method) + ")";
666       }
667       else {
668         return method.getName();
669       }
670     }
671
672     public String getGeneratedName(final JavaRunConfigurationModule configurationModule) {
673       if (TEST_PACKAGE.equals(TEST_OBJECT) || TEST_DIRECTORY.equals(TEST_OBJECT)) {
674         if (TEST_SEARCH_SCOPE.getScope() == TestSearchScope.WHOLE_PROJECT) {
675           return ExecutionBundle.message("default.junit.config.name.whole.project");
676         }
677         final String moduleName = TEST_SEARCH_SCOPE.getScope() == TestSearchScope.WHOLE_PROJECT ? "" : configurationModule.getModuleName();
678         final String packageName = TEST_PACKAGE.equals(TEST_OBJECT) ? getPackageName() : StringUtil.getShortName(getDirName(), '/');
679         if (packageName.length() == 0) {
680           if (moduleName.length() > 0) {
681             return ExecutionBundle.message("default.junit.config.name.all.in.module", moduleName);
682           }
683           return DEFAULT_PACKAGE_NAME;
684         }
685         if (moduleName.length() > 0) {
686           return ExecutionBundle.message("default.junit.config.name.all.in.package.in.module", packageName, moduleName);
687         }
688         return packageName;
689       }
690       if (TEST_PATTERN.equals(TEST_OBJECT)) {
691         final int size = myPattern.size();
692         if (size == 0) return "Temp suite";
693         String fqName = myPattern.iterator().next();
694         String firstName =
695           fqName.contains("*") ? fqName
696                                : StringUtil.getShortName(fqName.contains("(") ? StringUtil.getPackageName(fqName, '(') : fqName);
697         return firstName + (size > 1 ? " and " + (size - 1) + " more" : "");
698       }
699       if (TEST_CATEGORY.equals(TEST_OBJECT)) {
700         return "@Category(" + (StringUtil.isEmpty(CATEGORY_NAME) ? "Invalid" : CATEGORY_NAME) + ")";
701       }
702       if (TEST_UNIQUE_ID.equals(TEST_OBJECT)) {
703         return UNIQUE_ID != null ? StringUtil.join(UNIQUE_ID, " ") : "Temp suite";
704       }
705       if (TEST_TAGS.equals(TEST_OBJECT)) {
706         return TAGS != null ? "Tags (" + StringUtil.join(TAGS, " ") + ")" : "Temp suite";
707       }
708       final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName());
709       if (TEST_METHOD.equals(TEST_OBJECT)) {
710         return className + '.' + getMethodName();
711       }
712
713       return className;
714     }
715
716     public String getMainClassName() {
717       return MAIN_CLASS_NAME != null ? MAIN_CLASS_NAME : "";
718     }
719
720     public String getPackageName() {
721       return PACKAGE_NAME != null ? PACKAGE_NAME : "";
722     }
723
724     public String getMethodName() {
725       String signature = getMethodNameWithSignature();
726       int paramsIdx = signature.lastIndexOf("(");
727       return paramsIdx > -1 ? signature.substring(0, paramsIdx) : signature;
728     }
729
730     public String getMethodNameWithSignature() {
731       return METHOD_NAME != null ? METHOD_NAME : "";
732     }
733
734     public String getDirName() {
735       return DIR_NAME != null ? DIR_NAME : "";
736     }
737
738     public void setDirName(String dirName) {
739       DIR_NAME = dirName;
740     }
741
742     public Set<String> getPatterns() {
743       return myPattern;
744     }
745
746     public void setPatterns(LinkedHashSet<String> pattern) {
747       myPattern = pattern;
748     }
749
750     public String getPatternPresentation() {
751       final List<String> enabledTests = new ArrayList<>();
752       for (String pattern : myPattern) {
753         enabledTests.add(pattern);
754       }
755       return StringUtil.join(enabledTests, "||");
756     }
757
758     public TestObject getTestObject(@NotNull JUnitConfiguration configuration) {
759       final ExecutionEnvironment environment = ExecutionEnvironmentBuilder.create(DefaultRunExecutor.getRunExecutorInstance(), configuration).build();
760       final TestObject testObject = TestObject.fromString(TEST_OBJECT, configuration, environment);
761       return testObject == null ? new UnknownTestTarget(configuration, environment) : testObject;
762     }
763
764     public Module setMainClass(final PsiClass testClass) {
765       MAIN_CLASS_NAME = JavaExecutionUtil.getRuntimeQualifiedName(testClass);
766       PsiPackage containingPackage = JUnitUtil.getContainingPackage(testClass);
767       PACKAGE_NAME = containingPackage != null ? containingPackage.getQualifiedName() : "";
768       return JavaExecutionUtil.findModule(testClass);
769     }
770
771     public Map<String, String> getEnvs() {
772       return myEnvs;
773     }
774
775     public void setEnvs(final Map<String, String> envs) {
776       myEnvs = envs;
777     }
778
779     public String getCategory() {
780       return CATEGORY_NAME != null ? CATEGORY_NAME : "";
781     }
782
783     public void setCategoryName(String categoryName) {
784       CATEGORY_NAME = categoryName;
785     }
786
787     public String getChangeList() {
788       return myChangeList;
789     }
790
791     public void setChangeList(String changeList) {
792       myChangeList = changeList;
793     }
794   }
795
796 }