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