From 9fca7e814fc7766603ff6bb99c1f4d79cfb5ad85 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 27 Apr 2017 17:40:02 +0300 Subject: [PATCH] Test refactoring: extract common parts from inspection tests --- .../AbstractKotlinMavenInspectionTest.kt | 42 ++++---------- .../codeInsight/AbstractInspectionTest.kt | 27 ++------- .../AbstractMultiFileInspectionTest.kt | 23 +------- .../gradle/GradleInspectionTest.kt | 20 +------ .../AbstractLocalInspectionTest.kt | 28 +++------- .../idea/inspections/InspectionUtils.kt | 55 +++++++++++++++++++ 6 files changed, 85 insertions(+), 110 deletions(-) create mode 100644 idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionUtils.kt diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt index 9cb3a6a2fc4..054e6e8e44a 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.idea.maven -import com.intellij.analysis.AnalysisScope -import com.intellij.codeInspection.* -import com.intellij.codeInspection.ex.InspectionManagerEx -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper +import com.intellij.codeInspection.CommonProblemDescriptor +import com.intellij.codeInspection.ProblemDescriptorBase +import com.intellij.codeInspection.QuickFix import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.Result @@ -31,10 +30,8 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiManager import com.intellij.psi.search.FileTypeIndex -import com.intellij.testFramework.InspectionTestUtil -import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl import org.jetbrains.jps.model.java.JavaSourceRootType -import org.jetbrains.kotlin.idea.maven.inspections.DifferentKotlinMavenVersionInspection +import org.jetbrains.kotlin.idea.inspections.runInspection import org.jetbrains.kotlin.idea.maven.inspections.KotlinMavenPluginPhaseInspection import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory import org.jetbrains.kotlin.idea.util.projectStructure.allModules @@ -67,7 +64,14 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { val matcher = "".toRegex() val expected = pomText.lines().mapNotNull { matcher.find(it) }.map { SimplifiedProblemDescription(it.groups[2]!!.value.trim(), it.groups[1]!!.value.trim()) } - val actual = runInspection(inspectionClass).sortedBy { it.first.text } + val actual = runInspection(inspectionClass, myProject) + .problemElements + .filter { it.key.name == "pom.xml" } + .values + .flatMap { it.toList() } + .mapNotNull { it as? ProblemDescriptorBase } + .map { SimplifiedProblemDescription(it.descriptionTemplate, it.psiElement.text.replace("\\s+".toRegex(), "")) to it } + .sortedBy { it.first.text } assertEquals(expected.sortedBy { it.text }, actual.map { it.first }) @@ -145,27 +149,5 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { assertTrue(FileTypeIndex.containsFileOfType(JavaFileType.INSTANCE, myProject.allModules().single().moduleScope)) } - private fun runInspection(inspectionClass: Class<*>): List> { - val toolWrapper = LocalInspectionToolWrapper(inspectionClass.newInstance() as LocalInspectionTool) - - val tool = toolWrapper.tool - if (tool is DifferentKotlinMavenVersionInspection) { - tool.testVersionMessage = "\$PLUGIN_VERSION" - } - - val scope = AnalysisScope(myProject) - val inspectionManager = (InspectionManager.getInstance(myProject) as InspectionManagerEx) - val globalContext = CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, myProject, inspectionManager, toolWrapper) - - InspectionTestUtil.runTool(toolWrapper, scope, globalContext) - val presentation = globalContext.getPresentation(toolWrapper) - - return presentation.problemElements.filter { it.key.name == "pom.xml" } - .values - .flatMap { it.toList() } - .mapNotNull { it as? ProblemDescriptorBase } - .map { SimplifiedProblemDescription(it.descriptionTemplate, it.psiElement.text.replace("\\s+".toRegex(), "")) to it } - } - private data class SimplifiedProblemDescription(val text: String, val elementText: String) } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt index df0739c7f63..be56051ed67 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt @@ -16,20 +16,13 @@ package org.jetbrains.kotlin.idea.codeInsight -import com.intellij.analysis.AnalysisScope -import com.intellij.codeInspection.InspectionManager -import com.intellij.codeInspection.LocalInspectionTool import com.intellij.codeInspection.ex.EntryPointsManagerBase -import com.intellij.codeInspection.ex.InspectionManagerEx -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.util.io.FileUtil import com.intellij.psi.PsiFile import com.intellij.testFramework.IdeaTestUtil -import com.intellij.testFramework.InspectionTestUtil import com.intellij.testFramework.LightProjectDescriptor -import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl -import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection +import org.jetbrains.kotlin.idea.inspections.runInspection import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion @@ -63,12 +56,6 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase() val options = FileUtil.loadFile(optionsFile, true) val inspectionClass = Class.forName(InTextDirectivesUtils.findStringWithPrefixes(options, "// INSPECTION_CLASS: ")!!) - val toolWrapper = LocalInspectionToolWrapper(inspectionClass.newInstance() as LocalInspectionTool) - - val tool = toolWrapper.tool - if (tool is DifferentKotlinGradleVersionInspection) { - tool.testVersionMessage = "\$PLUGIN_VERSION" - } val fixtureClasses = InTextDirectivesUtils.findListWithPrefixes(options, "// FIXTURE_CLASS: ") @@ -128,17 +115,11 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase() configExtra(psiFiles, options) - val scope = AnalysisScope(project, psiFiles.map { it.virtualFile!! }) - scope.invalidate() - - val inspectionManager = (InspectionManager.getInstance(project) as InspectionManagerEx) - val globalContext = CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, project, inspectionManager, toolWrapper) - - InspectionTestUtil.runTool(toolWrapper, scope, globalContext) - InspectionTestUtil.compareToolResults(globalContext, toolWrapper, false, inspectionsTestDir.path) + val presentation = runInspection( + inspectionClass, project, files = psiFiles.map { it.virtualFile!!}, withTestDir = inspectionsTestDir.path) if (afterFiles.isNotEmpty()) { - globalContext.getPresentation(toolWrapper).problemDescriptors.forEach { + presentation.problemDescriptors.forEach { problem -> problem.fixes?.forEach { CommandProcessor.getInstance().executeCommand(project, { diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractMultiFileInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractMultiFileInspectionTest.kt index 9e204484153..e5fa6723700 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractMultiFileInspectionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractMultiFileInspectionTest.kt @@ -18,14 +18,8 @@ package org.jetbrains.kotlin.idea.codeInsight import com.google.gson.JsonObject import com.google.gson.JsonParser -import com.intellij.analysis.AnalysisScope -import com.intellij.codeInspection.InspectionManager -import com.intellij.codeInspection.LocalInspectionTool -import com.intellij.codeInspection.ex.InspectionManagerEx -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper import com.intellij.openapi.util.io.FileUtil -import com.intellij.testFramework.InspectionTestUtil -import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl +import org.jetbrains.kotlin.idea.inspections.runInspection import org.jetbrains.kotlin.idea.jsonUtils.getString import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase @@ -41,7 +35,6 @@ abstract class AbstractMultiFileInspectionTest : KotlinMultiFileTestCase() { protected fun doTest(path: String) { val configFile = File(path) val config = JsonParser().parse(FileUtil.loadFile(configFile, true)) as JsonObject - val inspection = LocalInspectionToolWrapper(Class.forName(config.getString("inspectionClass")).newInstance() as LocalInspectionTool) val withRuntime = config["withRuntime"]?.asBoolean ?: false val withFullJdk = config["withFullJdk"]?.asBoolean ?: false @@ -58,18 +51,8 @@ abstract class AbstractMultiFileInspectionTest : KotlinMultiFileTestCase() { } } - val scope = AnalysisScope(myProject) - scope.invalidate() - - val globalContext = CodeInsightTestFixtureImpl.createGlobalContextForTool( - scope, - myProject, - InspectionManager.getInstance(myProject) as InspectionManagerEx, - inspection - ) - - InspectionTestUtil.runTool(inspection, scope, globalContext) - InspectionTestUtil.compareToolResults(globalContext, inspection, false, configFile.parent) + runInspection(Class.forName(config.getString("inspectionClass")), project, + withTestDir = configFile.parent) } finally { if (withRuntime) { diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleInspectionTest.kt index ce26b16466a..1bde64e0003 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleInspectionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleInspectionTest.kt @@ -16,20 +16,13 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle -import com.intellij.analysis.AnalysisScope -import com.intellij.codeInspection.InspectionManager import com.intellij.codeInspection.LocalInspectionTool import com.intellij.codeInspection.ProblemDescriptorBase -import com.intellij.codeInspection.ex.InspectionManagerEx -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper import com.intellij.openapi.util.Ref import com.intellij.openapi.vfs.VirtualFile -import com.intellij.testFramework.InspectionTestUtil -import com.intellij.testFramework.UsefulTestCase -import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl -import com.intellij.testFramework.runInEdtAndWait import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection import org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection +import org.jetbrains.kotlin.idea.inspections.runInspection import org.junit.Assert import org.junit.Test @@ -163,18 +156,9 @@ class GradleInspectionTest : GradleImportingTestCase() { } fun getInspectionResult(tool: LocalInspectionTool, file: VirtualFile): List { - val toolWrapper = LocalInspectionToolWrapper(tool) - - val scope = AnalysisScope(myProject, listOf(file)) - scope.invalidate() - - val inspectionManager = (InspectionManager.getInstance(myProject) as InspectionManagerEx) - val globalContext = CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, myProject, inspectionManager, toolWrapper) - val resultRef = Ref>() invokeTestRunnable { - InspectionTestUtil.runTool(toolWrapper, scope, globalContext) - val presentation = globalContext.getPresentation(toolWrapper) + val presentation = runInspection(tool, myProject, listOf(file)) val foundProblems = presentation.problemElements .values diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt index 90be6986342..02f20209fc3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt @@ -17,14 +17,10 @@ package org.jetbrains.kotlin.idea.inspections import com.google.common.collect.Lists -import com.intellij.analysis.AnalysisScope import com.intellij.codeInspection.ProblemDescriptor -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.io.FileUtil -import com.intellij.psi.PsiFile -import com.intellij.testFramework.InspectionTestUtil -import com.intellij.testFramework.createGlobalContextForTool +import com.intellij.openapi.vfs.VirtualFile import junit.framework.ComparisonFailure import junit.framework.TestCase import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils @@ -36,7 +32,7 @@ import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.Assert import java.io.File -abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestCase() { +abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestCase() { protected open fun inspectionFileName(): String = ".inspection" protected open fun afterFileNameSuffix(): String = ".after" @@ -74,8 +70,6 @@ abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestC val mainFile = File(path) val inspection = createInspection(mainFile) - val psiFile = myFixture.configureByFiles(mainFile.name).first() - val fileText = FileUtil.loadFile(mainFile, true) TestCase.assertTrue("\"\" is missing in file \"$mainFile\"", fileText.contains("")) @@ -86,27 +80,24 @@ abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestC DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) } - doTestFor(mainFile.name, psiFile, inspection, fileText) + val psiFile = myFixture.configureByFiles(mainFile.name).first() + + doTestFor(mainFile.name, psiFile.virtualFile!!, inspection, fileText) if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_AFTER")) { DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) } } - private fun doTestFor(mainFilePath: String, psiFile: PsiFile, inspection: AbstractKotlinInspection, fileText: String) { + private fun doTestFor(mainFilePath: String, file: VirtualFile, inspection: AbstractKotlinInspection, fileText: String) { val problemExpectedString = InTextDirectivesUtils.findStringWithPrefixes( fileText, "// ${expectedProblemDirectiveName()}: ") val problemExpected = problemExpectedString == null || problemExpectedString != "none" - val toolWrapper = LocalInspectionToolWrapper(inspection) - val scope = AnalysisScope(project, listOf(psiFile.virtualFile!!)) - scope.invalidate() - val globalContext = createGlobalContextForTool(scope, project, listOf(toolWrapper)) - InspectionTestUtil.runTool(toolWrapper, scope, globalContext) - - val problemDescriptors = globalContext.getPresentation(toolWrapper).problemDescriptors + val presentation = runInspection(inspection, project, listOf(file)) + val problemDescriptors = presentation.problemDescriptors .filterIsInstance() - .filter { editor.caretModel.offset in it.psiElement.textRange } + .filter { myFixture.caretOffset in it.psiElement.textRange } Assert.assertTrue( if (!problemExpected) "No problems should be detected at caret\n" + @@ -144,7 +135,6 @@ abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestC project.executeWriteCommand(localFixAction!!.name, null) { localFixAction.applyFix(project, problemDescriptor) - null } val canonicalPathToExpectedFile = mainFilePath + afterFileNameSuffix() try { diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionUtils.kt b/idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionUtils.kt new file mode 100644 index 00000000000..1b138ce06a0 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/InspectionUtils.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2010-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 org.jetbrains.kotlin.idea.inspections + +import com.intellij.analysis.AnalysisScope +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper +import com.intellij.codeInspection.ui.InspectionToolPresentation +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.InspectionTestUtil +import com.intellij.testFramework.createGlobalContextForTool +import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection +import org.jetbrains.kotlin.idea.maven.inspections.DifferentKotlinMavenVersionInspection + +fun runInspection( + inspection: LocalInspectionTool, project: Project, files: List? = null, withTestDir: String? = null +): InspectionToolPresentation { + val wrapper = LocalInspectionToolWrapper(inspection) + + val tool = wrapper.tool + when (tool) { + is DifferentKotlinMavenVersionInspection -> tool.testVersionMessage = "\$PLUGIN_VERSION" + is DifferentKotlinGradleVersionInspection -> tool.testVersionMessage = "\$PLUGIN_VERSION" + } + + val scope = if (files != null) AnalysisScope(project, files) else AnalysisScope(project) + scope.invalidate() + val globalContext = createGlobalContextForTool(scope, project, listOf(wrapper)) + InspectionTestUtil.runTool(wrapper, scope, globalContext) + if (withTestDir != null) { + InspectionTestUtil.compareToolResults(globalContext, wrapper, false, withTestDir) + } + return globalContext.getPresentation(wrapper) +} + +fun runInspection( + inspectionClass: Class<*>, project: Project, files: List? = null, withTestDir: String? = null +): InspectionToolPresentation { + return runInspection(inspectionClass.newInstance() as LocalInspectionTool, project, files, withTestDir) +}