193: Fix code fragment tests fixture configuration

This commit is contained in:
Vyacheslav Gerasimov
2019-10-04 18:44:12 +03:00
parent f7d12efc24
commit 98f8e0c800
2 changed files with 203 additions and 0 deletions
@@ -0,0 +1,154 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.debugger.evaluate
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.codeInspection.InspectionProfileEntry
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import org.jetbrains.kotlin.checkers.AbstractPsiCheckerTest
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTest
import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils
import org.jetbrains.kotlin.idea.completion.test.handlers.AbstractCompletionHandlerTest
import org.jetbrains.kotlin.idea.debugger.getContextElement
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
import kotlin.test.assertNull
import kotlin.test.assertTrue
abstract class AbstractCodeFragmentHighlightingTest : AbstractPsiCheckerTest() {
override fun doTest(filePath: String) {
myFixture.configureByCodeFragment(testDataFile())
checkHighlighting(filePath)
}
fun doTestWithImport(filePath: String) {
myFixture.configureByCodeFragment(testDataFile())
project.executeWriteCommand("Imports insertion") {
val fileText = FileUtil.loadFile(File(filePath), true)
val file = myFixture.file as KtFile
InTextDirectivesUtils.findListWithPrefixes(fileText, "// IMPORT: ").forEach {
val descriptor = file.resolveImportReference(FqName(it)).singleOrNull()
?: error("Could not resolve descriptor to import: $it")
ImportInsertHelper.getInstance(project).importDescriptor(file, descriptor)
}
}
checkHighlighting(filePath)
}
private fun checkHighlighting(filePath: String) {
val inspectionName = InTextDirectivesUtils.findStringWithPrefixes(File(filePath).readText(), "// INSPECTION_CLASS: ")
if (inspectionName != null) {
val inspection = Class.forName(inspectionName).newInstance() as InspectionProfileEntry
myFixture.enableInspections(inspection)
try {
myFixture.checkHighlighting(true, false, false)
} finally {
myFixture.disableInspections(inspection)
}
return
}
myFixture.checkHighlighting(true, false, false)
}
}
abstract class AbstractCodeFragmentCompletionTest : AbstractJvmBasicCompletionTest() {
override fun setUpFixture(testPath: String) {
myFixture.configureByCodeFragment(testDataFile())
}
}
abstract class AbstractCodeFragmentCompletionHandlerTest : AbstractCompletionHandlerTest(CompletionType.BASIC) {
override fun setUpFixture(testPath: String) {
myFixture.configureByCodeFragment(testDataFile())
}
override fun doTest(testPath: String) {
super.doTest(testPath)
val fragment = myFixture.file as KtCodeFragment
fragment.checkImports(testPath)
}
}
abstract class AbstractCodeFragmentAutoImportTest : AbstractPsiCheckerTest() {
override fun doTest(filePath: String) {
myFixture.configureByCodeFragment(testDataFile())
myFixture.doHighlighting()
val importFix = myFixture.availableIntentions.singleOrNull { it.familyName == "Import" }
?: error("No import fix available")
importFix.invoke(project, editor, file)
myFixture.checkResultByFile(filePath + ".after")
val fragment = myFixture.file as KtCodeFragment
fragment.checkImports(testDataPath + File.separator + filePath)
val fixAfter = myFixture.availableIntentions.firstOrNull { it.familyName == "Import" }
assertNull(fixAfter, "No import fix should be available after")
}
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
}
private fun KtCodeFragment.checkImports(testPath: String) {
val importList = importsAsImportList()
val importsText = StringUtil.convertLineSeparators(importList?.text ?: "")
val fragmentAfterFile = File(testPath + ".after.imports")
if (fragmentAfterFile.exists()) {
KotlinTestUtils.assertEqualsToFile(fragmentAfterFile, importsText)
}
else {
assertTrue(importsText.isEmpty(), "Unexpected imports found: $importsText" )
}
}
private fun JavaCodeInsightTestFixture.configureByCodeFragment(testDataFile: File) {
configureByFile(testDataFile.name)
val elementAt = file?.findElementAt(caretOffset)
val file = createCodeFragment(testDataFile.path, elementAt!!)
val typeStr = InTextDirectivesUtils.findStringWithPrefixes(getFile().text, "// ${ExpectedCompletionUtils.RUNTIME_TYPE} ")
if (typeStr != null) {
file.putCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR, {
val codeFragment = KtPsiFactory(project).createBlockCodeFragment("val xxx: $typeStr", PsiTreeUtil.getParentOfType(elementAt, KtElement::class.java))
val context = codeFragment.analyzeWithContent()
val typeReference: KtTypeReference = PsiTreeUtil.getChildOfType(codeFragment.getContentElement().firstChild, KtTypeReference::class.java)!!
context[BindingContext.TYPE, typeReference]
})
}
configureFromExistingVirtualFile(file.virtualFile!!)
}
private fun createCodeFragment(filePath: String, contextElement: PsiElement): KtCodeFragment {
val fileForFragment = File(filePath + ".fragment")
val codeFragmentText = FileUtil.loadFile(fileForFragment, true).trim()
val psiFactory = KtPsiFactory(contextElement.project)
if (fileForFragment.readLines().size == 1) {
return psiFactory.createExpressionCodeFragment(codeFragmentText, getContextElement(contextElement))
}
return psiFactory.createBlockCodeFragment(codeFragmentText, getContextElement(contextElement))
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.debugger.evaluate
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.idea.test.invalidateLibraryCache
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.junit.Assert
abstract class AbstractSelectExpressionForDebuggerTest : LightCodeInsightFixtureTestCase() {
override fun setUp() {
super.setUp()
invalidateLibraryCache(project)
}
fun doTest(path: String) {
doTest(path, true)
}
fun doTestWoMethodCalls(path: String) {
doTest(path, false)
}
fun doTest(path: String, allowMethodCalls: Boolean) {
myFixture.configureByFile(path.substringAfterLast('/'))
val elementAt = myFixture.file?.findElementAt(myFixture.caretOffset)!!
val selectedExpression = KotlinEditorTextProvider.findExpressionInner(elementAt, allowMethodCalls)
val expected = InTextDirectivesUtils.findStringWithPrefixes(myFixture.file?.text!!, "// EXPECTED: ")
val actualResult = if (selectedExpression != null)
KotlinEditorTextProvider.getElementInfo(selectedExpression) { it.text }
else
"null"
Assert.assertEquals("Another expression should be selected", expected, actualResult)
}
override fun getProjectDescriptor() = KotlinLightProjectDescriptor.INSTANCE
override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase() + "/debugger/selectExpression"
}