LookupImpl: do not overwrite left border of injection on lookup insertion DBE-2607
[idea/community.git] / java / java-tests / testSrc / com / intellij / codeInspection / ex / InspectionProfileTest.java
1 /*
2  * Copyright 2000-2015 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.codeInspection.ex;
17
18 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
19 import com.intellij.codeInspection.InspectionManager;
20 import com.intellij.codeInspection.LocalInspectionEP;
21 import com.intellij.codeInspection.LocalInspectionTool;
22 import com.intellij.codeInspection.ModifiableModel;
23 import com.intellij.codeInspection.dataFlow.DataFlowInspection;
24 import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
25 import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
26 import com.intellij.openapi.util.JDOMUtil;
27 import com.intellij.openapi.util.WriteExternalException;
28 import com.intellij.profile.Profile;
29 import com.intellij.profile.codeInspection.InspectionProfileManager;
30 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
31 import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable;
32 import com.intellij.psi.PsiModifier;
33 import com.intellij.testFramework.LightIdeaTestCase;
34 import org.jdom.Element;
35 import org.jdom.JDOMException;
36 import org.jetbrains.annotations.NotNull;
37
38 import java.io.IOException;
39 import java.util.ArrayList;
40 import java.util.List;
41
42 import static com.intellij.testFramework.PlatformTestUtil.assertElementsEqual;
43
44 /**
45  * @author Anna.Kozlova
46  * Date: 18-Aug-2006
47  */
48 public class InspectionProfileTest extends LightIdeaTestCase {
49   private static final String PROFILE = "ToConvert";
50
51   @Override
52   protected void setUp() throws Exception {
53     //noinspection AssignmentToStaticFieldFromInstanceMethod
54     InspectionProfileImpl.INIT_INSPECTIONS = true;
55     super.setUp();
56     InspectionToolRegistrar.getInstance().createTools();
57   }
58
59   @Override
60   protected void tearDown() throws Exception {
61     super.tearDown();
62     //noinspection AssignmentToStaticFieldFromInstanceMethod
63     InspectionProfileImpl.INIT_INSPECTIONS = false;
64     InspectionProfileManager.getInstance().deleteProfile(PROFILE);
65   }
66
67   public void testCopyProjectProfile() throws Exception {
68     final Element element = loadProfile();
69     final InspectionProfileImpl profile = createProfile();
70     profile.readExternal(element);
71     final ModifiableModel model = profile.getModifiableModel();
72     model.commit();
73     final Element copy = new Element("inspections");
74     profile.writeExternal(copy);
75     assertElementsEqual(element, copy);
76   }
77
78   private static InspectionProfileImpl createProfile() {
79     return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getDefaultProfile());
80   }
81   private static InspectionProfileImpl createProfile(@NotNull InspectionProfileImpl base) {
82     return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), base);
83   }
84
85   public void testSameNameSharedProfile() throws Exception {
86     InspectionProfileManager profileManager = InspectionProfileManager.getInstance();
87     InspectionProfileImpl localProfile = createProfile();
88     profileManager.updateProfile(localProfile);
89
90     InspectionProjectProfileManager projectProfileManager = InspectionProjectProfileManager.getInstance(getProject());
91     try {
92       //normally on open project profile wrappers are init for both managers
93       profileManager.updateProfile(localProfile);
94       InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), projectProfileManager,
95                                                                 InspectionProfileImpl.getDefaultProfile());
96       projectProfileManager.updateProfile(profile);
97       projectProfileManager.setProjectProfile(profile.getName());
98
99       assertTrue(projectProfileManager.getInspectionProfile() == profile);
100     }
101     finally {
102       projectProfileManager.deleteProfile(PROFILE);
103     }
104   }
105
106   public void testConvertOldProfile() throws Exception {
107     Element element = JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
108                                             "  <option name=\"myName\" value=\"ToConvert\" />\n" +
109                                             "  <inspection_tool class=\"JavaDoc\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
110                                             "    <option name=\"TOP_LEVEL_CLASS_OPTIONS\">\n" +
111                                             "      <value>\n" +
112                                             "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
113                                             "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
114                                             "      </value>\n" +
115                                             "    </option>\n" +
116                                             "    <option name=\"INNER_CLASS_OPTIONS\">\n" +
117                                             "      <value>\n" +
118                                             "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
119                                             "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
120                                             "      </value>\n" +
121                                             "    </option>\n" +
122                                             "    <option name=\"METHOD_OPTIONS\">\n" +
123                                             "      <value>\n" +
124                                             "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
125                                             "        <option name=\"REQUIRED_TAGS\" value=\"@return@param@throws or @exception\" />\n" +
126                                             "      </value>\n" + "    </option>\n" +
127                                             "    <option name=\"FIELD_OPTIONS\">\n" +
128                                             "      <value>\n" +
129                                             "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
130                                             "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
131                                             "      </value>\n" +
132                                             "    </option>\n" +
133                                             "    <option name=\"IGNORE_DEPRECATED\" value=\"false\" />\n" +
134                                             "    <option name=\"IGNORE_JAVADOC_PERIOD\" value=\"false\" />\n" +
135                                             "    <option name=\"IGNORE_DUPLICATED_THROWS\" value=\"false\" />\n" +
136                                             "    <option name=\"IGNORE_POINT_TO_ITSELF\" value=\"false\" />\n" +
137                                             "    <option name=\"myAdditionalJavadocTags\" value=\"tag1,tag2 \" />\n" +
138                                             "  </inspection_tool>\n" +
139                                             "</inspections>").getRootElement();
140     InspectionProfileImpl profile = createProfile();
141     profile.readExternal(element);
142     ModifiableModel model = profile.getModifiableModel();
143     model.commit();
144
145     Element copy = new Element("inspections");
146     profile.writeExternal(copy);
147     assertElementsEqual(loadProfile(), copy);
148   }
149
150   private static Element loadProfile() throws IOException, JDOMException {
151     return JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
152                                  "  <option name=\"myName\" value=\"ToConvert\" />\n" +
153                                  "  <inspection_tool class=\"JavaDoc\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
154                                  "    <option name=\"TOP_LEVEL_CLASS_OPTIONS\">\n" +
155                                  "      <value>\n" +
156                                  "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
157                                  "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
158                                  "      </value>\n" +
159                                  "    </option>\n" +
160                                  "    <option name=\"INNER_CLASS_OPTIONS\">\n" +
161                                  "      <value>\n" +
162                                  "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
163                                  "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
164                                  "      </value>\n" +
165                                  "    </option>\n" +
166                                  "    <option name=\"METHOD_OPTIONS\">\n" +
167                                  "      <value>\n" +
168                                  "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
169                                  "        <option name=\"REQUIRED_TAGS\" value=\"@return@param@throws or @exception\" />\n" +
170                                  "      </value>\n" + "    </option>\n" +
171                                  "    <option name=\"FIELD_OPTIONS\">\n" +
172                                  "      <value>\n" +
173                                  "        <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n" +
174                                  "        <option name=\"REQUIRED_TAGS\" value=\"\" />\n" +
175                                  "      </value>\n" +
176                                  "    </option>\n" +
177                                  "    <option name=\"IGNORE_DEPRECATED\" value=\"false\" />\n" +
178                                  "    <option name=\"IGNORE_JAVADOC_PERIOD\" value=\"false\" />\n" +
179                                  "    <option name=\"IGNORE_DUPLICATED_THROWS\" value=\"false\" />\n" +
180                                  "    <option name=\"IGNORE_POINT_TO_ITSELF\" value=\"false\" />\n" +
181                                  "    <option name=\"myAdditionalJavadocTags\" value=\"tag1,tag2 \" />\n" +
182                                  "  </inspection_tool>\n" +
183                                  "</inspections>").getRootElement();
184   }
185
186   public void testReloadProfileWithUnknownScopes() throws Exception {
187     final Element element = JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
188                                                   "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
189                                                   "  <inspection_tool class=\"ArgNamesErrorsInspection\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +
190                                                   "  <inspection_tool class=\"ArgNamesWarningsInspection\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\" />\n" +
191                                                   "  <inspection_tool class=\"AroundAdviceStyleInspection\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\" />\n" +
192                                                   "  <inspection_tool class=\"DeclareParentsInspection\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +
193                                                   /*"  <inspection_tool class=\"ManifestDomInspection\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +*/
194                                                   "  <inspection_tool class=\"MissingAspectjAutoproxyInspection\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\" />\n" +
195                                                   "  <inspection_tool class=\"UNUSED_IMPORT\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
196                                                   "    <scope name=\"Unknown scope name\" level=\"WARNING\" enabled=\"true\" />\n" +
197                                                   "  </inspection_tool>\n" +
198                                                   "</inspections>").getRootElement();
199     final InspectionProfileImpl profile = createProfile();
200     profile.readExternal(element);
201     final ModifiableModel model = profile.getModifiableModel();
202     model.commit();
203     final Element copy = new Element("inspections");
204     profile.writeExternal(copy);
205     assertElementsEqual(element, copy);
206   }
207
208   public void testMergeUnusedDeclarationAndUnusedSymbol() throws Exception {
209     //no specific settings
210     final Element element = JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
211                                                   "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
212                                                   "</inspections>").getRootElement();
213     InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
214     profile.readExternal(element);
215     ModifiableModel model = profile.getModifiableModel();
216     model.commit();
217     final Element copy = new Element("inspections");
218     profile.writeExternal(copy);
219     assertElementsEqual(element, copy);
220
221
222     //settings to merge
223     final Element unusedProfile = JDOMUtil.loadDocument("<inspections version=\"1.0\">\n" +
224                                                         "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
225                                                         "  <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
226                                                         "      <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
227                                                         "      <option name=\"FIELD\" value=\"true\" />\n" +
228                                                         "      <option name=\"METHOD\" value=\"true\" />\n" +
229                                                         "      <option name=\"CLASS\" value=\"true\" />\n" +
230                                                         "      <option name=\"PARAMETER\" value=\"true\" />\n" +
231                                                         "      <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
232                                                         "  </inspection_tool>\n" +
233                                                         "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
234                                                         "      <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
235                                                         "      <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
236                                                         "      <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
237                                                         "      <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
238                                                         "   </inspection_tool>\n" +
239                                                         "</inspections>").getRootElement();
240     profile.readExternal(unusedProfile);
241     model = profile.getModifiableModel();
242     model.commit();
243     assertEquals("<profile version=\"1.0\">\n" +
244                  "  <option name=\"myName\" value=\"ToConvert\" />\n" +
245                  "  <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
246                  "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
247                  "    <option name=\"FIELD\" value=\"true\" />\n" +
248                  "    <option name=\"METHOD\" value=\"true\" />\n" +
249                  "    <option name=\"CLASS\" value=\"true\" />\n" +
250                  "    <option name=\"PARAMETER\" value=\"true\" />\n" +
251                  "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
252                  "  </inspection_tool>\n" +
253                  "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
254                  "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
255                  "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
256                  "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
257                  "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
258                  "  </inspection_tool>\n" +
259                  "</profile>", serialize(profile));
260
261     //make them default
262     profile = createProfile(new InspectionProfileImpl("foo"));
263     profile.readExternal(unusedProfile);
264     model = profile.getModifiableModel();
265     InspectionToolWrapper toolWrapper = ((InspectionProfileImpl)model).getInspectionTool("unused", getProject());
266     UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool();
267     tool.ADD_NONJAVA_TO_ENTRIES = true;
268     UnusedSymbolLocalInspectionBase inspectionTool = tool.getSharedLocalInspectionTool();
269     inspectionTool.setParameterVisibility(PsiModifier.PUBLIC);
270     model.commit();
271     String mergedText = "<profile version=\"1.0\">\n" +
272                         "  <option name=\"myName\" value=\"ToConvert\" />\n" +
273                         "  <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
274                         "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
275                         "    <option name=\"FIELD\" value=\"true\" />\n" +
276                         "    <option name=\"METHOD\" value=\"true\" />\n" +
277                         "    <option name=\"CLASS\" value=\"true\" />\n" +
278                         "    <option name=\"PARAMETER\" value=\"true\" />\n" +
279                         "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
280                         "  </inspection_tool>\n" +
281                         "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
282                         "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
283                         "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
284                         "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
285                         "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
286                         "  </inspection_tool>\n" +
287                         "  <inspection_tool class=\"unusedMerged\" />\n" +
288                         "</profile>";
289     assertEquals(mergedText, serialize(profile));
290
291     Element toImportElement = new Element("profile");
292     profile.writeExternal(toImportElement);
293     final InspectionProfileImpl importedProfile =
294       InspectionToolsConfigurable.importInspectionProfile(toImportElement, InspectionProfileManager.getInstance(), getProject(), null);
295
296     //check merged
297     Element mergedElement = JDOMUtil.loadDocument(mergedText).getRootElement();
298     profile = createProfile(new InspectionProfileImpl("foo"));
299     profile.readExternal(mergedElement);
300     model = profile.getModifiableModel();
301     model.commit();
302     Element copyMerged = new Element("profile");
303     profile.writeExternal(copyMerged);
304     assertElementsEqual(mergedElement, copyMerged);
305
306     Element imported = new Element("profile");
307     importedProfile.writeExternal(imported);
308     assertElementsEqual(mergedElement, imported);
309   }
310
311   public void testStoredMemberVisibility() throws Exception {
312     InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
313     profile.readExternal(JDOMUtil.loadDocument("<profile version=\"1.0\">\n" +
314                                                "  <inspection_tool class=\"unused\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
315                                                "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
316                                                "    <option name=\"FIELD\" value=\"true\" />\n" +
317                                                "    <option name=\"METHOD\" value=\"true\" />\n" +
318                                                "    <option name=\"CLASS\" value=\"true\" />\n" +
319                                                "    <option name=\"PARAMETER\" value=\"true\" />\n" +
320                                                "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"true\" />\n" +
321                                                "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
322                                                "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
323                                                "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
324                                                "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
325                                                "  </inspection_tool>\n" +
326                                                "</profile>").getRootElement());
327     InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel();
328     InspectionToolWrapper toolWrapper = model.getInspectionTool("unused", getProject());
329     UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool();
330     UnusedSymbolLocalInspectionBase inspectionTool = tool.getSharedLocalInspectionTool();
331     inspectionTool.setClassVisibility("none");
332     model.commit();
333     String mergedText = "<profile version=\"1.0\">\n" +
334                         "  <option name=\"myName\" value=\"ToConvert\" />\n" +
335                         "  <inspection_tool class=\"unused\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" inner_class=\"none\">\n" +
336                         "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
337                         "    <option name=\"FIELD\" value=\"true\" />\n" +
338                         "    <option name=\"METHOD\" value=\"true\" />\n" +
339                         "    <option name=\"CLASS\" value=\"false\" />\n" +
340                         "    <option name=\"PARAMETER\" value=\"true\" />\n" +
341                         "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"true\" />\n" +
342                         "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
343                         "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
344                         "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
345                         "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
346                         "  </inspection_tool>\n" +
347                         "</profile>";
348     assertEquals(mergedText, serialize(profile));
349   }
350
351   public void testDisabledUnusedDeclarationWithoutChanges() throws Exception {
352     checkMergedNoChanges("<profile version=\"1.0\">\n" +
353                          "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
354                          "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
355                          "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
356                          "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
357                          "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
358                          "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"true\" />\n" +
359                          "  </inspection_tool>\n" +
360                          "</profile>");
361   }
362
363   public void testDisabledUnusedDeclarationWithChanges() throws Exception {
364     checkMergedNoChanges("<profile version=\"1.0\">\n" +
365                          "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
366                          "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
367                          "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
368                          "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
369                          "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
370                          "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
371                          "  </inspection_tool>\n" +
372                          "</profile>");
373   }
374
375   public void testEnabledUnusedDeclarationWithChanges() throws Exception {
376     checkMergedNoChanges("<profile version=\"1.0\">\n" +
377                          "  <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
378                          "  <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
379                          "    <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
380                          "    <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
381                          "    <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
382                          "    <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
383                          "  </inspection_tool>\n" +
384                          "</profile>");
385   }
386
387   public void testDisabledUnusedSymbolWithoutChanges() throws Exception {
388     checkMergedNoChanges("<profile version=\"1.0\">\n" +
389                          "  <option name=\"myName\" value=\"" +
390                          PROFILE +
391                          "\" />\n" +
392                          "  <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
393                          "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
394                          "    <option name=\"FIELD\" value=\"true\" />\n" +
395                          "    <option name=\"METHOD\" value=\"true\" />\n" +
396                          "    <option name=\"CLASS\" value=\"true\" />\n" +
397                          "    <option name=\"PARAMETER\" value=\"true\" />\n" +
398                          "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"true\" />\n" +
399                          "  </inspection_tool>\n" +
400                          "</profile>");
401   }
402
403   public void testEnabledUnusedSymbolWithChanges() throws Exception {
404     checkMergedNoChanges("<profile version=\"1.0\">\n" +
405                          "  <option name=\"myName\" value=\"" +
406                          PROFILE +
407                          "\" />\n" +
408                          "  <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
409                          "    <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
410                          "    <option name=\"FIELD\" value=\"true\" />\n" +
411                          "    <option name=\"METHOD\" value=\"true\" />\n" +
412                          "    <option name=\"CLASS\" value=\"true\" />\n" +
413                          "    <option name=\"PARAMETER\" value=\"true\" />\n" +
414                          "    <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
415                          "  </inspection_tool>\n" +
416                          "</profile>");
417   }
418
419   private void checkMergedNoChanges(String initialText) throws Exception {
420     final Element element = JDOMUtil.loadDocument(initialText).getRootElement();
421     InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo"));
422     profile.readExternal(element);
423     ModifiableModel model = profile.getModifiableModel();
424     model.commit();
425     assertEquals(initialText, serialize(profile));
426   }
427
428   public void testLockProfile() throws Exception {
429     final List<InspectionToolWrapper> list = new ArrayList<InspectionToolWrapper>();
430     list.add(createTool("foo", true));
431
432     InspectionToolRegistrar registrar = new InspectionToolRegistrar() {
433       @NotNull
434       @Override
435       public List<InspectionToolWrapper> createTools() {
436         return list;
437       }
438     };
439
440     InspectionProfileImpl profile = createProfile(registrar);
441
442     List<ScopeToolState> tools = profile.getAllTools(getProject());
443     assertEquals(1, tools.size());
444     assertTrue(profile.isToolEnabled(HighlightDisplayKey.find("foo")));
445     assertTrue(profile.getToolDefaultState("foo", getProject()).isEnabled());
446
447     InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel();
448     model.lockProfile(true);
449     model.initInspectionTools(getProject()); // todo commit should take care of initialization
450     model.commit();
451
452     assertEquals("<profile version=\"1.0\" is_locked=\"true\">\n" +
453                  "  <option name=\"myName\" value=\"Foo\" />\n" +
454                  "  <inspection_tool class=\"foo\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\" />\n" +
455                  "</profile>",
456                  serialize(profile));
457
458     Element element = new Element("element");
459     profile.writeExternal(element);
460
461     list.add(createTool("bar", true));
462     list.add(createTool("disabled", false));
463
464     profile = createProfile(registrar);
465     profile.readExternal(element);
466
467     tools = profile.getAllTools(getProject());
468     assertEquals(3, tools.size());
469
470     assertTrue(profile.isProfileLocked());
471     assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("bar")));
472     assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("disabled")));
473
474     assertTrue(profile.getToolDefaultState("bar", getProject()).isEnabled());
475     assertFalse(profile.getToolDefaultState("disabled", getProject()).isEnabled());
476
477     assertEquals("<profile version=\"1.0\" is_locked=\"true\">\n" +
478                  "  <option name=\"myName\" value=\"Foo\" />\n" +
479                  "  <inspection_tool class=\"bar\" enabled=\"false\" level=\"ERROR\" enabled_by_default=\"true\" />\n" +
480                  "  <inspection_tool class=\"disabled\" enabled=\"false\" level=\"ERROR\" enabled_by_default=\"false\" />\n" +
481                  "  <inspection_tool class=\"foo\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\" />\n" +
482                  "</profile>", serialize(profile));
483   }
484
485   private static String serialize(InspectionProfileImpl profile) throws WriteExternalException {
486     Element element = new Element("profile");
487     profile.writeExternal(element);
488     return JDOMUtil.writeElement(element);
489   }
490
491   private static InspectionProfileImpl createProfile(InspectionToolRegistrar registrar) {
492     InspectionProfileImpl base = new InspectionProfileImpl("Base", registrar, InspectionProfileManager.getInstance(), null);
493     return new InspectionProfileImpl("Foo", registrar, InspectionProfileManager.getInstance(), base);
494   }
495
496   public void testGlobalInspectionContext() throws Exception {
497     InspectionProfileImpl profile = new InspectionProfileImpl("Foo");
498     profile.disableAllTools(getProject());
499     profile.enableTool(new UnusedDeclarationInspectionBase(true).getShortName(), getProject());
500
501     GlobalInspectionContextImpl context = ((InspectionManagerEx)InspectionManager.getInstance(getProject())).createNewGlobalContext(false);
502     context.setExternalProfile(profile);
503     context.initializeTools(new ArrayList<Tools>(), new ArrayList<Tools>(), new ArrayList<Tools>());
504   }
505
506   public void testInspectionsInitialization() throws Exception {
507
508     InspectionProfileImpl foo = new InspectionProfileImpl("foo");
509     assertEquals(0, countInitializedTools(foo));
510     foo.initInspectionTools(getProject());
511     assertEquals(0, countInitializedTools(foo));
512
513     ModifiableModel model = foo.getModifiableModel();
514     assertEquals(0, countInitializedTools(model));
515     model.commit();
516     assertEquals(0, countInitializedTools(model));
517     assertEquals(0, countInitializedTools(foo));
518
519     model = foo.getModifiableModel();
520     assertEquals(0, countInitializedTools(model));
521     List<ScopeToolState> tools = ((InspectionProfileImpl)model).getAllTools(getProject());
522     for (ScopeToolState tool : tools) {
523       if (!tool.isEnabled()) {
524         tool.setEnabled(true);
525       }
526     }
527     model.commit();
528     assertEquals(0, countInitializedTools(model));
529   }
530
531   public void testDoNotInstantiateOnSave() throws Exception {
532     InspectionProfileImpl profile = new InspectionProfileImpl("profile", InspectionToolRegistrar.getInstance(), InspectionProfileManager.getInstance(), InspectionProfileImpl.getDefaultProfile());
533     assertEquals(0, countInitializedTools(profile));
534     InspectionToolWrapper[] toolWrappers = profile.getInspectionTools(null);
535     assertTrue(toolWrappers.length > 0);
536     InspectionToolWrapper toolWrapper = profile.getInspectionTool(new DataFlowInspection().getShortName(), getProject());
537     assertNotNull(toolWrapper);
538     String id = toolWrapper.getShortName();
539     System.out.println(id);
540     if (profile.isToolEnabled(HighlightDisplayKey.findById(id))) {
541       profile.disableTool(id, getProject());
542     }
543     else {
544       profile.enableTool(id, getProject());
545     }
546     assertEquals(0, countInitializedTools(profile));
547     profile.writeExternal(new Element("profile"));
548     List<InspectionToolWrapper> initializedTools = getInitializedTools(profile);
549     if (initializedTools.size() > 0) {
550       for (InspectionToolWrapper initializedTool : initializedTools) {
551         System.out.println(initializedTool.getShortName());
552       }
553       fail();
554     }
555   }
556
557   public void testInspectionInitializationForSerialization() throws Exception {
558     InspectionProfileImpl foo = new InspectionProfileImpl("foo");
559     foo.readExternal(JDOMUtil.loadDocument("<profile version=\"1.0\">\n" +
560                                            "    <option name=\"myName\" value=\"idea.default\" />\n" +
561                                            "    <inspection_tool class=\"AbstractMethodCallInConstructor\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
562                                            "    <inspection_tool class=\"AssignmentToForLoopParameter\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
563                                            "      <option name=\"m_checkForeachParameters\" value=\"false\" />\n" +
564                                            "    </inspection_tool>\n" +
565                                            "</profile>").getRootElement());
566     foo.initInspectionTools(getProject());
567     assertEquals(1, countInitializedTools(foo));
568   }
569
570   public void testPreserveCompatibility() throws Exception {
571     InspectionProfileImpl foo = new InspectionProfileImpl("foo", InspectionToolRegistrar.getInstance(), InspectionProjectProfileManager.getInstance(getProject()));
572     String test = "<profile version=\"1.0\" is_locked=\"false\">\n" +
573                  "  <option name=\"myName\" value=\"idea.default\" />\n" +
574                  "  <option name=\"myLocal\" value=\"false\" />\n" +
575                  "  <inspection_tool class=\"AbstractMethodCallInConstructor\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
576                  "  <inspection_tool class=\"AssignmentToForLoopParameter\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n" +
577                  "    <option name=\"m_checkForeachParameters\" value=\"false\" />\n" +
578                  "  </inspection_tool>\n" +
579                  "</profile>";
580     foo.readExternal(JDOMUtil.loadDocument(test).getRootElement());
581     foo.initInspectionTools(getProject());
582     Element serialized = new Element("profile");
583     foo.writeExternal(serialized);
584     assertEquals(test, JDOMUtil.writeElement(serialized));
585   }
586
587   public static int countInitializedTools(Profile foo) {
588     return getInitializedTools(foo).size();
589   }
590
591   @NotNull
592   public static List<InspectionToolWrapper> getInitializedTools(@NotNull Profile foo) {
593     List<InspectionToolWrapper> initialized = new ArrayList<InspectionToolWrapper>();
594     List<ScopeToolState> tools = ((InspectionProfileImpl)foo).getAllTools(getProject());
595     for (ScopeToolState tool : tools) {
596       InspectionToolWrapper toolWrapper = tool.getTool();
597       if (toolWrapper.isInitialized()) {
598         initialized.add(toolWrapper);
599       }
600     }
601     return initialized;
602   }
603
604   private static LocalInspectionToolWrapper createTool(String s, boolean enabled) {
605     LocalInspectionEP foo = new LocalInspectionEP();
606     foo.shortName = s;
607     foo.displayName = s;
608     foo.groupDisplayName = s;
609     foo.level = "ERROR";
610     foo.enabledByDefault = enabled;
611     foo.implementationClass = TestTool.class.getName();
612     return new LocalInspectionToolWrapper(foo);
613   }
614
615   @SuppressWarnings("InspectionDescriptionNotFoundInspection")
616   public static class TestTool extends LocalInspectionTool {
617
618   }
619 }