[Wasm] Wasi kotlin.test implementation
This commit is contained in:
committed by
Zalim Bashorov
parent
8cc0660693
commit
18a9c1916e
@@ -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.
|
||||
*/
|
||||
|
||||
package kotlin.test
|
||||
|
||||
import kotlin.test.FrameworkAdapter
|
||||
import kotlin.js.Promise
|
||||
|
||||
// Need to wrap into additional lambdas so that js launcher will work without Mocha or any other testing framework
|
||||
private fun describe(name: String, fn: () -> Unit): Unit =
|
||||
js("describe(name, fn)")
|
||||
|
||||
private fun xdescribe(name: String, fn: () -> Unit): Unit =
|
||||
js("xdescribe(name, fn)")
|
||||
|
||||
private fun it(name: String, fn: () -> JsAny?): Unit =
|
||||
js("it(name, fn)")
|
||||
|
||||
private fun xit(name: String, fn: () -> JsAny?): Unit =
|
||||
js("xit(name, fn)")
|
||||
|
||||
private fun jsThrow(jsException: JsAny): Nothing =
|
||||
js("{ throw jsException; }")
|
||||
|
||||
private fun throwableToJsError(message: String, stack: String): JsAny =
|
||||
js("{ const e = new Error(); e.message = message; e.stack = stack; return e; }")
|
||||
|
||||
private fun Throwable.toJsError(): JsAny =
|
||||
throwableToJsError(message ?: "", stackTraceToString())
|
||||
|
||||
/**
|
||||
* [Jasmine](https://github.com/jasmine/jasmine) adapter.
|
||||
* Also used for [Mocha](https://mochajs.org/) and [Jest](https://facebook.github.io/jest/).
|
||||
*/
|
||||
internal class JasmineLikeAdapter : FrameworkAdapter {
|
||||
override fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
|
||||
if (ignored) {
|
||||
xdescribe(name, suiteFn)
|
||||
} else {
|
||||
describe(name, suiteFn)
|
||||
}
|
||||
}
|
||||
|
||||
private fun callTest(testFn: () -> Any?): JsAny? =
|
||||
try {
|
||||
(testFn() as? Promise<*>)?.catch { exception ->
|
||||
val jsException = exception
|
||||
.toThrowableOrNull()
|
||||
?.toJsError()
|
||||
?: exception
|
||||
Promise.reject(jsException)
|
||||
}
|
||||
} catch (exception: Throwable) {
|
||||
jsThrow(exception.toJsError())
|
||||
}
|
||||
|
||||
override fun test(name: String, ignored: Boolean, testFn: () -> Any?) {
|
||||
if (ignored) {
|
||||
xit(name) {
|
||||
callTest(testFn)
|
||||
}
|
||||
} else {
|
||||
it(name) {
|
||||
callTest(testFn)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.math.abs
|
||||
import kotlin.js.*
|
||||
|
||||
// Using 'globalThis.arguments' because 'arguments' can refer to current JS function arguments
|
||||
@JsFun("() => globalThis.arguments?.join?.(' ') ?? ''")
|
||||
private external fun d8Arguments(): String
|
||||
@JsFun("() => (typeof process != 'undefined' && typeof process.argv != 'undefined') ? process.argv.slice(2).join(' ') : ''")
|
||||
private external fun nodeArguments(): String
|
||||
|
||||
internal fun getArguments(): List<String> = (d8Arguments().ifEmpty { nodeArguments() }).split(' ')
|
||||
|
||||
internal class TeamcityAdapterWithPromiseSupport : TeamcityAdapter() {
|
||||
private var scheduleNextTaskAfter: Promise<JsAny?>? = null
|
||||
override fun runOrScheduleNext(block: () -> Unit) {
|
||||
if (scheduleNextTaskAfter == null) {
|
||||
block()
|
||||
} else {
|
||||
scheduleNextTaskAfter = scheduleNextTaskAfter!!.finally(block)
|
||||
}
|
||||
}
|
||||
|
||||
override fun runOrScheduleNextWithResult(block: () -> Any?) {
|
||||
val nextTask = scheduleNextTaskAfter
|
||||
if (nextTask == null) {
|
||||
val result = block()
|
||||
if (result is Promise<JsAny?>)
|
||||
scheduleNextTaskAfter = result
|
||||
} else {
|
||||
scheduleNextTaskAfter = nextTask.then {
|
||||
block() as? Promise<JsAny?>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tryProcessResult(result: Any?, name: String): Any? {
|
||||
if (result == null) return null
|
||||
if (result !is Promise<*>) return null
|
||||
|
||||
return result.then(
|
||||
onFulfilled = { value ->
|
||||
MessageType.Finished.report(name)
|
||||
value
|
||||
},
|
||||
onRejected = { e ->
|
||||
val throwable = e.toThrowableOrNull()
|
||||
if (throwable != null) {
|
||||
MessageType.Failed.report(name, throwable)
|
||||
} else {
|
||||
MessageType.Failed.report(name, e.toString())
|
||||
}
|
||||
MessageType.Finished.report(name)
|
||||
null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* Overrides current framework adapter with a provided instance of [FrameworkAdapter]. Use in order to support custom test frameworks.
|
||||
*
|
||||
* If this function is not called, the test framework will be detected automatically.
|
||||
*
|
||||
*/
|
||||
internal fun setAdapter(adapter: FrameworkAdapter) {
|
||||
currentAdapter = adapter
|
||||
}
|
||||
|
||||
internal var currentAdapter: FrameworkAdapter? = null
|
||||
|
||||
private fun isJasmine(): Boolean =
|
||||
js("typeof describe === 'function' && typeof it === 'function'")
|
||||
|
||||
internal fun adapter(): FrameworkAdapter {
|
||||
val result = currentAdapter ?: if (isJasmine()) JasmineLikeAdapter() else TeamcityAdapterWithPromiseSupport()
|
||||
currentAdapter = result
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user