diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractKotlinSourceInJavaCompletionTest.kt.193 b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractKotlinSourceInJavaCompletionTest.kt.193 new file mode 100644 index 00000000000..3bbe56bc7e3 --- /dev/null +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractKotlinSourceInJavaCompletionTest.kt.193 @@ -0,0 +1,41 @@ +/* + * 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.completion.test + +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.openapi.util.io.FileUtil +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import java.io.File + +abstract class AbstractKotlinSourceInJavaCompletionTest : KotlinFixtureCompletionBaseTestCase() { + override fun getPlatform() = JvmPlatforms.unspecifiedJvmPlatform + + override fun doTest(testPath: String) { + val mockPath = RELATIVE_COMPLETION_TEST_DATA_BASE_PATH + "/injava/mockLib" + val mockLibDir = File(mockPath) + fun collectPaths(dir: File): List { + return dir.listFiles()!!.flatMap { + if (it.isDirectory) { + collectPaths(it) + } else listOf(FileUtil.toSystemIndependentName(it.path)) + } + } + + val paths = collectPaths(mockLibDir).toTypedArray() + paths.forEach { path -> + val vFile = myFixture.copyFileToProject(path.substringAfter(testDataPath), path.substring(mockPath.length)) + myFixture.configureFromExistingVirtualFile(vFile) + } + + LightClassComputationControl.testWithControl(project, FileUtil.loadFile(File(testPath))) { + super.doTest(testPath) + } + } + + override fun getProjectDescriptor() = LightCodeInsightFixtureTestCase.JAVA_LATEST + override fun defaultCompletionType() = CompletionType.BASIC +} \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KotlinFixtureCompletionBaseTestCase.kt.193 b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KotlinFixtureCompletionBaseTestCase.kt.193 new file mode 100644 index 00000000000..095fe57b6d2 --- /dev/null +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/KotlinFixtureCompletionBaseTestCase.kt.193 @@ -0,0 +1,67 @@ +/* + * 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.completion.test + +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker +import org.jetbrains.kotlin.idea.test.CompilerTestDirectives +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.configureCompilerOptions +import org.jetbrains.kotlin.idea.test.rollbackCompilerOptions +import org.jetbrains.kotlin.platform.TargetPlatform +import java.io.File + +abstract class KotlinFixtureCompletionBaseTestCase : KotlinLightCodeInsightFixtureTestCase() { + abstract fun getPlatform(): TargetPlatform + + protected open fun complete(completionType: CompletionType, invocationCount: Int): Array? = + myFixture.complete(completionType, invocationCount) + + protected abstract fun defaultCompletionType(): CompletionType + protected open fun defaultInvocationCount(): Int = 0 + + open fun doTest(testPath: String) { + setUpFixture(fileName()) + + val fileText = FileUtil.loadFile(File(testPath), true) + val configured = configureCompilerOptions(fileText, project, module) + try { + + assertTrue("\"\" is missing in file \"$testPath\"", fileText.contains("")) + + if (ExpectedCompletionUtils.shouldRunHighlightingBeforeCompletion(fileText)) { + myFixture.doHighlighting() + } + + testCompletion( + fileText, + getPlatform(), + { completionType, count -> complete(completionType, count) }, + defaultCompletionType(), + defaultInvocationCount(), + additionalValidDirectives = CompilerTestDirectives.ALL_COMPILER_TEST_DIRECTIVES + ) + } finally { + if (configured) { + rollbackCompilerOptions(project, module) + } + tearDownFixture() + } + } + + protected open fun setUpFixture(testPath: String) { + //TODO: this is a hacky workaround for js second completion tests failing with PsiInvalidElementAccessException + LibraryModificationTracker.getInstance(project).incModificationCount() + + myFixture.configureByFile(testPath) + } + + protected open fun tearDownFixture() { + + } +} diff --git a/idea/tests/org/jetbrains/kotlin/DataFlowValueRenderingTest.kt.193 b/idea/tests/org/jetbrains/kotlin/DataFlowValueRenderingTest.kt.193 new file mode 100644 index 00000000000..95bf61aff81 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/DataFlowValueRenderingTest.kt.193 @@ -0,0 +1,63 @@ +/* + * 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 + +import com.intellij.openapi.util.io.FileUtil +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.descriptors.PackageViewDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoAfter +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue +import org.jetbrains.kotlin.resolve.calls.smartcasts.IdentifierInfo +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + +abstract class AbstractDataFlowValueRenderingTest: KotlinLightCodeInsightFixtureTestCase() { + + private fun IdentifierInfo.render(): String? = when (this) { + is IdentifierInfo.Expression -> expression.text + is IdentifierInfo.Receiver -> (value as? ImplicitReceiver)?.declarationDescriptor?.name?.let { "this@$it" } + is IdentifierInfo.Variable -> variable.name.asString() + is IdentifierInfo.PackageOrClass -> (descriptor as? PackageViewDescriptor)?.let { it.fqName.asString() } + is IdentifierInfo.Qualified -> receiverInfo.render() + "." + selectorInfo.render() + else -> null + } + + private fun DataFlowValue.render() = + // If it is not a stable identifier, there's no point in rendering it + if (!isStable) null + else identifierInfo.render() + + override fun getTestDataPath() : String { + return PluginTestCaseBase.getTestDataPathBase() + "/dataFlowValueRendering/" + } + + override fun getProjectDescriptor(): LightProjectDescriptor { + return LightCodeInsightFixtureTestCase.JAVA_LATEST + } + + fun doTest(path: String) { + val fixture = myFixture + fixture.configureByFile(fileName()) + + val jetFile = fixture.file as KtFile + val element = jetFile.findElementAt(fixture.caretOffset)!! + val expression = element.getStrictParentOfType()!! + val info = expression.analyze().getDataFlowInfoAfter(expression) + + val allValues = (info.completeTypeInfo.keySet() + info.completeNullabilityInfo.keySet()).toSet() + val actual = allValues.mapNotNull { it.render() }.sorted().joinToString("\n") + + KotlinTestUtils.assertEqualsToFile(File(FileUtil.getNameWithoutExtension(path) + ".txt"), actual) + } +} diff --git a/idea/tests/org/jetbrains/kotlin/checkers/AbstractJsCheckerTest.java.193 b/idea/tests/org/jetbrains/kotlin/checkers/AbstractJsCheckerTest.java.193 new file mode 100644 index 00000000000..a2cc2e3125d --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/checkers/AbstractJsCheckerTest.java.193 @@ -0,0 +1,24 @@ +/* + * 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.checkers; + +import com.intellij.testFramework.LightProjectDescriptor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase; +import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor; + +public abstract class AbstractJsCheckerTest extends KotlinLightCodeInsightFixtureTestCase { + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return KotlinStdJSProjectDescriptor.INSTANCE; + } + + public void doTest(String filePath) { + myFixture.configureByFile(fileName()); + myFixture.checkHighlighting(true, false, false); + } +} diff --git a/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt.193 b/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt.193 new file mode 100644 index 00000000000..19455d26202 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/copyright/AbstractUpdateKotlinCopyrightTest.kt.193 @@ -0,0 +1,51 @@ +/* + * 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.copyright + +import junit.framework.AssertionFailedError +import org.jetbrains.kotlin.idea.copyright.UpdateKotlinCopyright +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.junit.Assert +import java.io.File + +abstract class AbstractUpdateKotlinCopyrightTest : KotlinLightCodeInsightFixtureTestCase() { + fun doTest(path: String) { + myFixture.configureByFile(fileName()) + + val fileText = myFixture.file.text.trim() + val expectedNumberOfComments = InTextDirectivesUtils.getPrefixedInt(fileText, "// COMMENTS: ") ?: run { + if (fileText.isNotEmpty()) { + throw AssertionFailedError("Every test should assert number of comments with `COMMENTS` directive") + } else { + 0 + } + } + + val comments = UpdateKotlinCopyright.getExistentComments(myFixture.file) + for (comment in comments) { + val commentText = comment.text + when { + commentText.contains("PRESENT") -> { + } + commentText.contains("ABSENT") -> { + throw AssertionFailedError("Unexpected comment found: `$commentText`") + } + else -> { + throw AssertionFailedError("A comment with bad directive found: `$commentText`") + } + } + } + + Assert.assertEquals( + "Wrong number of comments found:\n${comments.joinToString(separator = "\n") { it.text }}\n", + expectedNumberOfComments, comments.size + ) + } + + override fun getTestDataPath() = File(PluginTestCaseBase.getTestDataPathBase(), "/copyright").path + File.separator +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractBreadcrumbsTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractBreadcrumbsTest.kt.193 new file mode 100644 index 00000000000..616e6d068bf --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractBreadcrumbsTest.kt.193 @@ -0,0 +1,35 @@ +/* + * 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.codeInsight + +import com.intellij.testFramework.LightProjectDescriptor +import org.jetbrains.kotlin.idea.test.KotlinLightPlatformCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + +abstract class AbstractBreadcrumbsTest : KotlinLightPlatformCodeInsightFixtureTestCase() { + override fun getProjectDescriptor(): LightProjectDescriptor? = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + + override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase() + "/codeInsight/breadcrumbs" + + protected open fun doTest(path: String) { + assert(path.endsWith(".kt")) { path } + myFixture.configureByFile(path.substringAfterLast('/')) + + val element = myFixture.file.findElementAt(myFixture.caretOffset)!! + val provider = KotlinBreadcrumbsInfoProvider() + val elements = generateSequence(element) { provider.getParent(it) } + .filter { provider.acceptElement(it) } + .toList() + .asReversed() + val crumbs = elements.joinToString(separator = "\n") { " " + provider.getElementInfo(it) } + val tooltips = elements.joinToString(separator = "\n") { " " + provider.getElementTooltip(it) } + val resultText = "Crumbs:\n$crumbs\nTooltips:\n$tooltips" + KotlinTestUtils.assertEqualsToFile(File(testDataPath + "/" + File(path).nameWithoutExtension + ".txt"), resultText) + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractExpressionTypeTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractExpressionTypeTest.kt.193 new file mode 100644 index 00000000000..2d73438c8bc --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractExpressionTypeTest.kt.193 @@ -0,0 +1,28 @@ +/* + * 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.codeInsight + +import com.intellij.testFramework.UsefulTestCase +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.InTextDirectivesUtils + +abstract class AbstractExpressionTypeTest : KotlinLightCodeInsightFixtureTestCase() { + override fun getBasePath() = PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE + "/codeInsight/expressionType" + + override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + + protected fun doTest(path: String) { + myFixture.configureByFile(fileName()) + val expressionTypeProvider = KotlinExpressionTypeProvider() + val elementAtCaret = myFixture.file.findElementAt(myFixture.editor.caretModel.offset)!! + val expressions = expressionTypeProvider.getExpressionsAt(elementAtCaret) + val types = expressions.map { "${it.text.replace('\n', ' ')} -> ${expressionTypeProvider.getInformationHint(it)}" } + val expectedTypes = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.file.text, "// TYPE: ") + UsefulTestCase.assertOrderedEquals(types, expectedTypes) + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.193 new file mode 100644 index 00000000000..e11b51d8dbd --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt.193 @@ -0,0 +1,189 @@ +/* + * 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.codeInsight + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings +import com.intellij.codeInsight.daemon.LineMarkerInfo +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl +import com.intellij.openapi.editor.Document +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.io.FileUtil +import com.intellij.psi.PsiDocumentManager +import com.intellij.rt.execution.junit.FileComparisonFailure +import com.intellij.testFramework.ExpectedHighlightingData +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.PlatformTestUtil +import com.intellij.testFramework.UsefulTestCase +import junit.framework.TestCase +import org.jetbrains.kotlin.idea.highlighter.markers.TestableLineMarkerNavigator +import org.jetbrains.kotlin.idea.navigation.NavigationTestUtils +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.TagsTestDataUtil +import org.jetbrains.kotlin.test.util.renderAsGotoImplementation +import org.junit.Assert +import java.io.File + +abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() { + + override fun getBasePath(): String { + return PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE + "/codeInsight/lineMarker" + } + + override fun getProjectDescriptor(): LightProjectDescriptor { + return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + } + + fun doTest(path: String) = doTest(path) {} + + protected fun doAndCheckHighlighting( + project: Project, + documentToAnalyze: Document, + expectedHighlighting: ExpectedHighlightingData, + expectedFile: File + ): List> { + myFixture.doHighlighting() + + return checkHighlighting(project, documentToAnalyze, expectedHighlighting, expectedFile) + } + + fun doTest(path: String, additionalCheck: () -> Unit) { + val fileText = FileUtil.loadFile(File(path)) + try { + ConfigLibraryUtil.configureLibrariesByDirective(myFixture.module, PlatformTestUtil.getCommunityPath(), fileText) + if (InTextDirectivesUtils.findStringWithPrefixes(fileText, "METHOD_SEPARATORS") != null) { + DaemonCodeAnalyzerSettings.getInstance().SHOW_METHOD_SEPARATORS = true + } + + myFixture.configureByFile(fileName()) + val project = myFixture.project + val document = myFixture.editor.document + + val data = ExpectedHighlightingData(document, false, false, false, myFixture.file) + data.init() + + PsiDocumentManager.getInstance(project).commitAllDocuments() + + val markers = doAndCheckHighlighting(myFixture.project, document, data, File(path)) + + assertNavigationElements(myFixture.project, myFixture.file as KtFile, markers) + additionalCheck() + } catch (exc: Exception) { + throw RuntimeException(exc) + } finally { + ConfigLibraryUtil.unconfigureLibrariesByDirective(module, fileText) + DaemonCodeAnalyzerSettings.getInstance().SHOW_METHOD_SEPARATORS = false + } + + } + + companion object { + + @Suppress("SpellCheckingInspection") + private const val LINE_MARKER_PREFIX = "LINEMARKER:" + private const val TARGETS_PREFIX = "TARGETS" + + fun assertNavigationElements(project: Project, file: KtFile, markers: List>) { + val navigationDataComments = KotlinTestUtils.getLastCommentsInFile( + file, KotlinTestUtils.CommentType.BLOCK_COMMENT, false + ) + if (navigationDataComments.isEmpty()) return + + for ((navigationCommentIndex, navigationComment) in navigationDataComments.reversed().withIndex()) { + val description = getLineMarkerDescription(navigationComment) + val navigateMarkers = markers.filter { it.lineMarkerTooltip?.startsWith(description) == true } + val navigateMarker = navigateMarkers.singleOrNull() ?: navigateMarkers.getOrNull(navigationCommentIndex) + + TestCase.assertNotNull( + String.format("Can't find marker for navigation check with description \"%s\"", description), + navigateMarker + ) + + val handler = navigateMarker!!.navigationHandler + if (handler is TestableLineMarkerNavigator) { + val navigateElements = handler.getTargetsPopupDescriptor(navigateMarker.element)?.targets?.sortedBy { + it.renderAsGotoImplementation() + } + val actualNavigationData = NavigationTestUtils.getNavigateElementsText(project, navigateElements) + + UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData) + } else { + Assert.fail("Only TestableLineMarkerNavigator are supported in navigate check") + } + } + } + + private fun getLineMarkerDescription(navigationComment: String): String { + val firstLineEnd = navigationComment.indexOf("\n") + TestCase.assertTrue( + "The first line in block comment must contain description of marker for navigation check", firstLineEnd != -1 + ) + + var navigationMarkerText = navigationComment.substring(0, firstLineEnd) + + TestCase.assertTrue( + String.format("Add %s directive in first line of comment", LINE_MARKER_PREFIX), + navigationMarkerText.startsWith(LINE_MARKER_PREFIX) + ) + + navigationMarkerText = navigationMarkerText.substring(LINE_MARKER_PREFIX.length) + + return navigationMarkerText.trim { it <= ' ' } + } + + private fun getExpectedNavigationText(navigationComment: String): String { + val firstLineEnd = navigationComment.indexOf("\n") + + var expectedNavigationText = navigationComment.substring(firstLineEnd + 1) + + TestCase.assertTrue( + String.format("Marker %s is expected before navigation data", TARGETS_PREFIX), + expectedNavigationText.startsWith(TARGETS_PREFIX) + ) + + expectedNavigationText = expectedNavigationText.substring(expectedNavigationText.indexOf("\n") + 1) + + return expectedNavigationText + } + + fun checkHighlighting( + project: Project, + documentToAnalyze: Document, + expectedHighlighting: ExpectedHighlightingData, + expectedFile: File + ): MutableList> { + val markers = DaemonCodeAnalyzerImpl.getLineMarkers(documentToAnalyze, project) + + try { + expectedHighlighting.checkLineMarkers(markers, documentToAnalyze.text) + + // This is a workaround for sad bug in ExpectedHighlightingData: + // the latter doesn't throw assertion error when some line markers are expected, but none are present. + if (FileUtil.loadFile(expectedFile).contains(" + name.startsWith(fileNameBase) && name != mainFileName && (name.endsWith(".kt") || name.endsWith(".java")) + } + .forEach { + myFixture.configureByFile(File(rootDir, it).path.replace(File.separator, "/")) + } + + configure(path, fileText) + mainPsiFile = myFixture.file as KtFile + + val targetPlatformName = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// PLATFORM: ") + if (targetPlatformName != null) { + val targetPlatform = when (targetPlatformName) { + "JVM" -> JvmPlatforms.unspecifiedJvmPlatform + "JavaScript" -> JsPlatforms.defaultJsPlatform + "Common" -> CommonPlatforms.defaultCommonPlatform + else -> error("Unexpected platform name: $targetPlatformName") + } + mainPsiFile.forcedTargetPlatform = targetPlatform + } + + val action = createAction(fileText) + + val isApplicableExpected = !InTextDirectivesUtils.isDirectiveDefined(fileText, "// NOT_APPLICABLE") + val isForced = InTextDirectivesUtils.isDirectiveDefined(fileText, "// FORCED") + + val presentation = testAction(action, isForced) + if (!isForced) { + TestCase.assertEquals(isApplicableExpected, presentation.isEnabled) + } + + assert(!conflictFile.exists()) { "Conflict file $conflictFile should not exist" } + + if (isForced || isApplicableExpected) { + TestCase.assertTrue(afterFile.exists()) + myFixture.checkResult(FileUtil.loadFile(afterFile, true)) + checkExtra() + } + } + catch (e: ComparisonFailure) { + KotlinTestUtils.assertEqualsToFile(afterFile, myFixture.editor) + } + catch (e: CommonRefactoringUtil.RefactoringErrorHintException) { + KotlinTestUtils.assertEqualsToFile(conflictFile, e.message!!) + } + finally { + mainPsiFile?.forcedTargetPlatform = null + ConfigLibraryUtil.unconfigureLibrariesByDirective(module, fileText) + } + } + + override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt.193 b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt.193 new file mode 100644 index 00000000000..2e785b12a70 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt.193 @@ -0,0 +1,75 @@ +/* + * 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 + +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture +import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils +import org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.InTextDirectivesUtils + +abstract class AbstractSmartStepIntoTest : KotlinLightCodeInsightFixtureTestCase() { + private val fixture: JavaCodeInsightTestFixture + get() = myFixture + + protected fun doTest(path: String) { + fixture.configureByFile(fileName()) + + val offset = fixture.caretOffset + val line = fixture.getDocument(fixture.file!!)!!.getLineNumber(offset) + + val lineStart = CodeInsightUtils.getStartLineOffset(file, line)!! + val elementAtOffset = file.findElementAt(lineStart) + + val position = MockSourcePosition(_file = fixture.file, + _line = line, + _offset = offset, + _editor = fixture.editor, + _elementAt = elementAtOffset) + + val actual = KotlinSmartStepIntoHandler().findSmartStepTargets(position).map { it.presentation } + + val expected = InTextDirectivesUtils.findListWithPrefixes(fixture.file?.text!!.replace("\\,", "+++"), "// EXISTS: ").map { it.replace("+++", ",") } + + for (actualTargetName in actual) { + assert(actualTargetName in expected) { + "Unexpected step into target was found: $actualTargetName\n${renderTableWithResults(expected, actual)}" + + "\n // EXISTS: ${actual.joinToString()}" + } + } + + for (expectedTargetName in expected) { + assert(expectedTargetName in actual) { + "Missed step into target: $expectedTargetName\n${renderTableWithResults(expected, actual)}" + + "\n // EXISTS: ${actual.joinToString()}" + } + } + } + + private fun renderTableWithResults(expected: List, actual: List): String { + val sb = StringBuilder() + + val maxExtStrSize = (expected.maxBy { it.length }?.length ?: 0) + 5 + val longerList = (if (expected.size < actual.size) actual else expected).sorted() + val shorterList = (if (expected.size < actual.size) expected else actual).sorted() + for ((i, element) in longerList.withIndex()) { + sb.append(element) + sb.append(" ".repeat(maxExtStrSize - element.length)) + if (i < shorterList.size) sb.append(shorterList[i]) + sb.append("\n") + } + + return sb.toString() + } + + override fun getTestDataPath(): String { + return PluginTestCaseBase.getTestDataPathBase() + "/debugger/smartStepInto" + } + + override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE +}