Merge remote-tracking branch 'origin/master' into develar/is
[idea/community.git] / java / testFramework / src / com / intellij / testFramework / InspectionTestCase.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 package com.intellij.testFramework;
17
18 import com.intellij.ToolExtensionPoints;
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.codeInspection.GlobalInspectionTool;
21 import com.intellij.codeInspection.InspectionEP;
22 import com.intellij.codeInspection.InspectionManager;
23 import com.intellij.codeInspection.LocalInspectionTool;
24 import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
25 import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
26 import com.intellij.codeInspection.deadCode.UnusedDeclarationPresentation;
27 import com.intellij.codeInspection.ex.*;
28 import com.intellij.codeInspection.reference.EntryPoint;
29 import com.intellij.codeInspection.reference.RefElement;
30 import com.intellij.openapi.application.ApplicationManager;
31 import com.intellij.openapi.application.ex.PathManagerEx;
32 import com.intellij.openapi.diagnostic.Logger;
33 import com.intellij.openapi.extensions.ExtensionPoint;
34 import com.intellij.openapi.extensions.Extensions;
35 import com.intellij.openapi.projectRoots.Sdk;
36 import com.intellij.openapi.roots.LanguageLevelProjectExtension;
37 import com.intellij.openapi.vfs.LocalFileSystem;
38 import com.intellij.openapi.vfs.VfsUtilCore;
39 import com.intellij.openapi.vfs.VirtualFile;
40 import com.intellij.pom.java.LanguageLevel;
41 import com.intellij.psi.PsiElement;
42 import com.intellij.psi.PsiManager;
43 import com.intellij.psi.util.PsiUtilCore;
44 import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests;
45 import com.intellij.util.containers.ContainerUtil;
46 import org.jdom.Element;
47 import org.jetbrains.annotations.NonNls;
48 import org.jetbrains.annotations.NotNull;
49
50 import java.io.File;
51 import java.util.ArrayList;
52 import java.util.List;
53
54 /**
55  * @author max
56  * @since Apr 11, 2002
57  */
58 @SuppressWarnings("HardCodedStringLiteral")
59 public abstract class InspectionTestCase extends PsiTestCase {
60   private static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.InspectionTestCase");
61   private EntryPoint myUnusedCodeExtension;
62   private VirtualFile ext_src;
63
64   protected static GlobalInspectionToolWrapper getUnusedDeclarationWrapper() {
65     InspectionEP ep = new InspectionEP();
66     ep.presentation = UnusedDeclarationPresentation.class.getName();
67     ep.implementationClass = UnusedDeclarationInspection.class.getName();
68     ep.shortName = UnusedDeclarationInspectionBase.SHORT_NAME;
69     return new GlobalInspectionToolWrapper(ep);
70   }
71
72   public InspectionManagerEx getManager() {
73     return (InspectionManagerEx)InspectionManager.getInstance(myProject);
74   }
75
76   public void doTest(@NonNls @NotNull String folderName, @NotNull LocalInspectionTool tool) {
77     doTest(folderName, new LocalInspectionToolWrapper(tool));
78   }
79
80   public void doTest(@NonNls @NotNull String folderName, @NotNull GlobalInspectionTool tool) {
81     doTest(folderName, new GlobalInspectionToolWrapper(tool));
82   }
83
84   public void doTest(@NonNls @NotNull String folderName, @NotNull GlobalInspectionTool tool, boolean checkRange) {
85     doTest(folderName, new GlobalInspectionToolWrapper(tool), checkRange);
86   }
87
88   public void doTest(@NonNls @NotNull String folderName, @NotNull GlobalInspectionTool tool, boolean checkRange, boolean runDeadCodeFirst) {
89     doTest(folderName, new GlobalInspectionToolWrapper(tool), "java 1.4", checkRange, runDeadCodeFirst);
90   }
91
92   public void doTest(@NonNls @NotNull String folderName, @NotNull InspectionToolWrapper tool) {
93     doTest(folderName, tool, "java 1.4");
94   }
95
96   public void doTest(@NonNls @NotNull String folderName, @NotNull InspectionToolWrapper tool, final boolean checkRange) {
97     doTest(folderName, tool, "java 1.4", checkRange);
98   }
99
100   public void doTest(@NonNls @NotNull String folderName, @NotNull LocalInspectionTool tool, @NonNls final String jdkName) {
101     doTest(folderName, new LocalInspectionToolWrapper(tool), jdkName);
102   }
103
104   public void doTest(@NonNls @NotNull String folderName, @NotNull InspectionToolWrapper tool, @NonNls final String jdkName) {
105     doTest(folderName, tool, jdkName, false);
106   }
107
108   public void doTest(@NonNls @NotNull String folderName, @NotNull InspectionToolWrapper tool, @NonNls final String jdkName, boolean checkRange) {
109     doTest(folderName, tool, jdkName, checkRange, false);
110   }
111
112   public void doTest(@NonNls @NotNull String folderName,
113                      @NotNull InspectionToolWrapper toolWrapper,
114                      @NonNls final String jdkName,
115                      boolean checkRange,
116                      boolean runDeadCodeFirst,
117                      @NotNull InspectionToolWrapper... additional) {
118     final String testDir = getTestDataPath() + "/" + folderName;
119     GlobalInspectionContextImpl context = runTool(testDir, jdkName, runDeadCodeFirst, toolWrapper, additional);
120
121     InspectionTestUtil.compareToolResults(context, toolWrapper, checkRange, testDir);
122   }
123
124   protected void runTool(@NonNls @NotNull String testDir, @NonNls final String jdkName, @NotNull InspectionToolWrapper tool) {
125     runTool(testDir, jdkName, false, tool);
126   }
127
128   protected GlobalInspectionContextImpl runTool(@NotNull final String testDir,
129                                                 final String jdkName,
130                                                 boolean runDeadCodeFirst,
131                                                 @NotNull InspectionToolWrapper toolWrapper,
132                                                 @NotNull InspectionToolWrapper... additional) {
133     final VirtualFile[] sourceDir = new VirtualFile[1];
134     ApplicationManager.getApplication().runWriteAction(() -> {
135       try {
136         setupRootModel(testDir, sourceDir, jdkName);
137       }
138       catch (Exception e) {
139         LOG.error(e);
140       }
141     });
142     VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir));
143     AnalysisScope scope = createAnalysisScope(sourceDir[0].equals(projectDir) ? projectDir : sourceDir[0].getParent());
144
145     List<InspectionToolWrapper<?, ?>> toolWrappers = new ArrayList<>();
146     if (runDeadCodeFirst) {
147       toolWrappers.add(getUnusedDeclarationWrapper());
148     }
149     toolWrappers.add(toolWrapper);
150     ContainerUtil.addAll(toolWrappers, additional);
151     GlobalInspectionContextForTests globalContext = InspectionsKt.createGlobalContextForTool(scope, getProject(), toolWrappers);
152
153     InspectionTestUtil.runTool(toolWrapper, scope, globalContext);
154     return globalContext;
155   }
156
157   @NotNull
158   protected AnalysisScope createAnalysisScope(VirtualFile sourceDir) {
159     PsiManager psiManager = PsiManager.getInstance(myProject);
160     return new AnalysisScope(psiManager.findDirectory(sourceDir));
161   }
162
163   protected void setupRootModel(@NotNull String testDir, @NotNull VirtualFile[] sourceDir, final String sdkName) {
164     VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir));
165     assertNotNull("could not find project dir " + testDir, projectDir);
166     sourceDir[0] = projectDir.findChild("src");
167     if (sourceDir[0] == null) {
168       sourceDir[0] = projectDir;
169     }
170     // IMPORTANT! The jdk must be obtained in a way it is obtained in the normal program!
171     //ProjectJdkEx jdk = ProjectJdkTable.getInstance().getInternalJdk();
172     PsiTestUtil.removeAllRoots(myModule, getTestProjectSdk());
173     PsiTestUtil.addContentRoot(myModule, projectDir);
174     PsiTestUtil.addSourceRoot(myModule, sourceDir[0]);
175     ext_src = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir + "/ext_src"));
176     if (ext_src != null) {
177       PsiTestUtil.addSourceRoot(myModule, ext_src);
178     }
179   }
180
181   @Override
182   protected void setUp() throws Exception {
183     super.setUp();
184     ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ToolExtensionPoints.DEAD_CODE_TOOL);
185     myUnusedCodeExtension = new EntryPoint() {
186       @NotNull
187       @Override
188       public String getDisplayName() {
189         return "duh";
190       }
191
192       @Override
193       public boolean isEntryPoint(@NotNull RefElement refElement, @NotNull PsiElement psiElement) {
194         return isEntryPoint(psiElement);
195       }
196
197       @Override
198       public boolean isEntryPoint(@NotNull PsiElement psiElement) {
199         return ext_src != null && VfsUtilCore.isAncestor(ext_src, PsiUtilCore.getVirtualFile(psiElement), false);
200       }
201
202       @Override
203       public boolean isSelected() {
204         return true;
205       }
206
207       @Override
208       public void setSelected(boolean selected) {
209
210       }
211
212       @Override
213       public void readExternal(Element element) {
214
215       }
216
217       @Override
218       public void writeExternal(Element element) {
219
220       }
221     };
222
223     point.registerExtension(myUnusedCodeExtension);
224   }
225
226   @Override
227   protected void tearDown() throws Exception {
228     try {
229       ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ToolExtensionPoints.DEAD_CODE_TOOL);
230       point.unregisterExtension(myUnusedCodeExtension);
231       myUnusedCodeExtension = null;
232       ext_src = null;
233     }
234     finally {
235       super.tearDown();
236     }
237   }
238
239   @Override
240   protected void setUpJdk() {
241   }
242
243   protected Sdk getTestProjectSdk() {
244     Sdk sdk = IdeaTestUtil.getMockJdk17();
245     LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
246     return sdk;
247   }
248
249   @Override
250   @NonNls
251   protected String getTestDataPath() {
252     return PathManagerEx.getTestDataPath() + "/inspection/";
253   }
254 }