Unfinished business
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 797acea..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="RunConfigurationProducerService">
- <option name="ignoredProducers">
- <set>
- <option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
- </set>
- </option>
- </component>
-</project>
\ No newline at end of file
diff --git a/libraries/kotlin.test/build.gradle.kts b/libraries/kotlin.test/build.gradle.kts
index fc76598..f01f1aa 100644
--- a/libraries/kotlin.test/build.gradle.kts
+++ b/libraries/kotlin.test/build.gradle.kts
@@ -55,6 +55,24 @@
extendsFrom(jsApiVariant)
}
+val wasmApiVariant by configurations.creating {
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ attributes {
+ attribute(Usage.USAGE_ATTRIBUTE, objects.named("kotlin-api"))
+ attribute(KotlinPlatformType.attribute, KotlinPlatformType.js)
+ }
+}
+val wasmRuntimeVariant by configurations.creating {
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ attributes {
+ attribute(Usage.USAGE_ATTRIBUTE, objects.named("kotlin-runtime"))
+ attribute(KotlinPlatformType.attribute, KotlinPlatformType.js)
+ }
+ extendsFrom(wasmApiVariant)
+}
+
val nativeApiVariant by configurations.creating {
isCanBeConsumed = true
isCanBeResolved = false
@@ -76,6 +94,7 @@
dependencies {
jvmApi(project(":kotlin-stdlib"))
jsApiVariant("$group:kotlin-test-js:$version")
+ wasmApiVariant("$group:kotlin-test-wasm:$version")
commonVariant("$group:kotlin-test-common:$version")
commonVariant("$group:kotlin-test-annotations-common:$version")
}
@@ -114,6 +133,8 @@
}
addVariantsFromConfiguration(jsApiVariant) { mapToOptional() }
addVariantsFromConfiguration(jsRuntimeVariant) { mapToOptional() }
+ addVariantsFromConfiguration(wasmApiVariant) { mapToOptional() }
+ addVariantsFromConfiguration(wasmRuntimeVariant) { mapToOptional() }
addVariantsFromConfiguration(nativeApiVariant) { mapToOptional() }
addVariantsFromConfiguration(commonVariant) { mapToOptional() }
}
@@ -236,6 +257,38 @@
}
}
+val (wasmApi, wasmRuntime) = listOf("api", "runtime").map { usage ->
+ configurations.create("wasm${usage.capitalize()}") {
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ attributes {
+ attribute(Usage.USAGE_ATTRIBUTE, objects.named("kotlin-$usage"))
+ attribute(KotlinPlatformType.attribute, KotlinPlatformType.js)
+ }
+ }
+}
+wasmRuntime.extendsFrom(wasmApi)
+
+dependencies {
+ wasmApi(project(":kotlin-stdlib-wasm"))
+}
+
+//artifacts {
+// val wasmJar = tasks.getByPath(":kotlin-test:kotlin-test-wasm:jsJar")
+// add(wasmApi.name, wasmJar)
+// add(wasmRuntime.name, wasmJar)
+//}
+
+val wasmComponent = componentFactory.adhoc("wasm").apply {
+ addVariantsFromConfiguration(wasmApi) {
+ mapToMavenScope("compile")
+ }
+ addVariantsFromConfiguration(wasmRuntime) {
+ mapToMavenScope("runtime")
+ }
+}
+
+
val commonMetadata by configurations.creating {
isCanBeConsumed = true
isCanBeResolved = false
@@ -306,6 +359,12 @@
artifact(tasks.getByPath(":kotlin-test:kotlin-test-js:sourcesJar") as Jar)
configureKotlinPomAttributes(project, "Kotlin Test for JS")
}
+ create("wasm", MavenPublication::class) {
+ artifactId = "kotlin-test-wasm"
+ from(wasmComponent)
+ //artifact(tasks.getByPath(":kotlin-test:kotlin-test-wasm:sourcesJar") as Jar)
+ configureKotlinPomAttributes(project, "Kotlin Test for WASM")
+ }
create("common", MavenPublication::class) {
artifactId = "kotlin-test-common"
from(commonMetadataComponent)
diff --git a/libraries/kotlin.test/js/it/js/jasmine-reporter.js b/libraries/kotlin.test/js/it/js/jasmine-reporter.js
index 8f43b69..ab95434 100644
--- a/libraries/kotlin.test/js/it/js/jasmine-reporter.js
+++ b/libraries/kotlin.test/js/it/js/jasmine-reporter.js
@@ -19,4 +19,4 @@
tester.pending(name);
}
}
-});
\ No newline at end of file
+})
\ No newline at end of file
diff --git a/libraries/kotlin.test/wasm/build.gradle.kt b/libraries/kotlin.test/wasm/build.gradle.kt
new file mode 100644
index 0000000..9faba69
--- /dev/null
+++ b/libraries/kotlin.test/wasm/build.gradle.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
+
+plugins {
+ kotlin("multiplatform")
+}
+
+val commonMainSources by task<Sync> {
+ from(
+ "$rootDir/libraries/kotlin.test/common/src",
+ "$rootDir/libraries/kotlin.test/annotations-common/src"
+ )
+ into("$buildDir/commonMainSources")
+}
+
+//val commonTestSources by task<Sync> {
+// from("$rootDir/libraries/kotlin.test/common/src/test/kotlin")
+// into("$buildDir/commonTestSources")
+//}
+
+val wasmMainSources by task<Sync> {
+ from("$rootDir/libraries/kotlin.test/wasm/src")
+ into("$buildDir/wasmMainSources")
+}
+
+kotlin {
+ js(IR) {
+ nodejs()
+ }
+
+ sourceSets {
+ val commonMain by getting {
+ dependencies {
+ api(project(":kotlin-stdlib-wasm"))
+ }
+ kotlin.srcDir(commonMainSources.get().destinationDir)
+ }
+// val commonTest by getting {
+// kotlin.srcDir(commonTestSources.get().destinationDir)
+// }
+ val jsMain by getting {
+ dependencies {
+ api(project(":kotlin-stdlib-wasm"))
+ }
+ kotlin.srcDir(wasmMainSources.get().destinationDir)
+ }
+ }
+}
+
+tasks.withType<KotlinCompile<*>>().configureEach {
+ kotlinOptions.freeCompilerArgs += listOf(
+ "-Xallow-kotlin-package",
+ "-opt-in=kotlin.ExperimentalMultiplatform",
+ "-opt-in=kotlin.contracts.ExperimentalContracts"
+ )
+}
+
+tasks.named("compileKotlinJs") {
+ (this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += "-Xir-module-name=kotlin-test"
+ dependsOn(commonMainSources)
+ dependsOn(wasmMainSources)
+}
+
+//tasks.named("compileTestKotlinJs") {
+// dependsOn(commonTestSources)
+//}
diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/Annotations.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/Annotations.kt
new file mode 100644
index 0000000..cf4cc2bd
--- /dev/null
+++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/Annotations.kt
@@ -0,0 +1,30 @@
+/*
+ * 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 kotlin.test
+
+/**
+ * Marks a function as a test.
+ */
+@Target(AnnotationTarget.FUNCTION)
+public actual annotation class Test
+
+/**
+ * Marks a test or a suite as ignored.
+ */
+@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
+public actual annotation class Ignore
+
+/**
+ * Marks a function to be invoked before each test.
+ */
+@Target(AnnotationTarget.FUNCTION)
+public actual annotation class BeforeTest
+
+/**
+ * Marks a function to be invoked after each test.
+ */
+@Target(AnnotationTarget.FUNCTION)
+public actual annotation class AfterTest
diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/BareAdapter.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/BareAdapter.kt
new file mode 100644
index 0000000..ac2cc74
--- /dev/null
+++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/BareAdapter.kt
@@ -0,0 +1,26 @@
+/*
+ * 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 kotlin.test.adapters
+
+import kotlin.test.FrameworkAdapter
+
+/**
+ * A fallback adapter for the case when no framework is detected.
+ */
+internal open class BareAdapter : FrameworkAdapter {
+
+ override fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
+ if (!ignored) {
+ suiteFn()
+ }
+ }
+
+ override fun test(name: String, ignored: Boolean, testFn: () -> Any?) {
+ if (!ignored) {
+ testFn()
+ }
+ }
+}
diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/DefaultWasmAsserter.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/DefaultWasmAsserter.kt
new file mode 100644
index 0000000..14d4282
--- /dev/null
+++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/DefaultWasmAsserter.kt
@@ -0,0 +1,98 @@
+/*
+ * 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 kotlin.test
+
+/**
+ * Describes the result of an assertion execution.
+ */
+public external interface AssertionResult {
+ val result: Boolean
+ val expected: Any?
+ val actual: Any?
+ val lazyMessage: () -> String?
+}
+
+internal var assertHook: (AssertionResult) -> Unit = { _ -> }
+
+internal object DefaultJsAsserter : Asserter {
+ private var e: Any? = undefined
+ private var a: Any? = undefined
+
+ override fun assertEquals(message: String?, expected: Any?, actual: Any?) {
+ e = expected
+ a = actual
+ super.assertEquals(message, expected, actual)
+ }
+
+ override fun assertNotEquals(message: String?, illegal: Any?, actual: Any?) {
+ e = illegal
+ a = actual
+ super.assertNotEquals(message, illegal, actual)
+ }
+
+ override fun assertSame(message: String?, expected: Any?, actual: Any?) {
+ e = expected
+ a = actual
+ super.assertSame(message, expected, actual)
+ }
+
+ override fun assertNotSame(message: String?, illegal: Any?, actual: Any?) {
+ e = illegal
+ a = actual
+ super.assertNotSame(message, illegal, actual)
+ }
+
+ override fun assertNull(message: String?, actual: Any?) {
+ a = actual
+ super.assertNull(message, actual)
+ }
+
+ override fun assertNotNull(message: String?, actual: Any?) {
+ a = actual
+ super.assertNotNull(message, actual)
+ }
+
+ override fun assertTrue(lazyMessage: () -> String?, actual: Boolean) {
+ if (!actual) {
+ failWithMessage(lazyMessage, null)
+ } else {
+ invokeHook(true, lazyMessage)
+ }
+ }
+
+ override fun assertTrue(message: String?, actual: Boolean) {
+ assertTrue({ message }, actual)
+ }
+
+ override fun fail(message: String?): Nothing {
+ fail(message, null)
+ }
+
+ @SinceKotlin("1.4")
+ override fun fail(message: String?, cause: Throwable?): Nothing {
+ failWithMessage({ message }, cause)
+ }
+
+ private inline fun failWithMessage(lazyMessage: () -> String?, cause: Throwable?): Nothing {
+ val message = lazyMessage()
+ invokeHook(false) { message }
+ throw AssertionErrorWithCause(message, cause)
+ }
+
+ private fun invokeHook(result: Boolean, lazyMessage: () -> String?) {
+ try {
+ assertHook(object : AssertionResult {
+ override val result: Boolean = result
+ override val expected: Any? = e
+ override val actual: Any? = a
+ override val lazyMessage: () -> String? = lazyMessage
+ })
+ } finally {
+ e = undefined
+ a = undefined
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/TestApi.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/TestApi.kt
new file mode 100644
index 0000000..92ebcfb0
--- /dev/null
+++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/TestApi.kt
@@ -0,0 +1,80 @@
+/*
+ * 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 kotlin.test
+
+import kotlin.test.adapters.*
+//
+///**
+// * Overrides current framework adapter with a provided instance of [FrameworkAdapter]. Use in order to support custom test frameworks.
+// *
+// * Also some string arguments are supported. Use "qunit" to set the adapter to [QUnit](https://qunitjs.com/), "mocha" for
+// * [Mocha](https://mochajs.org/), "jest" for [Jest](https://facebook.github.io/jest/),
+// * "jasmine" for [Jasmine](https://github.com/jasmine/jasmine), and "auto" to detect one of those frameworks automatically.
+// *
+// * If this function is not called, the test framework will be detected automatically (as if "auto" was passed).
+// *
+// */
+//internal fun setAdapter(adapter: dynamic) {
+// if (js("typeof adapter === 'string'")) {
+// NAME_TO_ADAPTER[adapter]?.let {
+// setAdapter(it.invoke())
+// } ?: throw IllegalArgumentException("Unsupported test framework adapter: '$adapter'")
+// } else {
+// currentAdapter = adapter
+// }
+//}
+//
+///**
+// * Use in order to define which action should be taken by the test framework on the [AssertionResult].
+// */
+//internal fun setAssertHook(hook: (AssertionResult) -> Unit) {
+// assertHook = hook
+//}
+
+/**
+ * The functions below are used by the compiler to describe the tests structure, e.g.
+ *
+ * suite('a suite', false, function() {
+ * suite('a subsuite', false, function() {
+ * test('a test', false, function() {...});
+ * test('an ignored/pending test', true, function() {...});
+ * });
+ * suite('an ignored/pending test', true, function() {...});
+ * });
+ */
+
+@JsName("suite")
+internal fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
+ currentAdapter.suite(name, ignored, suiteFn)
+}
+
+@JsName("test")
+internal fun test(name: String, ignored: Boolean, testFn: () -> Any?) {
+ currentAdapter.test(name, ignored, testFn)
+}
+
+internal var currentAdapter: FrameworkAdapter = BareAdapter()
+
+//internal fun adapter(): FrameworkAdapter {
+// val result = currentAdapter ?: detectAdapter()
+// currentAdapter = result
+// return result
+//}
+//
+//
+//internal fun detectAdapter() = when {
+// isQUnit() -> QUnitAdapter()
+// isJasmine() -> JasmineLikeAdapter()
+// else -> BareAdapter()
+//}
+//
+//internal val NAME_TO_ADAPTER: Map<String, () -> FrameworkAdapter> = mapOf(
+// "qunit" to ::QUnitAdapter,
+// "jasmine" to ::JasmineLikeAdapter,
+// "mocha" to ::JasmineLikeAdapter,
+// "jest" to ::JasmineLikeAdapter,
+// "auto" to ::detectAdapter
+//)
\ No newline at end of file
diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/WasmImpl.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/WasmImpl.kt
new file mode 100644
index 0000000..f6f6fdd
--- /dev/null
+++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/WasmImpl.kt
@@ -0,0 +1,45 @@
+/*
+ * 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 kotlin.test
+
+import kotlin.reflect.KClass
+
+/**
+ * Takes the given [block] of test code and _doesn't_ execute it.
+ *
+ * This keeps the code under test referenced, but doesn't actually test it until it is implemented.
+ */
+actual fun todo(block: () -> Unit) {
+ println("TODO at " + block)
+}
+
+/** Platform-specific construction of AssertionError with cause */
+@Suppress("NOTHING_TO_INLINE")
+internal actual inline fun AssertionErrorWithCause(message: String?, cause: Throwable?): AssertionError =
+ AssertionError(message, cause)
+
+
+@PublishedApi
+internal actual fun <T : Throwable> checkResultIsFailure(exceptionClass: KClass<T>, message: String?, blockResult: Result<Unit>): T {
+ blockResult.fold(
+ onSuccess = {
+ asserter.fail(messagePrefix(message) + "Expected an exception of $exceptionClass to be thrown, but was completed successfully.")
+ },
+ onFailure = { e ->
+ if (exceptionClass.isInstance(e)) {
+ @Suppress("UNCHECKED_CAST")
+ return e as T
+ }
+ asserter.fail(messagePrefix(message) + "Expected an exception of $exceptionClass to be thrown, but was $e", e)
+ }
+ )
+}
+
+
+/**
+ * Provides the JS implementation of asserter
+ */
+internal actual fun lookupAsserter(): Asserter = DefaultWasmAsserter
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index df59aca..baa62e7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -500,7 +500,8 @@
":kotlin-test",
":kotlin-test:kotlin-test-js",
":kotlin-test:kotlin-test-js-ir",
- ":kotlin-test:kotlin-test-js:kotlin-test-js-it"
+ ":kotlin-test:kotlin-test-js:kotlin-test-js-it",
+ ":kotlin-test:kotlin-test-wasm"
project(':kotlin-stdlib-common').projectDir = "$rootDir/libraries/stdlib/common" as File
project(':kotlin-stdlib').projectDir = "$rootDir/libraries/stdlib/jvm" as File
@@ -520,6 +521,7 @@
project(':kotlin-test:kotlin-test-js').projectDir = "$rootDir/libraries/kotlin.test/js" as File
project(':kotlin-test:kotlin-test-js-ir').projectDir = "$rootDir/libraries/kotlin.test/js-ir" as File
project(':kotlin-test:kotlin-test-js:kotlin-test-js-it').projectDir = "$rootDir/libraries/kotlin.test/js/it" as File
+ project(':kotlin-test:kotlin-test-wasm').projectDir = "$rootDir/libraries/kotlin.test/wasm" as File
}
include ":compiler:android-tests"