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