Created AbstractKlibBinaryCompatibilityTest and AbstractJsKlibBinaryCompatibilityTest

A common test runner for klib binary compatibility tests
and its js counterpart
This commit is contained in:
Alexander Gorshenev
2021-01-14 15:51:20 +03:00
parent e7cf34a2a9
commit 16b3fedcd4
4 changed files with 448 additions and 1 deletions
@@ -8,7 +8,11 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.js.test.AbstractDceTest
import org.jetbrains.kotlin.js.test.AbstractJsLineNumberTest
import org.jetbrains.kotlin.js.test.es6.semantics.*
import org.jetbrains.kotlin.js.test.compatibility.binary.AbstractJsKlibBinaryCompatibilityTest
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrBoxJsES6Test
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsCodegenBoxES6Test
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsCodegenInlineES6Test
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsTypeScriptExportES6Test
import org.jetbrains.kotlin.js.test.ir.semantics.*
import org.jetbrains.kotlin.js.test.semantics.*
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenBoxWasmTest
@@ -124,5 +128,11 @@ fun main(args: Array<String>) {
model("codegen/box/arrays", targetBackend = TargetBackend.JS)
}
}
testGroup("js/js.tests/tests-gen", "compiler/testData/binaryCompatibility", testRunnerMethodName = "runTest0") {
testClass<AbstractJsKlibBinaryCompatibilityTest> {
model("klibEvolution", targetBackend = TargetBackend.JS_IR)
}
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2021 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.js.test.compatibility.binary
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.compatibility.binary.*
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.js.test.V8JsTestChecker
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
import java.io.File
abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompatibilityTest() {
override fun createEnvironment() =
KotlinCoreEnvironment.createForTests(testRootDisposable, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
private fun TestModule.name(version: Int) = if (this.hasVersions) "version$version/${this.name}" else this.name
private fun List<TestModule>.toLibrariesArg(version: Int): String {
val fileNames = this.map { it.name(version) }
val allDependencies = fileNames.map { File(workingDir, it.klib).absolutePath } + STDLIB_DEPENDENCY
return allDependencies.joinToString(File.pathSeparator)
}
private fun TestModule.dependenciesToLibrariesArg(version: Int): String =
this.dependencies.map { it as? TestModule ?: error("Unexpected dependency kind: $it") }.toLibrariesArg(version)
private val TestModule.jsPath get() = File(workingDir, "${this.name}.js").absolutePath
private fun createFiles(files: List<TestFile>): List<String> =
files.map {
val file = File(workingDir, it.name)
file.writeText(it.content)
file.absolutePath
}
private fun runnerFunctionFile(): String {
val file = File(workingDir, RUNNER_FUNCTION_FILE)
file.writeText(runnerFileText)
return file.absolutePath
}
override fun produceKlib(module: TestModule, version: Int) {
val args = K2JSCompilerArguments().apply {
freeArgs = createFiles(module.versionFiles(version))
libraries = module.dependenciesToLibrariesArg(version = version)
outputFile = File(workingDir, "${module.name(version)}.$KLIB_FILE_EXTENSION").absolutePath
irProduceKlibFile = true
irOnly = true
irModuleName = module.name
repositries = "$workingDir${File.pathSeparator}$workingDir/version$version"
}
K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args)
}
override fun produceProgram(module: TestModule) {
assert(!module.hasVersions)
val args = K2JSCompilerArguments().apply {
freeArgs = createFiles(module.files) + runnerFunctionFile()
libraries = module.dependenciesToLibrariesArg(version = 2)
outputFile = File(workingDir, module.name.js).absolutePath
irProduceJs = true
irOnly = true
irModuleName = module.name
repositries = "$workingDir${File.pathSeparator}$workingDir/version2"
}
K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args)
}
override fun runProgram(module: TestModule, expectedResult: String) {
testChecker.check(listOf(module.jsPath), module.name, null, RUNNER_FUNCTION, expectedResult, false)
}
// TODO: ask js folks what to use here.
protected open val testChecker get() = V8JsTestChecker
companion object {
private val String.klib: String get() = "$this.$KLIB_FILE_EXTENSION"
private val String.js: String get() = "$this.js"
private val STDLIB_DEPENDENCY = System.getProperty("kotlin.js.full.stdlib.path")
// A @JsExport wrapper for box().
// Otherwise box() is not available in js.
private const val RUNNER_FUNCTION = "__js_exported_wrapper_function"
private const val RUNNER_FUNCTION_FILE = "js_exported_wrapper_function.kt"
private val runnerFileText = """
@JsExport
fun $RUNNER_FUNCTION() = $TEST_FUNCTION()
"""
}
}
abstract class AbstractJsKlibBinaryCompatibilityErrorTest : AbstractJsKlibBinaryCompatibilityTest()
private class TestMessageCollector : MessageCollector {
override fun clear() {}
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
if (severity.isError()) error(message)
}
override fun hasErrors(): Boolean = error("Unsupported operation")
}