193: Fix test fixture configuration
Path to test data file should be relative to test data directory
This commit is contained in:
+41
@@ -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<String> {
|
||||||
|
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
|
||||||
|
}
|
||||||
+67
@@ -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<LookupElement>? =
|
||||||
|
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("\"<caret>\" is missing in file \"$testPath\"", fileText.contains("<caret>"))
|
||||||
|
|
||||||
|
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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<KtExpression>()!!
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<LineMarkerInfo<*>> {
|
||||||
|
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<LineMarkerInfo<*>>) {
|
||||||
|
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<LineMarkerInfo<*>> {
|
||||||
|
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("<lineMarker") && markers.isEmpty()) {
|
||||||
|
throw AssertionError("Some line markers are expected, but nothing is present at all")
|
||||||
|
}
|
||||||
|
} catch (error: AssertionError) {
|
||||||
|
try {
|
||||||
|
val actualTextWithTestData = TagsTestDataUtil.insertInfoTags(markers, true, documentToAnalyze.text)
|
||||||
|
KotlinTestUtils.assertEqualsToFile(expectedFile, actualTextWithTestData)
|
||||||
|
} catch (failure: FileComparisonFailure) {
|
||||||
|
throw FileComparisonFailure(
|
||||||
|
error.message + "\n" + failure.message,
|
||||||
|
failure.expected,
|
||||||
|
failure.actual,
|
||||||
|
failure.filePath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return markers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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.openapi.application.ApplicationManager;
|
||||||
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiManager;
|
||||||
|
import com.intellij.psi.impl.PsiModificationTrackerImpl;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
||||||
|
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListenerKt;
|
||||||
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
||||||
|
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
||||||
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.ResolveSession;
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class AbstractOutOfBlockModificationTest extends KotlinLightCodeInsightFixtureTestCase {
|
||||||
|
@Override
|
||||||
|
public void setUp() {
|
||||||
|
super.setUp();
|
||||||
|
myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/codeInsight/outOfBlock");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return PluginTestCaseBase.getTestDataPathBase() + "/codeInsight/outOfBlock";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doTest(String path) throws IOException {
|
||||||
|
myFixture.configureByFile(fileName());
|
||||||
|
|
||||||
|
boolean expectedOutOfBlock = getExpectedOutOfBlockResult();
|
||||||
|
boolean isSkipCheckDefined = InTextDirectivesUtils.isDirectiveDefined(myFixture.getFile().getText(), "SKIP_ANALYZE_CHECK");
|
||||||
|
|
||||||
|
assertTrue("It's allowed to skip check with analyze only for tests where out-of-block is expected",
|
||||||
|
!isSkipCheckDefined || expectedOutOfBlock);
|
||||||
|
|
||||||
|
|
||||||
|
PsiModificationTrackerImpl tracker =
|
||||||
|
(PsiModificationTrackerImpl) PsiManager.getInstance(myFixture.getProject()).getModificationTracker();
|
||||||
|
|
||||||
|
PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
|
||||||
|
assertNotNull("Should be valid element", element);
|
||||||
|
|
||||||
|
KtFile file = (KtFile) getFile();
|
||||||
|
|
||||||
|
long oobBeforeType = KotlinCodeBlockModificationListenerKt.getOutOfBlockModificationCount(file);
|
||||||
|
long modificationCountBeforeType = tracker.getModificationCount();
|
||||||
|
|
||||||
|
myFixture.type(getStringToType());
|
||||||
|
PsiDocumentManager.getInstance(myFixture.getProject()).commitDocument(myFixture.getDocument(myFixture.getFile()));
|
||||||
|
|
||||||
|
long oobAfterCount = KotlinCodeBlockModificationListenerKt.getOutOfBlockModificationCount(file);
|
||||||
|
long modificationCountAfterType = tracker.getModificationCount();
|
||||||
|
|
||||||
|
assertTrue("Modification tracker should always be changed after type", modificationCountBeforeType != modificationCountAfterType);
|
||||||
|
|
||||||
|
assertEquals("Result for out of block test is differs from expected on element in file:\n" + FileUtil.loadFile(new File(path)),
|
||||||
|
expectedOutOfBlock, oobBeforeType != oobAfterCount);
|
||||||
|
|
||||||
|
if (!isSkipCheckDefined) {
|
||||||
|
checkOOBWithDescriptorsResolve(expectedOutOfBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOOBWithDescriptorsResolve(boolean expectedOutOfBlock) {
|
||||||
|
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
((PsiModificationTrackerImpl) PsiManager.getInstance(myFixture.getProject()).getModificationTracker())
|
||||||
|
.incOutOfCodeBlockModificationCounter();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
PsiElement updateElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset() - 1);
|
||||||
|
KtExpression ktExpression = PsiTreeUtil.getParentOfType(updateElement, KtExpression.class, false);
|
||||||
|
KtDeclaration ktDeclaration = PsiTreeUtil.getParentOfType(updateElement, KtDeclaration.class, false);
|
||||||
|
KtElement ktElement = ktExpression != null ? ktExpression : ktDeclaration;
|
||||||
|
|
||||||
|
if (ktElement == null) return;
|
||||||
|
|
||||||
|
ResolutionFacade facade = ResolutionUtils.getResolutionFacade(ktElement.getContainingKtFile());
|
||||||
|
ResolveSession session = facade.getFrontendService(ResolveSession.class);
|
||||||
|
session.forceResolveAll();
|
||||||
|
|
||||||
|
BindingContext context = session.getBindingContext();
|
||||||
|
|
||||||
|
if (ktExpression != null && ktExpression != ktDeclaration) {
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
boolean expressionProcessed = context.get(
|
||||||
|
BindingContext.PROCESSED,
|
||||||
|
ktExpression instanceof KtFunctionLiteral ? (KtLambdaExpression) ktExpression.getParent() : ktExpression) == Boolean.TRUE;
|
||||||
|
|
||||||
|
assertEquals("Expected out-of-block should result expression analyzed and vise versa", expectedOutOfBlock,
|
||||||
|
expressionProcessed);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boolean declarationProcessed = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration) != null;
|
||||||
|
assertEquals("Expected out-of-block should result declaration analyzed and vise versa", expectedOutOfBlock,
|
||||||
|
declarationProcessed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringToType() {
|
||||||
|
String text = myFixture.getDocument(myFixture.getFile()).getText();
|
||||||
|
String typeDirectives = InTextDirectivesUtils.findStringWithPrefixes(text, "TYPE:");
|
||||||
|
|
||||||
|
return typeDirectives != null ? StringUtil.unescapeStringCharacters(typeDirectives) : "a";
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getExpectedOutOfBlockResult() {
|
||||||
|
String text = myFixture.getDocument(myFixture.getFile()).getText();
|
||||||
|
|
||||||
|
boolean expectedOutOfBlock = false;
|
||||||
|
if (text.startsWith("// TRUE")) {
|
||||||
|
expectedOutOfBlock = true;
|
||||||
|
}
|
||||||
|
else if (text.startsWith("// FALSE")) {
|
||||||
|
expectedOutOfBlock = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail("Expectation of code block result test should be configured with " +
|
||||||
|
"\"// TRUE\" or \"// FALSE\" directive in the beginning of the file");
|
||||||
|
}
|
||||||
|
return expectedOutOfBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
+120
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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.generate
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.actions.CodeInsightAction
|
||||||
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
|
import com.intellij.openapi.actionSystem.Presentation
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
|
import com.intellij.testFramework.PlatformTestUtil
|
||||||
|
import com.intellij.testFramework.TestActionEvent
|
||||||
|
import junit.framework.ComparisonFailure
|
||||||
|
import junit.framework.TestCase
|
||||||
|
import org.jetbrains.kotlin.idea.project.forcedTargetPlatform
|
||||||
|
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.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
|
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractCodeInsightActionTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
|
protected open fun createAction(fileText: String): CodeInsightAction {
|
||||||
|
val actionClassName = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// ACTION_CLASS: ")
|
||||||
|
return Class.forName(actionClassName).newInstance() as CodeInsightAction
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun configure(mainFilePath: String, mainFileText: String) {
|
||||||
|
myFixture.configureByFile(fileName()) as KtFile
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun checkExtra() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun testAction(action: AnAction, forced: Boolean): Presentation {
|
||||||
|
val e = TestActionEvent(action)
|
||||||
|
action.beforeActionPerformedUpdate(e)
|
||||||
|
if (forced || (e.presentation.isEnabled && e.presentation.isVisible)) {
|
||||||
|
action.actionPerformed(e)
|
||||||
|
}
|
||||||
|
return e.presentation
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun doTest(path: String) {
|
||||||
|
val fileText = FileUtil.loadFile(File(path), true)
|
||||||
|
|
||||||
|
val conflictFile = File("$path.messages")
|
||||||
|
val afterFile = File("$path.after")
|
||||||
|
|
||||||
|
var mainPsiFile: KtFile? = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
ConfigLibraryUtil.configureLibrariesByDirective(module, PlatformTestUtil.getCommunityPath(), fileText)
|
||||||
|
|
||||||
|
val mainFile = File(path)
|
||||||
|
val mainFileName = mainFile.name
|
||||||
|
val fileNameBase = mainFile.nameWithoutExtension + "."
|
||||||
|
val rootDir = mainFile.parentFile
|
||||||
|
rootDir
|
||||||
|
.list { _, name ->
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -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<String>, actual: List<String>): 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user