AbstractScriptConfigurationTest: rewrite script template setup

Allow simpler setup of common scenarios
Do not require to define DependenciesResolver for every test
Drop redundant template files
This commit is contained in:
Pavel V. Talanov
2017-09-06 18:04:10 +03:00
parent d7149a4083
commit 53144def10
21 changed files with 114 additions and 280 deletions
@@ -5,3 +5,5 @@ val g = listOf("a", "b", "c")
val time = measureNanoTime {
println("text")
}
// DEPENDENCIES: classpath:runtime-classes; imports:kotlin.system.*
@@ -1,25 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("runtime-classes") as File)
override val imports: Iterable<String> = listOf("kotlin.system.*")
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -6,3 +6,4 @@ doStuff(c1, c2)
doStuff(c1, <error>3</error>)
// DEPENDENCIES: classpath:lib-classes; imports:custom.library.*
@@ -1,28 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(
environment?.get("lib-classes") as File
)
override val imports: Iterable<String> = listOf("custom.library.*")
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -6,4 +6,6 @@ fun f(
<warning>i</warning>: JavaInterface.F.I
) {
}
}
// DEPENDENCIES: classpath:lib-classes; imports:custom.library.*
@@ -1,28 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(
environment?.get("lib-classes") as File
)
override val imports: Iterable<String> = listOf("custom.library.*")
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -4,4 +4,6 @@ val g = listOf("a", "b", "c")
val time = <error>measureNanoTime</error> {
println("text")
}
}
// DEPENDENCIES: classpath:runtime-classes
@@ -1,24 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("runtime-classes") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,3 +1,6 @@
test.Utils.fo<caret>o("asd")
// DEPENDENCIES: classpath:lib-classes
// REF: (in test.Utils).foo(String)
// FILE: test/Utils.class
@@ -1,24 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("lib-classes") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,3 +1,6 @@
test.Utils.fo<caret>o("asd")
// DEPENDENCIES: classpath:lib-classes; sources:lib-source
// REF: (in test.Utils).foo(String)
// FILE: test/Utils.java
@@ -1,25 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("lib-classes") as File)
override val sources: Iterable<File> = listOf(environment?.get("lib-source") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,3 +1,6 @@
test.KObject.<caret>foo()
// DEPENDENCIES: classpath:lib-classes
// REF: (in test.KObject).foo()
// FILE: test/KObject.class
@@ -1,24 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("lib-classes") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,3 +1,6 @@
test.KObject.<caret>foo()
// DEPENDENCIES: classpath:lib-classes; sources:lib-source
// REF: (in test.KObject).foo()
// FILE: test/custom.kt
@@ -1,25 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("lib-classes") as File)
override val sources: Iterable<File> = listOf(environment?.get("lib-source") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,4 +1,6 @@
val g = lis<caret>tOf("a", "b", "c")
// DEPENDENCIES: classpath:runtime-classes
// REF: (kotlin.collections).listOf(vararg T)
// FILE: collections/CollectionsKt.class
@@ -1,24 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("runtime-classes") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -1,4 +1,6 @@
val g = lis<caret>tOf("a", "b", "c")
// DEPENDENCIES: classpath:runtime-classes; sources:runtime-source
// REF: (kotlin.collections).listOf(vararg T)
// FILE: collections/Collections.kt
@@ -1,25 +0,0 @@
package custom.scriptDefinition
import kotlin.script.dependencies.*
import kotlin.script.templates.*
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future
class TestDependenciesResolver : ScriptDependenciesResolver {
override fun resolve(
script: ScriptContents,
environment: Map<String, Any?>?,
report: (ScriptDependenciesResolver.ReportSeverity, String, ScriptContents.Position?) -> Unit, previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> {
return CompletableFuture.completedFuture(
object : KotlinScriptExternalDependencies {
override val classpath: Iterable<File> = listOf(environment?.get("runtime-classes") as File)
override val sources: Iterable<File> = listOf(environment?.get("runtime-source") as File)
})
}
}
@ScriptTemplateDefinition(TestDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template
@@ -37,11 +37,18 @@ import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert
import java.io.File
import java.util.regex.Pattern
import kotlin.script.dependencies.Environment
import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.dependencies.asSuccess
import kotlin.script.templates.ScriptTemplateDefinition
abstract class AbstractScriptConfigurationHighlightingTest : AbstractScriptConfigurationTest() {
override fun doTest(path: String) {
configureScriptEnvironment(path)
registerScriptTemplateProvider(createScriptEnvironment(path))
super.doTest(setupScriptFile(path))
}
@@ -50,7 +57,7 @@ abstract class AbstractScriptConfigurationHighlightingTest : AbstractScriptConfi
abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigurationTest() {
override fun doTest(path: String) {
configureScriptEnvironment(path)
registerScriptTemplateProvider(createScriptEnvironment(path))
myFixture.configureFromExistingVirtualFile(setupScriptFile(path))
val reference = myFixture.getReferenceAtCaretPosition()!!
@@ -69,20 +76,56 @@ abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigu
}
}
private val validKeys = setOf("sources", "classpath", "imports")
private const val useDefaultTemplate = "// DEPENDENCIES:"
private fun String.splitOrEmpty(delimeters: String) = split(delimeters).takeIf { it.size > 1 } ?: emptyList()
private val switches = listOf(
useDefaultTemplate
)
abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() {
protected fun configureScriptEnvironment(path: String) {
val templateOutDir = compileLibToDir(
File("${path}template"),
PathUtil.kotlinPathsForDistDirectory.scriptRuntimePath.path
)
protected fun createScriptEnvironment(path: String): Environment {
val defaultEnvironment = defaultEnvironment(path)
val env = mutableMapOf<String, Any?>()
File("${path}script.kts").forEachLine { line ->
line.trim().takeIf { useDefaultTemplate in it }?.substringAfter(useDefaultTemplate)?.split(";")?.forEach { entry ->
val (key, values) = entry.splitOrEmpty(":").map { it.trim() }
assert(key in validKeys) { "Unexpected key: $key" }
env[key] = values.split(",").map {
val str = it.trim()
defaultEnvironment[str] ?: str
}
}
val libSrcDir = File("${path}lib")
val libClasses = if (libSrcDir.isDirectory) {
compileLibToDir(libSrcDir)
switches.forEach {
if (it in line) {
env[it] = true
}
}
}
else null
if (env[useDefaultTemplate] == true && defaultEnvironment["template-classes"] != null) {
error("Script configuration should be defined by either '$useDefaultTemplate' clause or via template in 'template' directory")
}
env.putAll(defaultEnvironment)
return env
}
registerScriptTemplateProvider(templateOutDir, libClasses, libSrcDir)
private fun defaultEnvironment(path: String): Map<String, File?> {
val templateOutDir = File("${path}template").takeIf { it.isDirectory }?.let {
compileLibToDir(it, PathUtil.kotlinPathsForDistDirectory.scriptRuntimePath.path)
}
val libSrcDir = File("${path}lib").takeIf { it.isDirectory }
val libClasses = libSrcDir?.let { compileLibToDir(it) }
return mapOf(
"runtime-classes" to ForTestCompileRuntime.runtimeJarForTests(),
"runtime-source" to File("libraries/stdlib/src"),
"lib-classes" to libClasses,
"lib-source" to libSrcDir,
"template-classes" to templateOutDir
)
}
protected fun setupScriptFile(path: String): VirtualFile {
@@ -112,17 +155,13 @@ abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() {
return outDir
}
private fun registerScriptTemplateProvider(templateDir: File, libClasses: File?, libSource: File?) {
val provider = TestScriptTemplateProvider(
templateDir,
mapOf(
"runtime-classes" to ForTestCompileRuntime.runtimeJarForTests(),
"runtime-source" to File("libraries/stdlib/src"),
"lib-classes" to libClasses,
"lib-source" to libSource,
"template-classes" to templateDir
)
)
protected fun registerScriptTemplateProvider(environment: Environment) {
val provider = if (environment[useDefaultTemplate] == true) {
FromTextTemplateProvider(environment)
}
else {
CustomScriptTemplateProvider(environment)
}
PlatformTestUtil.registerExtension(
Extensions.getArea(project),
@@ -136,12 +175,36 @@ abstract class AbstractScriptConfigurationTest : AbstractPsiCheckerTest() {
override fun getProjectDescriptor() = KotlinLightProjectDescriptor.INSTANCE
}
class TestScriptTemplateProvider(
compiledTemplateDir: File,
class CustomScriptTemplateProvider(
override val environment: Map<String, Any?>
) : ScriptTemplatesProvider {
override val id = "Test"
override val isValid = true
override val templateClassNames = listOf("custom.scriptDefinition.Template")
override val templateClasspath = listOf(compiledTemplateDir)
override val templateClasspath = listOfNotNull(environment["template-classes"] as? File)
}
class FromTextTemplateProvider(
override val environment: Map<String, Any?>
) : ScriptTemplatesProvider {
override val id = "Test"
override val isValid = true
override val templateClassNames = listOf("org.jetbrains.kotlin.idea.script.Template")
override val templateClasspath get() = emptyList<File>()
}
class FromTextDependenciesResolver : AsyncDependenciesResolver {
@Suppress("UNCHECKED_CAST")
suspend override fun resolveAsync(scriptContents: ScriptContents, environment: Environment): DependenciesResolver.ResolveResult {
return ScriptDependencies(
classpath = (environment["classpath"] as? List<File>).orEmpty(),
imports = (environment["imports"] as? List<String>).orEmpty(),
sources = (environment["sources"] as? List<File>).orEmpty()
).asSuccess()
}
}
@Suppress("unused")
@ScriptTemplateDefinition(FromTextDependenciesResolver::class, scriptFilePattern = "script.kts")
class Template