/* * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.codeInspection.ex; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.LocalInspectionEP; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.dataFlow.DataFlowInspection; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase; import com.intellij.openapi.util.JDOMUtil; import com.intellij.profile.codeInspection.BaseInspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.ProjectInspectionProfileManager; import com.intellij.profile.codeInspection.ui.header.InspectionProfileSchemesPanel; import com.intellij.psi.PsiModifier; import com.intellij.testFramework.InspectionsKt; import com.intellij.testFramework.LightIdeaTestCase; import com.intellij.util.JdomKt; import com.intellij.util.SmartList; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Supplier; import static com.intellij.testFramework.assertions.Assertions.assertThat; public class InspectionProfileTest extends LightIdeaTestCase { private static final String PROFILE = "ToConvert"; @Override protected void setUp() throws Exception { //noinspection AssignmentToStaticFieldFromInstanceMethod InspectionProfileImpl.INIT_INSPECTIONS = true; super.setUp(); InspectionToolRegistrar.getInstance().createTools(); } @Override protected void tearDown() throws Exception { try { //noinspection SuperTearDownInFinally super.tearDown(); } finally { //noinspection AssignmentToStaticFieldFromInstanceMethod InspectionProfileImpl.INIT_INSPECTIONS = false; getApplicationProfileManager().deleteProfile(PROFILE); } } @NotNull private static BaseInspectionProfileManager getApplicationProfileManager() { return (BaseInspectionProfileManager)InspectionProfileManager.getInstance(); } public void testCopyProjectProfile() throws Exception { final Element element = loadProfile(); final InspectionProfileImpl profile = createProfile(); profile.readExternal(element); profile.getModifiableModel().commit(); assertThat(profile.writeScheme()).isEqualTo(element); } private static InspectionProfileImpl createProfile() { return createProfile(InspectionProfileKt.getBASE_PROFILE()); } private static InspectionProfileImpl createProfile(@NotNull InspectionProfileImpl base) { return new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), base); } public void testSameNameSharedProfile() throws Exception { BaseInspectionProfileManager profileManager = getApplicationProfileManager(); InspectionProfileImpl localProfile = createProfile(); updateProfile(profileManager, localProfile); ProjectInspectionProfileManager projectProfileManager = ProjectInspectionProfileManager.getInstance(getProject()); try { //normally on open project profile wrappers are init for both managers updateProfile(profileManager, localProfile); InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE, InspectionToolRegistrar.getInstance(), projectProfileManager, null); updateProfile(projectProfileManager, profile); projectProfileManager.setRootProfile(profile.getName()); assertTrue(projectProfileManager.getCurrentProfile() == profile); } finally { projectProfileManager.deleteProfile(PROFILE); } } private static void updateProfile(BaseInspectionProfileManager profileManager, InspectionProfileImpl localProfile) { profileManager.addProfile(localProfile); profileManager.fireProfileChanged(localProfile); } public void testConvertOldProfile() throws Exception { Element element = JdomKt.loadElement("\n" + " "); InspectionProfileImpl profile = createProfile(); profile.readExternal(element); profile.getModifiableModel().commit(); assertThat(profile.writeScheme()).isEqualTo(loadProfile()); } private static Element loadProfile() throws IOException, JDOMException { return JdomKt.loadElement("\n" + " "); } public void testReloadProfileWithUnknownScopes() throws Exception { final Element element = JdomKt.loadElement("\n" + " "); final InspectionProfileImpl profile = createProfile(); profile.readExternal(element); profile.getModifiableModel().commit(); assertThat(profile.writeScheme()).isEqualTo(element); } public void testMergeUnusedDeclarationAndUnusedSymbol() throws Exception { //no specific settings final Element element = JdomKt.loadElement("\n" + " "); InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo")); profile.readExternal(element); profile.getModifiableModel().commit(); assertThat(profile.writeScheme()).isEqualTo(element); //settings to merge final Element unusedProfile = JdomKt.loadElement("\n" + " "); profile.readExternal(unusedProfile); profile.getModifiableModel().commit(); assertEquals("\n" + " ", serialize(profile)); //make them default profile = createProfile(new InspectionProfileImpl("foo")); profile.readExternal(unusedProfile); profile.modifyProfile(it -> { InspectionToolWrapper toolWrapper = it.getInspectionTool("unused", getProject()); UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool(); tool.ADD_NONJAVA_TO_ENTRIES = true; UnusedSymbolLocalInspectionBase inspectionTool = tool.getSharedLocalInspectionTool(); inspectionTool.setParameterVisibility(PsiModifier.PUBLIC); }); String mergedText = "\n" + " "; assertEquals(mergedText, serialize(profile)); Element toImportElement = profile.writeScheme(); final InspectionProfileImpl importedProfile = InspectionProfileSchemesPanel.importInspectionProfile(toImportElement, getApplicationProfileManager(), getProject()); //check merged Element mergedElement = JdomKt.loadElement(mergedText); profile = createProfile(new InspectionProfileImpl("foo")); profile.readExternal(mergedElement); profile.getModifiableModel().commit(); assertThat(profile.writeScheme()).isEqualTo(mergedElement); assertThat(importedProfile.writeScheme()).isEqualTo(mergedElement); } public void testStoredMemberVisibility() throws Exception { InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo")); profile.readExternal(JdomKt.loadElement("\n" + " \n" + " \n" + "")); profile.modifyProfile(it -> { InspectionToolWrapper toolWrapper = it.getInspectionTool("unused", getProject()); UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool(); UnusedSymbolLocalInspectionBase inspectionTool = tool.getSharedLocalInspectionTool(); inspectionTool.setClassVisibility(PsiModifier.PUBLIC); inspectionTool.CLASS = false; }); String mergedText = "\n" + " "; assertEquals(mergedText, serialize(profile)); } public void testDisabledUnusedDeclarationWithoutChanges() throws Exception { checkMergedNoChanges("\n" + " "); } public void testMergedMalformedSetUpTearDownInspections() throws Exception { checkMergedNoChanges("\n" + " "); checkMergedNoChanges("\n" + " "); } public void testMergedMethodDoesntCallSuperMethodInspections() throws Exception { checkMergedNoChanges("\n" + " "); } public void testMergedThrowableNotThrownInspections() throws Exception { checkMergedNoChanges("\n" + " "); checkMergedNoChanges("\n" + " "); } public void testMergedCallToSuspiciousStringMethodInspections() throws Exception { checkMergedNoChanges("\n" + " " ); } public void testMergedMisspelledInspections() throws Exception { checkMergedNoChanges("\n" + " "); checkMergedNoChanges("\n" + " "); } public void testDisabledUnusedDeclarationWithChanges() throws Exception { checkMergedNoChanges("\n" + " "); } public void testEnabledUnusedDeclarationWithChanges() throws Exception { checkMergedNoChanges("\n" + " "); } public void testDisabledUnusedSymbolWithoutChanges() throws Exception { checkMergedNoChanges("\n" + " "); } public void testEnabledUnusedSymbolWithChanges() throws Exception { checkMergedNoChanges("\n" + " "); } private static void checkMergedNoChanges(String initialText) throws Exception { final Element element = JdomKt.loadElement(initialText); InspectionProfileImpl profile = createProfile(new InspectionProfileImpl("foo")); profile.readExternal(element); profile.getModifiableModel().commit(); assertEquals(initialText, serialize(profile)); } public void testLockProfile() throws Exception { final List list = new ArrayList<>(); list.add(createTool("foo", true)); Supplier> toolSupplier = () -> list; InspectionProfileImpl profile = createProfile(toolSupplier); List tools = profile.getAllTools(); assertEquals(1, tools.size()); assertTrue(profile.isToolEnabled(HighlightDisplayKey.find("foo"))); assertTrue(profile.getToolDefaultState("foo", getProject()).isEnabled()); profile.modifyProfile(it -> { it.lockProfile(true); it.initInspectionTools(getProject()); // todo commit should take care of initialization }); assertEquals("\n" + " ", serialize(profile)); Element element = profile.writeScheme(); list.add(createTool("bar", true)); list.add(createTool("disabled", false)); profile = createProfile(toolSupplier); profile.readExternal(element); tools = profile.getAllTools(); assertEquals(3, tools.size()); assertTrue(profile.isProfileLocked()); assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("bar"))); assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("disabled"))); assertFalse(profile.getToolDefaultState("bar", getProject()).isEnabled()); assertFalse(profile.getToolDefaultState("disabled", getProject()).isEnabled()); assertEquals("\n" + " ", serialize(profile)); } private static String serialize(InspectionProfileImpl profile) { return JDOMUtil.writeElement(profile.writeScheme()); } private static InspectionProfileImpl createProfile(@NotNull Supplier> toolSupplier) { InspectionProfileImpl base = new InspectionProfileImpl("Base", toolSupplier, (InspectionProfileImpl)null); return new InspectionProfileImpl("Foo", toolSupplier, base); } public void testGlobalInspectionContext() throws Exception { InspectionProfileImpl profile = new InspectionProfileImpl("Foo"); InspectionsKt.disableAllTools(profile); profile.enableTool(new UnusedDeclarationInspectionBase(true).getShortName(), getProject()); GlobalInspectionContextImpl context = ((InspectionManagerEx)InspectionManager.getInstance(getProject())).createNewGlobalContext(false); context.setExternalProfile(profile); context.initializeTools(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } public void testInspectionsInitialization() throws Exception { InspectionProfileImpl foo = new InspectionProfileImpl("foo"); assertEquals(0, countInitializedTools(foo)); foo.initInspectionTools(getProject()); assertEquals(0, countInitializedTools(foo)); InspectionProfileModifiableModel model = foo.getModifiableModel(); assertEquals(0, countInitializedTools(model)); model.commit(); assertEquals(0, countInitializedTools(model)); assertEquals(0, countInitializedTools(foo)); model = foo.getModifiableModel(); assertEquals(0, countInitializedTools(model)); List tools = model.getAllTools(); for (ScopeToolState tool : tools) { if (!tool.isEnabled()) { tool.setEnabled(true); } } model.commit(); assertEquals(0, countInitializedTools(model)); } public void testDoNotInstantiateOnSave() throws Exception { InspectionProfileImpl profile = new InspectionProfileImpl("profile", InspectionToolRegistrar.getInstance(), InspectionProfileKt.getBASE_PROFILE()); assertEquals(0, countInitializedTools(profile)); InspectionToolWrapper[] toolWrappers = profile.getInspectionTools(null); assertTrue(toolWrappers.length > 0); InspectionToolWrapper toolWrapper = profile.getInspectionTool(new DataFlowInspection().getShortName(), getProject()); assertNotNull(toolWrapper); String id = toolWrapper.getShortName(); System.out.println(id); profile.setToolEnabled(id, !profile.isToolEnabled(HighlightDisplayKey.findById(id))); assertThat(countInitializedTools(profile)).isEqualTo(0); profile.writeScheme(); List initializedTools = getInitializedTools(profile); if (initializedTools.size() > 0) { for (InspectionToolWrapper initializedTool : initializedTools) { System.out.println(initializedTool.getShortName()); } fail(); } } public void testInspectionInitializationForSerialization() throws Exception { InspectionProfileImpl foo = new InspectionProfileImpl("foo"); foo.readExternal(JdomKt.loadElement("\n" + " ")); foo.initInspectionTools(getProject()); assertEquals(1, countInitializedTools(foo)); } public static int countInitializedTools(@NotNull InspectionProfileImpl foo) { return getInitializedTools(foo).size(); } @NotNull public static List getInitializedTools(@NotNull InspectionProfileImpl foo) { List initialized = null; List tools = foo.getAllTools(); for (ScopeToolState tool : tools) { InspectionToolWrapper toolWrapper = tool.getTool(); if (toolWrapper.isInitialized()) { if (initialized == null) { initialized = new SmartList<>(); } initialized.add(toolWrapper); } } return initialized == null ? Collections.emptyList() : initialized; } private static LocalInspectionToolWrapper createTool(String s, boolean enabled) { LocalInspectionEP foo = new LocalInspectionEP(); foo.shortName = s; foo.displayName = s; foo.groupDisplayName = s; foo.level = "ERROR"; foo.enabledByDefault = enabled; foo.implementationClass = TestTool.class.getName(); return new LocalInspectionToolWrapper(foo); } @SuppressWarnings("InspectionDescriptionNotFoundInspection") public static class TestTool extends LocalInspectionTool { } }