Minor: cleanup KotlinLightCodeInsightFixtureTestCase.kt

This commit is contained in:
Nikolay Krasko
2018-10-02 18:15:16 +03:00
parent d8fda8b153
commit ea9d4037e6
4 changed files with 82 additions and 328 deletions
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.psi.PsiClassOwner
import com.intellij.psi.PsiJavaFile import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import com.intellij.psi.search.FileTypeIndex import com.intellij.psi.search.FileTypeIndex
@@ -77,6 +78,8 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
} }
}) })
} }
fixTemplates()
} }
override fun tearDown() { override fun tearDown() {
@@ -92,8 +95,7 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
} }
} }
override fun getProjectDescriptor(): LightProjectDescriptor override fun getProjectDescriptor(): LightProjectDescriptor = getProjectDescriptorFromFileDirective()
= getProjectDescriptorFromFileDirective()
protected fun getProjectDescriptorFromAnnotation(): LightProjectDescriptor { protected fun getProjectDescriptorFromAnnotation(): LightProjectDescriptor {
val testMethod = this::class.java.getDeclaredMethod(name) val testMethod = this::class.java.getDeclaredMethod(name)
@@ -108,66 +110,62 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
protected fun getProjectDescriptorFromTestName(): LightProjectDescriptor { protected fun getProjectDescriptorFromTestName(): LightProjectDescriptor {
val testName = StringUtil.toLowerCase(getTestName(false)) val testName = StringUtil.toLowerCase(getTestName(false))
if (testName.endsWith("runtime")) { return when {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE testName.endsWith("runtime") -> KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
testName.endsWith("stdlib") -> ProjectDescriptorWithStdlibSources.INSTANCE
else -> KotlinLightProjectDescriptor.INSTANCE
} }
else if (testName.endsWith("stdlib")) {
return ProjectDescriptorWithStdlibSources.INSTANCE
}
return KotlinLightProjectDescriptor.INSTANCE
} }
protected fun getProjectDescriptorFromFileDirective(): LightProjectDescriptor { private fun getProjectDescriptorFromFileDirective(): LightProjectDescriptor {
if (!isAllFilesPresentInTest()) { if (isAllFilesPresentInTest()) return KotlinLightProjectDescriptor.INSTANCE
try {
val fileText = FileUtil.loadFile(File(testDataPath, fileName()), true)
val withLibraryDirective = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "WITH_LIBRARY:") try {
if (!withLibraryDirective.isEmpty()) { val fileText = FileUtil.loadFile(File(testDataPath, fileName()), true)
return SdkAndMockLibraryProjectDescriptor(
PluginTestCaseBase.getTestDataPathBase() + "/" + withLibraryDirective.get( val withLibraryDirective = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "WITH_LIBRARY:")
0 return when {
), true !withLibraryDirective.isEmpty() ->
SdkAndMockLibraryProjectDescriptor(
PluginTestCaseBase.getTestDataPathBase() + "/" + withLibraryDirective[0],
true
) )
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SOURCES")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SOURCES") ->
return ProjectDescriptorWithStdlibSources.INSTANCE ProjectDescriptorWithStdlibSources.INSTANCE
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_KOTLIN_TEST")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_KOTLIN_TEST") ->
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_KOTLIN_TEST KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_KOTLIN_TEST
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_FULL_JDK")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_FULL_JDK") ->
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_REFLECT")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_REFLECT") ->
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_REFLECT KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_REFLECT
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SCRIPT_RUNTIME")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SCRIPT_RUNTIME") ->
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_SCRIPT_RUNTIME KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_SCRIPT_RUNTIME
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME") || InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME") ||
InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_RUNTIME")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_RUNTIME") ->
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "JS")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "JS") ->
return KotlinStdJSProjectDescriptor KotlinStdJSProjectDescriptor
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "ENABLE_MULTIPLATFORM")) { InTextDirectivesUtils.isDirectiveDefined(fileText, "ENABLE_MULTIPLATFORM") ->
return KotlinProjectDescriptorWithFacet.KOTLIN_STABLE_WITH_MULTIPLATFORM KotlinProjectDescriptorWithFacet.KOTLIN_STABLE_WITH_MULTIPLATFORM
}
} else -> KotlinLightProjectDescriptor.INSTANCE
catch (e: IOException) {
throw rethrow(e)
} }
} catch (e: IOException) {
throw rethrow(e)
} }
return KotlinLightProjectDescriptor.INSTANCE
} }
protected fun isAllFilesPresentInTest(): Boolean = KotlinTestUtils.isAllFilesPresentTest(getTestName(false)) protected fun isAllFilesPresentInTest(): Boolean = KotlinTestUtils.isAllFilesPresentTest(getTestName(false))
protected open fun fileName(): String protected open fun fileName(): String = KotlinTestUtils.getTestDataFileName(this::class.java, this.name) ?: (getTestName(false) + ".kt")
= KotlinTestUtils.getTestDataFileName(this::class.java, this.name) ?: (getTestName(false) + ".kt")
protected fun performNotWriteEditorAction(actionId: String): Boolean { protected fun performNotWriteEditorAction(actionId: String): Boolean {
val dataContext = (myFixture.editor as EditorEx).dataContext val dataContext = (myFixture.editor as EditorEx).dataContext
@@ -234,8 +232,7 @@ fun configureLanguageAndApiVersion(
languageVersion: String, languageVersion: String,
apiVersion: String? = null apiVersion: String? = null
) { ) {
val accessToken = WriteAction.start() WriteAction.run<Throwable> {
try {
val modelsProvider = IdeModifiableModelsProviderImpl(project) val modelsProvider = IdeModifiableModelsProviderImpl(project)
val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false)
facet.configureFacet(languageVersion, LanguageFeature.State.DISABLED, null, modelsProvider) facet.configureFacet(languageVersion, LanguageFeature.State.DISABLED, null, modelsProvider)
@@ -245,9 +242,6 @@ fun configureLanguageAndApiVersion(
KotlinCommonCompilerArgumentsHolder.getInstance(project).update { this.languageVersion = languageVersion } KotlinCommonCompilerArgumentsHolder.getInstance(project).update { this.languageVersion = languageVersion }
modelsProvider.commit() modelsProvider.commit()
} }
finally {
accessToken.finish()
}
} }
fun Project.allKotlinFiles(): List<KtFile> { fun Project.allKotlinFiles(): List<KtFile> {
@@ -264,7 +258,8 @@ fun Project.allJavaFiles(): List<PsiJavaFile> {
.filterIsInstance<PsiJavaFile>() .filterIsInstance<PsiJavaFile>()
} }
fun Project.findFileWithCaret() = fun Project.findFileWithCaret(): PsiClassOwner {
(allKotlinFiles() + allJavaFiles()).single { return (allKotlinFiles() + allJavaFiles()).single {
"<caret>" in VfsUtilCore.loadText(it.virtualFile) && !it.virtualFile.name.endsWith(".after") "<caret>" in VfsUtilCore.loadText(it.virtualFile) && !it.virtualFile.name.endsWith(".after")
} }
}
@@ -1,270 +0,0 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. 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.test
import com.intellij.codeInsight.CodeInsightTestCase
import com.intellij.codeInsight.daemon.impl.EditorTracker
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.actionSystem.ex.ActionManagerEx
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import com.intellij.psi.search.FileTypeIndex
import com.intellij.psi.search.ProjectScope
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.LoggedErrorProcessor
import org.apache.log4j.Logger
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.facet.configureFacet
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.COMPILER_ARGUMENTS_DIRECTIVE
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.JVM_TARGET_DIRECTIVE
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.LANGUAGE_VERSION_DIRECTIVE
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestMetadata
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.rethrow
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.reflect.full.findAnnotation
abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFixtureTestCaseBase() {
private val exceptions = ArrayList<Throwable>()
protected val module: Module get() = myFixture.module
protected open val captureExceptions = true
override fun setUp() {
super.setUp()
(StartupManager.getInstance(project) as StartupManagerImpl).runPostStartupActivities()
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory())
project.getComponent(EditorTracker::class.java)?.projectOpened()
invalidateLibraryCache(project)
if (captureExceptions) {
LoggedErrorProcessor.setNewInstance(object : LoggedErrorProcessor() {
override fun processError(message: String?, t: Throwable?, details: Array<out String>?, logger: Logger) {
exceptions.addIfNotNull(t)
super.processError(message, t, details, logger)
}
})
}
CodeInsightTestCase.fixTemplates()
}
override fun tearDown() {
LoggedErrorProcessor.restoreDefaultProcessor()
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory())
super.tearDown()
if (exceptions.isNotEmpty()) {
exceptions.forEach { it.printStackTrace() }
throw AssertionError("Exceptions in other threads happened")
}
}
override fun getProjectDescriptor(): LightProjectDescriptor
= getProjectDescriptorFromFileDirective()
protected fun getProjectDescriptorFromAnnotation(): LightProjectDescriptor {
val testMethod = this::class.java.getDeclaredMethod(name)
val platformId = testMethod.getAnnotation(ProjectDescriptorKind::class.java)?.value
return when (platformId) {
JDK_AND_MULTIPLATFORM_STDLIB_WITH_SOURCES -> KotlinJdkAndMultiplatformStdlibDescriptor.JDK_AND_MULTIPLATFORM_STDLIB_WITH_SOURCES
else -> throw IllegalStateException("Unknown value for project descriptor kind")
}
}
protected fun getProjectDescriptorFromTestName(): LightProjectDescriptor {
val testName = StringUtil.toLowerCase(getTestName(false))
if (testName.endsWith("runtime")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
}
else if (testName.endsWith("stdlib")) {
return ProjectDescriptorWithStdlibSources.INSTANCE
}
return KotlinLightProjectDescriptor.INSTANCE
}
protected fun getProjectDescriptorFromFileDirective(): LightProjectDescriptor {
if (!isAllFilesPresentInTest()) {
try {
val fileText = FileUtil.loadFile(File(testDataPath, fileName()), true)
val withLibraryDirective = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "WITH_LIBRARY:")
if (!withLibraryDirective.isEmpty()) {
return SdkAndMockLibraryProjectDescriptor(
PluginTestCaseBase.getTestDataPathBase() + "/" + withLibraryDirective.get(
0
), true
)
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SOURCES")) {
return ProjectDescriptorWithStdlibSources.INSTANCE
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_KOTLIN_TEST")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_KOTLIN_TEST
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_FULL_JDK")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_REFLECT")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_REFLECT
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_SCRIPT_RUNTIME")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_SCRIPT_RUNTIME
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME") ||
InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_RUNTIME")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "JS")) {
return KotlinStdJSProjectDescriptor
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "ENABLE_MULTIPLATFORM")) {
return KotlinProjectDescriptorWithFacet.KOTLIN_STABLE_WITH_MULTIPLATFORM
}
}
catch (e: IOException) {
throw rethrow(e)
}
}
return KotlinLightProjectDescriptor.INSTANCE
}
protected fun isAllFilesPresentInTest(): Boolean = KotlinTestUtils.isAllFilesPresentTest(getTestName(false))
protected open fun fileName(): String
= KotlinTestUtils.getTestDataFileName(this::class.java, this.name) ?: (getTestName(false) + ".kt")
protected fun performNotWriteEditorAction(actionId: String): Boolean {
val dataContext = (myFixture.editor as EditorEx).dataContext
val managerEx = ActionManagerEx.getInstanceEx()
val action = managerEx.getAction(actionId)
val event = AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, Presentation(), managerEx, 0)
action.update(event)
if (!event.presentation.isEnabled) {
return false
}
managerEx.fireBeforeActionPerformed(action, dataContext, event)
action.actionPerformed(event)
managerEx.fireAfterActionPerformed(action, dataContext, event)
return true
}
override fun getTestDataPath(): String {
return this::class.findAnnotation<TestMetadata>()?.value ?: super.getTestDataPath()
}
}
object CompilerTestDirectives {
const val LANGUAGE_VERSION_DIRECTIVE = "LANGUAGE_VERSION:"
const val JVM_TARGET_DIRECTIVE = "JVM_TARGET:"
const val COMPILER_ARGUMENTS_DIRECTIVE = "COMPILER_ARGUMENTS:"
val ALL_COMPILER_TEST_DIRECTIVES = listOf(LANGUAGE_VERSION_DIRECTIVE, JVM_TARGET_DIRECTIVE, COMPILER_ARGUMENTS_DIRECTIVE)
}
fun configureCompilerOptions(fileText: String, project: Project, module: Module) {
val version = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $LANGUAGE_VERSION_DIRECTIVE ")
val jvmTarget = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $JVM_TARGET_DIRECTIVE ")
val options = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $COMPILER_ARGUMENTS_DIRECTIVE ")
if (version != null || jvmTarget != null || options != null) {
configureLanguageAndApiVersion(project, module, version ?: LanguageVersion.LATEST_STABLE.versionString)
val facetSettings = KotlinFacet.get(module)!!.configuration.settings
if (jvmTarget != null) {
(facetSettings.compilerArguments as K2JVMCompilerArguments).jvmTarget = jvmTarget
}
if (options != null) {
val compilerSettings = facetSettings.compilerSettings ?: CompilerSettings().also {
facetSettings.compilerSettings = it
}
compilerSettings.additionalArguments = options
facetSettings.updateMergedArguments()
KotlinCompilerSettings.getInstance(project).update { this.additionalArguments = options }
}
}
}
fun configureLanguageAndApiVersion(
project: Project,
module: Module,
languageVersion: String,
apiVersion: String? = null
) {
val accessToken = WriteAction.start()
try {
val modelsProvider = IdeModifiableModelsProviderImpl(project)
val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false)
facet.configureFacet(languageVersion, LanguageFeature.State.DISABLED, null, modelsProvider)
if (apiVersion != null) {
facet.configuration.settings.apiLevel = LanguageVersion.fromVersionString(apiVersion)
}
KotlinCommonCompilerArgumentsHolder.getInstance(project).update { this.languageVersion = languageVersion }
modelsProvider.commit()
}
finally {
accessToken.finish()
}
}
fun Project.allKotlinFiles(): List<KtFile> {
val virtualFiles = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, ProjectScope.getProjectScope(this))
return virtualFiles
.map { PsiManager.getInstance(this).findFile(it) }
.filterIsInstance<KtFile>()
}
fun Project.allJavaFiles(): List<PsiJavaFile> {
val virtualFiles = FileTypeIndex.getFiles(JavaFileType.INSTANCE, ProjectScope.getProjectScope(this))
return virtualFiles
.map { PsiManager.getInstance(this).findFile(it) }
.filterIsInstance<PsiJavaFile>()
}
fun Project.findFileWithCaret() =
(allKotlinFiles() + allJavaFiles()).single {
"<caret>" in VfsUtilCore.loadText(it.virtualFile) && !it.virtualFile.name.endsWith(".after")
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("UnusedImport")
package org.jetbrains.kotlin.idea.test
// Unneeded in 181, but used in 173
// BUNCH: 181
internal fun fixTemplates() {
}
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("UnusedImport")
package org.jetbrains.kotlin.idea.test
import com.intellij.codeInsight.CodeInsightTestCase
// Unneeded in 181, but used in 173
// BUNCH: 181
fun fixTemplates() {
CodeInsightTestCase.fixTemplates()
}