zero-tolerance fixes private @SafeVarArgs
[idea/community.git] / plugins / gradle / java / testSources / importing / GradleFindUsagesTest.java
1 // Copyright 2000-2019 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.
2 package org.jetbrains.plugins.gradle.importing;
3
4 import com.intellij.openapi.module.Module;
5 import com.intellij.openapi.util.Pair;
6 import com.intellij.openapi.util.Segment;
7 import com.intellij.openapi.util.Trinity;
8 import com.intellij.psi.JavaPsiFacade;
9 import com.intellij.psi.PsiClass;
10 import com.intellij.psi.PsiElement;
11 import com.intellij.psi.PsiMethod;
12 import com.intellij.psi.search.GlobalSearchScope;
13 import com.intellij.usageView.UsageInfo;
14 import org.gradle.initialization.BuildLayoutParameters;
15 import org.gradle.wrapper.PathAssembler;
16 import org.jetbrains.annotations.NotNull;
17 import org.jetbrains.annotations.Nullable;
18 import org.junit.Test;
19 import org.junit.runners.Parameterized;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.List;
27
28 import static com.intellij.openapi.util.Pair.pair;
29 import static com.intellij.testFramework.EdtTestUtil.runInEdtAndGet;
30
31 /**
32  * @author Vladislav.Soroka
33  */
34 public class GradleFindUsagesTest extends GradleImportingTestCase {
35
36   /**
37    * It's sufficient to run the test against one gradle version
38    */
39   @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
40   @Parameterized.Parameters(name = "with Gradle-{0}")
41   public static Collection<Object[]> data() {
42     return Arrays.asList(new Object[][]{{BASE_GRADLE_VERSION}});
43   }
44
45   @Override
46   protected void collectAllowedRoots(List<String> roots, PathAssembler.LocalDistribution distribution) {
47     super.collectAllowedRoots(roots, distribution);
48     File gradleUserHomeDir = new BuildLayoutParameters().getGradleUserHomeDir();
49     File generatedGradleJarsDir = new File(gradleUserHomeDir, "caches/" + gradleVersion + "/generated-gradle-jars");
50     roots.add(generatedGradleJarsDir.getPath());
51     File gradleDistLibDir = new File(distribution.getDistributionDir(), "gradle-" + gradleVersion + "/lib");
52     roots.add(gradleDistLibDir.getPath());
53   }
54
55   @Test
56   public void testBuildSrcClassesUsages() throws Exception {
57     createProjectSubFile("settings.gradle", "rootProject.name = 'multiproject'\n" +
58                                             "include ':app'");
59
60     createProjectSubFile("buildSrc/src/main/groovy/testBuildSrcClassesUsages/BuildSrcClass.groovy", "package testBuildSrcClassesUsages;\n" +
61                                                                                                     "public class BuildSrcClass {" +
62                                                                                                     "   public String sayHello() { 'Hello!' }" +
63                                                                                                     "}");
64     createProjectSubFile("app/build.gradle", "def foo = new testBuildSrcClassesUsages.BuildSrcClass().sayHello()");
65
66     importProject();
67     assertModules("multiproject", "multiproject.app",
68                   "multiproject.buildSrc", "multiproject.buildSrc.main", "multiproject.buildSrc.test");
69
70     Module buildSrcModule = getModule("multiproject.buildSrc.main");
71     assertNotNull(buildSrcModule);
72     assertUsages("testBuildSrcClassesUsages.BuildSrcClass", GlobalSearchScope.moduleScope(buildSrcModule), 1);
73     assertUsages("testBuildSrcClassesUsages.BuildSrcClass", "sayHello", GlobalSearchScope.moduleScope(buildSrcModule), 1);
74   }
75
76   @Test
77   public void testMultiModuleBuildSrcClassesUsages() throws Exception {
78     createProjectSubFile("settings.gradle", "rootProject.name = 'multiproject'\n" +
79                                             "include ':app'");
80     // buildSrc module files
81     createProjectSubFile("buildSrc/settings.gradle", "include 'buildSrcSubProject'");
82     createProjectSubFile("buildSrc/build.gradle", "allprojects {\n" +
83                                                   "    apply plugin: 'groovy'\n" +
84                                                   "    dependencies {\n" +
85                                                   "        compile gradleApi()\n" +
86                                                   "        compile localGroovy()\n" +
87                                                   "    }\n" +
88                                                   "    repositories {\n" +
89                                                   "        mavenCentral()\n" +
90                                                   "    }\n" +
91                                                   "\n" +
92                                                   "    if (it != rootProject) {\n" +
93                                                   "        rootProject.dependencies {\n" +
94                                                   "            runtime project(path)\n" +
95                                                   "        }\n" +
96                                                   "    }\n" +
97                                                   "}\n");
98     createProjectSubFile("buildSrc/src/main/groovy/testMultiModuleBuildSrcClassesUsages/BuildSrcClass.groovy",
99                          "package testMultiModuleBuildSrcClassesUsages;\n" +
100                          "public class BuildSrcClass {}");
101     createProjectSubFile("buildSrc/buildSrcSubProject/src/main/java/testMultiModuleBuildSrcClassesUsages/BuildSrcAdditionalClass.java",
102                          "package testMultiModuleBuildSrcClassesUsages;\n" +
103                          "public class BuildSrcAdditionalClass {}");
104
105     createProjectSubFile("build.gradle", "def foo = new testMultiModuleBuildSrcClassesUsages.BuildSrcClass()");
106     createProjectSubFile("app/build.gradle", "def foo1 = new testMultiModuleBuildSrcClassesUsages.BuildSrcClass()\n" +
107                                              "def foo2 = new testMultiModuleBuildSrcClassesUsages.BuildSrcAdditionalClass()");
108
109     importProject();
110     assertModules("multiproject", "multiproject.app",
111                   "multiproject.buildSrc", "multiproject.buildSrc.main", "multiproject.buildSrc.test",
112                   "multiproject.buildSrc.buildSrcSubProject", "multiproject.buildSrc.buildSrcSubProject.main", "multiproject.buildSrc.buildSrcSubProject.test");
113
114     assertUsages(pair("testMultiModuleBuildSrcClassesUsages.BuildSrcClass", 2),
115                  pair("testMultiModuleBuildSrcClassesUsages.BuildSrcAdditionalClass", 1));
116
117     importProjectUsingSingeModulePerGradleProject();
118     assertModules("multiproject", "multiproject.app",
119                   "multiproject.buildSrc",
120                   "multiproject.buildSrc.buildSrcSubProject");
121
122     assertUsages(pair("testMultiModuleBuildSrcClassesUsages.BuildSrcClass", 2),
123                  pair("testMultiModuleBuildSrcClassesUsages.BuildSrcAdditionalClass", 1));
124   }
125
126   @Test
127   public void testIncludedBuildSrcClassesUsages_nonQN() throws Exception {
128     createProjectWithIncludedBuildAndBuildSrcModules("testIncludedBuildSrcClassesUsages_nonQN");
129     // check for non-qualified module names
130     getCurrentExternalProjectSettings().setUseQualifiedModuleNames(false);
131
132     importProject();
133     assertModules("multiproject", "app",
134                   "multiproject_buildSrc", "multiproject_buildSrc_main", "multiproject_buildSrc_test",
135                   "gradle-plugin", "gradle-plugin_test", "gradle-plugin_main",
136                   "gradle-plugin_buildSrc", "gradle-plugin_buildSrc_main", "gradle-plugin_buildSrc_test");
137
138     assertUsages("testIncludedBuildSrcClassesUsages_nonQN.BuildSrcClass", 2);
139     assertUsages("testIncludedBuildSrcClassesUsages_nonQN.IncludedBuildSrcClass", 1);
140     assertUsages("testIncludedBuildSrcClassesUsages_nonQN.IncludedBuildClass", 2);
141   }
142
143   @Test
144   public void testIncludedBuildSrcClassesUsages_merged_nonQN() throws Exception {
145     createProjectWithIncludedBuildAndBuildSrcModules("testIncludedBuildSrcClassesUsages_merged_nonQN");
146     // check for non-qualified module names
147     getCurrentExternalProjectSettings().setUseQualifiedModuleNames(false);
148
149     importProjectUsingSingeModulePerGradleProject();
150     assertModules("multiproject", "app",
151                   "multiproject_buildSrc",
152                   "gradle-plugin",
153                   "gradle-plugin_buildSrc");
154     assertUsages(pair("testIncludedBuildSrcClassesUsages_merged_nonQN.BuildSrcClass", 2),
155                  pair("testIncludedBuildSrcClassesUsages_merged_nonQN.IncludedBuildSrcClass", 1));
156     assertUsages("testIncludedBuildSrcClassesUsages_merged_nonQN.IncludedBuildClass", 2);
157   }
158
159   @Test
160   public void testIncludedBuildSrcClassesUsages_qualified_names() throws Exception {
161     createProjectWithIncludedBuildAndBuildSrcModules("testIncludedBuildSrcClassesUsages_qualified_names");
162     importProject();
163     assertModules("multiproject", "multiproject.app",
164                   "multiproject.buildSrc", "multiproject.buildSrc.main", "multiproject.buildSrc.test",
165                   "gradle-plugin", "gradle-plugin.test", "gradle-plugin.main",
166                   "gradle-plugin.buildSrc", "gradle-plugin.buildSrc.main", "gradle-plugin.buildSrc.test");
167     assertUsages(pair("testIncludedBuildSrcClassesUsages_qualified_names.BuildSrcClass", 2),
168                  pair("testIncludedBuildSrcClassesUsages_qualified_names.IncludedBuildSrcClass", 1));
169     assertUsages("testIncludedBuildSrcClassesUsages_qualified_names.IncludedBuildClass", 2);
170   }
171
172   @Test
173   public void testIncludedBuildSrcClassesUsages_merged_qualified_names() throws Exception {
174     createProjectWithIncludedBuildAndBuildSrcModules("testIncludedBuildSrcClassesUsages_merged_qualified_names");
175     // check for qualified module names
176     getCurrentExternalProjectSettings().setUseQualifiedModuleNames(true);
177     importProjectUsingSingeModulePerGradleProject();
178     assertModules("multiproject", "multiproject.app",
179                   "multiproject.buildSrc",
180                   "gradle-plugin",
181                   "gradle-plugin.buildSrc");
182     assertUsages(pair("testIncludedBuildSrcClassesUsages_merged_qualified_names.BuildSrcClass", 2),
183                  pair("testIncludedBuildSrcClassesUsages_merged_qualified_names.IncludedBuildSrcClass", 1));
184     assertUsages("testIncludedBuildSrcClassesUsages_merged_qualified_names.IncludedBuildClass", 2);
185   }
186
187   private void createProjectWithIncludedBuildAndBuildSrcModules(@NotNull String classPackage) throws IOException {
188     createProjectSubFile("settings.gradle", "rootProject.name = 'multiproject'\n" +
189                                             "include ':app'\n" +
190                                             "includeBuild 'gradle-plugin'");
191     createProjectSubFile("buildSrc/src/main/groovy/" + classPackage + "/BuildSrcClass.groovy", "package " + classPackage + ";\n" +
192                                                                                                "public class BuildSrcClass {}");
193
194     createProjectSubFile("build.gradle", "buildscript {\n" +
195                                          "    dependencies {\n" +
196                                          "        classpath 'my.included:gradle-plugin:0'\n" +
197                                          "    }\n" +
198                                          "}\n" +
199                                          "def foo1 = new " + classPackage + ".BuildSrcClass()\n" +
200                                          "def foo2 = new " + classPackage + ".IncludedBuildClass()");
201     createProjectSubFile("app/build.gradle", "def foo1 = new " + classPackage + ".BuildSrcClass()\n" +
202                                              "def foo2 = new " + classPackage + ".IncludedBuildClass()");
203
204     // included build
205     createProjectSubFile("gradle-plugin/settings.gradle", "");
206     createProjectSubFile("gradle-plugin/build.gradle", "group 'my.included'\n" +
207                                                        "apply plugin: 'java'\n" +
208                                                        "def foo = new " + classPackage + ".IncludedBuildSrcClass()");
209     createProjectSubFile("gradle-plugin/buildSrc/src/main/groovy/" + classPackage + "/IncludedBuildSrcClass.groovy",
210                          "package " + classPackage + ";\n" +
211                          "public class IncludedBuildSrcClass {}");
212     createProjectSubFile("gradle-plugin/src/main/java/" + classPackage + "/IncludedBuildClass.java",
213                          "package " + classPackage + ";\n" +
214                          "public class IncludedBuildClass {}");
215   }
216
217   private void assertUsages(String fqn, GlobalSearchScope scope, int count) throws Exception {
218     assertUsages(fqn, null, scope, count);
219   }
220
221   private void assertUsages(@NotNull String fqn, @Nullable String methodName, GlobalSearchScope scope, int count) throws Exception {
222     PsiClass[] psiClasses = runInEdtAndGet(() -> JavaPsiFacade.getInstance(myProject).findClasses(fqn, scope));
223     assertEquals(1, psiClasses.length);
224     PsiClass aClass = psiClasses[0];
225     if (methodName != null) {
226       PsiMethod[] methods = runInEdtAndGet(() -> aClass.findMethodsByName(methodName, false));
227       List<UsageInfo> actualUsages = new ArrayList<>();
228       for (PsiMethod method : methods) {
229         actualUsages.addAll(findUsages(method));
230       }
231       assertUsagesCount(count, actualUsages);
232     }
233     else {
234       assertUsagesCount(count, aClass);
235     }
236   }
237
238   private void assertUsages(String fqn, int count) throws Exception {
239     assertUsages(fqn, GlobalSearchScope.projectScope(myProject), count);
240   }
241
242   @SafeVarargs
243   private void assertUsages(Trinity<String, GlobalSearchScope, Integer>... classUsageCount) throws Exception {
244     for (Trinity<String, GlobalSearchScope, Integer> trinity : classUsageCount) {
245       assertUsages(trinity.first, trinity.second, trinity.third);
246     }
247   }
248
249   @SafeVarargs
250   private void assertUsages(Pair<String, Integer>... classUsageCount) throws Exception {
251     for (Pair<String, Integer> pair : classUsageCount) {
252       assertUsages(Trinity.create(pair.first, GlobalSearchScope.projectScope(myProject), pair.second));
253     }
254   }
255
256   private static void assertUsagesCount(int expectedUsagesCount, PsiElement element) throws Exception {
257     assertUsagesCount(expectedUsagesCount, findUsages(element));
258   }
259
260   private static void assertUsagesCount(int expectedUsagesCount, Collection<UsageInfo> usages) throws Exception {
261     String message = "Found usges: " + runInEdtAndGet(() -> {
262       StringBuilder buf = new StringBuilder();
263       for (UsageInfo usage : usages) {
264         buf.append(usage).append(", from ").append(usage.getVirtualFile().getPath());
265         Segment navigationRange = usage.getNavigationRange();
266         if (navigationRange != null) {
267           buf.append(": ").append(usage.getNavigationRange().getStartOffset())
268             .append(",").append(usage.getNavigationRange().getEndOffset());
269         }
270         buf.append(" \n");
271       }
272
273       return buf.toString();
274     });
275     assertEquals(message, expectedUsagesCount, usages.size());
276   }
277 }