diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt.193 new file mode 100644 index 00000000000..214ae8f4e56 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt.193 @@ -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)) +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractSelectExpressionForDebuggerTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractSelectExpressionForDebuggerTest.kt.193 new file mode 100644 index 00000000000..1cf11f116ac --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractSelectExpressionForDebuggerTest.kt.193 @@ -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" +}