Test refactoring: extract common parts from inspection tests

This commit is contained in:
Mikhail Glukhikh
2017-04-27 17:40:02 +03:00
committed by Mikhail Glukhikh
parent 6f94f45409
commit 9fca7e814f
6 changed files with 85 additions and 110 deletions
@@ -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 = "<!--\\s*problem:\\s*on\\s*([^,]+),\\s*title\\s*(.+)\\s*-->".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<Pair<SimplifiedProblemDescription, ProblemDescriptorBase>> {
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)
}
@@ -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, {
@@ -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) {
@@ -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<String> {
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<List<String>>()
invokeTestRunnable {
InspectionTestUtil.runTool(toolWrapper, scope, globalContext)
val presentation = globalContext.getPresentation(toolWrapper)
val presentation = runInspection(tool, myProject, listOf(file))
val foundProblems = presentation.problemElements
.values
@@ -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("\"<caret>\" is missing in file \"$mainFile\"", fileText.contains("<caret>"))
@@ -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<ProblemDescriptor>()
.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 {
@@ -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<VirtualFile>? = 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<VirtualFile>? = null, withTestDir: String? = null
): InspectionToolPresentation {
return runInspection(inspectionClass.newInstance() as LocalInspectionTool, project, files, withTestDir)
}