junit: skip inner classes for known runners in test detection (IDEA-185621)
[idea/community.git] / java / java-tests / testSrc / com / intellij / java / execution / ConfigurationRefactoringsTest.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 package com.intellij.java.execution;
5
6 import com.intellij.execution.RunManager;
7 import com.intellij.execution.application.ApplicationConfiguration;
8 import com.intellij.execution.configurations.RunConfiguration;
9 import com.intellij.execution.configurations.RuntimeConfigurationException;
10 import com.intellij.execution.impl.RunManagerImpl;
11 import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
12 import com.intellij.execution.junit.AllInPackageConfigurationProducer;
13 import com.intellij.execution.junit.JUnitConfiguration;
14 import com.intellij.execution.junit.JUnitConfigurationType;
15 import com.intellij.execution.testframework.AbstractJavaTestConfigurationProducer;
16 import com.intellij.openapi.vfs.JarFileSystem;
17 import com.intellij.openapi.vfs.LocalFileSystem;
18 import com.intellij.openapi.vfs.VirtualFile;
19 import com.intellij.project.IntelliJProjectConfiguration;
20 import com.intellij.psi.*;
21 import com.intellij.refactoring.PackageWrapper;
22 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
23 import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination;
24 import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions;
25 import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor;
26 import com.intellij.refactoring.rename.RenameProcessor;
27 import com.intellij.testFramework.MapDataContext;
28 import org.jetbrains.annotations.NotNull;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.HashSet;
33
34 public class ConfigurationRefactoringsTest extends BaseConfigurationTestCase {
35   private static final String APPLICATION_CODE = "public class Application {" +
36                                                  "  public static void main(String[] args) {\n" +
37                                                  "  }" +
38                                                  "}";
39   private static final String TEST_CODE = "import junit.framework.TestCase;" +
40                                           "public class ATest extends TestCase {" +
41                                           "public void test() {}" +
42                                           "private void otherMethod() {}" +
43                                           "}";
44   private TestSources mySource;
45   private static final String NOT_A_TEST = "public class NotATest {" +
46                                            "public void test() {}" +
47                                            "}";
48   public void testRenameApplication() throws IOException {
49     PsiClass psiClass = mySource.createClass("Application", APPLICATION_CODE);
50     assertNotNull(psiClass);
51     ApplicationConfiguration configuration = createConfiguration(psiClass);
52     assertNotNull(configuration);
53     rename(psiClass, "NewName");
54     try {
55       configuration.checkConfiguration();
56     }
57     catch (RuntimeConfigurationException e) {
58       fail("Unexpected ConfigurationException: " + e);
59     }
60     assertEquals("NewName", configuration.getMainClassName());
61   }
62
63   public void testMoveApplication() throws IOException {
64     PsiClass psiClass = mySource.createClass("Application", APPLICATION_CODE);
65     assertNotNull(psiClass);
66     ApplicationConfiguration configuration = createConfiguration(psiClass);
67     move(psiClass, "pkg");
68     try {
69       configuration.checkConfiguration();
70     }
71     catch (RuntimeConfigurationException e) {
72       fail("Unexpected ConfigurationException: " + e);
73     }
74
75     assertEquals("pkg.Application", configuration.getMainClassName());
76     rename(JavaPsiFacade.getInstance(myProject).findPackage("pkg"), "pkg2");
77     assertEquals("pkg2.Application", configuration.getMainClassName());
78   }
79
80   public void testRenameJUnitPackage() {
81     PsiPackage psiPackage = mySource.createPackage("pkg");
82     JUnitConfiguration configuration = createJUnitConfiguration(psiPackage, AllInPackageConfigurationProducer.class, new MapDataContext());
83     rename(psiPackage, "pkg2");
84     checkPackage("pkg2", configuration);
85     PsiPackage outer = mySource.createPackage("outerPkg");
86     move(JavaPsiFacade.getInstance(myProject).findPackage("pkg2"), outer.getQualifiedName());
87     checkPackage("outerPkg.pkg2", configuration);
88     rename(outer, "outer2");
89     checkPackage("outer2.pkg2", configuration);
90   }
91
92   public void testRenameJUnitContainingPackage() throws IOException {
93     PsiClass psiClass = mySource.createClass("ATest", TEST_CODE);
94     assertNotNull(psiClass);
95     JUnitConfiguration configuration = createConfiguration(psiClass);
96     PsiPackage psiPackage = mySource.createPackage("pkg");
97     move(psiClass, "pkg");
98     checkClassName("pkg.ATest", configuration);
99     rename(psiPackage, "newPkg");
100     checkClassName("newPkg.ATest", configuration);
101     psiPackage = mySource.findPackage("newPkg");
102
103     mySource.createPackage("pkg2");
104     move(psiPackage, "pkg2");
105     checkClassName("pkg2.newPkg.ATest", configuration);
106   }
107
108   public void testRefactorTestMethod() throws IOException {
109     PsiClass psiClass = mySource.createClass("ATest", TEST_CODE);
110     assertNotNull(psiClass);
111     PsiMethod testMethod = psiClass.findMethodsByName("test", false)[0];
112     JUnitConfiguration configuration = createConfiguration(testMethod);
113     rename(testMethod, "test1");
114     checkMethodName("test1", configuration);
115     checkClassName("ATest", configuration);
116     assertEquals("ATest.test1", configuration.getName());
117     move(psiClass, "pkg");
118     checkClassName("pkg.ATest", configuration);
119     psiClass = configuration.getConfigurationModule().findClass(configuration.getPersistentData().getMainClassName());
120     rename(psiClass, "TestClassName");
121     assertEquals("TestClassName.test1", configuration.getName());
122     psiClass = configuration.getConfigurationModule().findClass(configuration.getPersistentData().getMainClassName());
123
124     PsiClass otherTest = mySource.createClass("ATest", TEST_CODE);
125     HashSet<PsiMember> members = new HashSet<>();
126     assertNotNull(psiClass);
127     members.add(psiClass.findMethodsByName("test1", false)[0]);
128     moveMembers(otherTest, members);
129     psiClass = configuration.getConfigurationModule().findClass(configuration.getPersistentData().getMainClassName());
130     checkMethodName("test1", configuration);
131     checkClassName("ATest", configuration);
132     assertEquals("ATest.test1", configuration.getName());
133
134     assertNotNull(psiClass);
135     PsiMethod otherMethod = psiClass.findMethodsByName("otherMethod", false)[0];
136     rename(otherMethod, "newName");
137     checkMethodName("test1", configuration);
138   }
139
140   public void testRenameBadTestClass() throws IOException {
141     PsiClass psiClass = mySource.createClass("NotATest", NOT_A_TEST);
142     assertNotNull(psiClass);
143     JUnitConfigurationType instance = JUnitConfigurationType.getInstance();
144     assertNotNull(instance);
145     JUnitConfiguration configuration = new JUnitConfiguration("notATest", myProject, instance.getConfigurationFactories()[0]);
146     configuration.setMainClass(psiClass);
147     configuration.setModule(configuration.getValidModules().iterator().next());
148
149     checkConfigurationException("NotATest isn't test class", configuration);
150
151     RunManagerImpl runManager = (RunManagerImpl)RunManager.getInstance(myProject);
152     runManager.setTemporaryConfiguration(new RunnerAndConfigurationSettingsImpl(runManager, configuration, false));
153     rename(psiClass, "NotATest2");
154     JUnitConfiguration.Data data = configuration.getPersistentData();
155     assertEquals("NotATest2", data.getMainClassName());
156
157     data.METHOD_NAME = "test";
158     data.TEST_OBJECT = JUnitConfiguration.TEST_METHOD;
159     checkConfigurationException("Test method 'test' doesn't exist", configuration);
160     rename(psiClass.findMethodsByName("test", false)[0], "test2");
161     assertEquals("NotATest2", data.getMainClassName());
162     assertEquals("test2", data.getMethodName());
163   }
164
165   private static void checkConfigurationException(String expectedExceptionMessage, JUnitConfiguration configuration) {
166     try {
167       configuration.checkConfiguration();
168     }
169     catch (RuntimeConfigurationException e) {
170       assertEquals(expectedExceptionMessage, e.getLocalizedMessage());
171       return;
172     }
173     fail("ConfigurationException expected");
174   }
175
176   public void testRefactorOtherClass() throws IOException {
177     PsiClass psiClass = mySource.createClass("ATest", TEST_CODE);
178     assertNotNull(psiClass);
179     JUnitConfiguration configuration = createConfiguration(psiClass);
180
181     psiClass = mySource.createClass("Application", APPLICATION_CODE);
182     assertNotNull(psiClass);
183     rename(psiClass, "NewName");
184     checkClassName("ATest", configuration);
185     mySource.createPackage("pkg");
186
187     psiClass = mySource.findClass("NewName");
188     assertNotNull(psiClass);
189     move(psiClass, "pkg");
190     checkClassName("ATest", configuration);
191   }
192
193   private void moveMembers(final PsiClass otherTest, final HashSet<PsiMember> members) {
194     MockMoveMembersOptions options = new MockMoveMembersOptions(otherTest.getQualifiedName(), members);
195     new MoveMembersProcessor(myProject, null, options).run();
196   }
197
198   private void initModule() {
199     mySource.initModule();
200     mySource.copyJdkFrom(myModule);
201     IntelliJProjectConfiguration.LibraryRoots junit4Library = IntelliJProjectConfiguration.getProjectLibrary("JUnit4");
202     for (File file : junit4Library.getClasses()) {
203       VirtualFile libFile = LocalFileSystem.getInstance().findFileByIoFile(file);
204       assertNotNull(libFile);
205       mySource.addLibrary(JarFileSystem.getInstance().getJarRootForLocalFile(libFile));
206     }
207   }
208
209   private void move(final PsiElement psiElement, String packageName) {
210     VirtualFile pkgFile = mySource.createPackageDir(packageName);
211     final PsiDirectory toDir = PsiManager.getInstance(myProject).findDirectory(pkgFile);
212     assertNotNull(toDir);
213     PackageWrapper wrapper = PackageWrapper.create(JavaDirectoryService.getInstance().getPackage(toDir));
214     new MoveClassesOrPackagesProcessor(myProject, new PsiElement[]{psiElement},
215                                        new SingleSourceRootMoveDestination(wrapper, toDir),
216                                        false, false, null).run();
217   }
218
219   private void rename(final PsiElement psiElement, final String newName) {
220     new RenameProcessor(myProject, psiElement, newName, false, false).run();
221   }
222
223   @Override
224   protected void setUp() throws Exception {
225     super.setUp();
226
227     mySource = new TestSources(myProject, myFilesToDelete);
228     initModule();
229   }
230
231   @Override
232   protected void tearDown() throws Exception {
233     try {
234       mySource.tearDown();
235       mySource = null;
236     }
237     finally {
238       super.tearDown();
239     }
240   }
241
242   @Override
243   protected <T extends RunConfiguration> T createConfiguration(@NotNull PsiElement psiClass, @NotNull MapDataContext dataContext) {
244     T configuration = super.createConfiguration(psiClass, dataContext);
245     RunManagerImpl manager = (RunManagerImpl)RunManager.getInstance(myProject);
246     manager.setTemporaryConfiguration(new RunnerAndConfigurationSettingsImpl(manager, configuration, false));
247     return configuration;
248   }
249
250   @Override
251   protected JUnitConfiguration createJUnitConfiguration(@NotNull PsiElement psiElement,
252                                                         @NotNull Class<? extends AbstractJavaTestConfigurationProducer> producerClass,
253                                                         @NotNull MapDataContext dataContext) {
254     final JUnitConfiguration configuration = super.createJUnitConfiguration(psiElement, producerClass, dataContext);
255     RunManagerImpl manager = (RunManagerImpl)RunManager.getInstance(myProject);
256     manager.setTemporaryConfiguration(new RunnerAndConfigurationSettingsImpl(manager, configuration));
257     return configuration;
258   }
259 }