[Wasm] Mocha test framework support

This commit is contained in:
Igor Yakovlev
2022-12-16 19:06:19 +01:00
committed by teamcity
parent 4e24a9caa5
commit 8b14f4b15c
2 changed files with 46 additions and 9 deletions
@@ -6,19 +6,29 @@
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
@JsFun("(name, fn) => describe(name, fn)")
internal external fun describe(name: String, fn: () -> Unit)
private external fun describe(name: String, fn: () -> Unit)
@JsFun("(name, fn) => xdescribe(name, fn)")
internal external fun xdescribe(name: String, fn: () -> Unit)
private external fun xdescribe(name: String, fn: () -> Unit)
@JsFun("(name, fn) => it(name, fn)")
internal external fun it(name: String, fn: () -> Any?)
private external fun it(name: String, fn: () -> Any?)
@JsFun("(name, fn) => xit(name, fn)")
internal external fun xit(name: String, fn: () -> Any?)
private external fun xit(name: String, fn: () -> Any?)
@JsFun("(e) => { throw e }")
private external fun jsThrow(jsException: Dynamic)
@JsFun("(message, stack) => { const e = new Error(); e.message = message; e.stack = stack; return e; }")
private external fun throwableToJsError(message: String, stack: String): Dynamic
private fun Throwable.toJsError(): Dynamic =
throwableToJsError(message ?: "", stackTraceToString())
/**
* [Jasmine](https://github.com/jasmine/jasmine) adapter.
@@ -33,11 +43,29 @@ internal class JasmineLikeAdapter : FrameworkAdapter {
}
}
private fun callTest(testFn: () -> Any?): Any? =
try {
(testFn() as? Promise<*>)?.catch { exception ->
val jsException = exception
.toThrowableOrNull()
?.let { it.toJsError() }
?: exception
Promise.reject(jsException) as Dynamic
}
} catch (exception: Throwable) {
jsThrow(exception.toJsError())
null
}
override fun test(name: String, ignored: Boolean, testFn: () -> Any?) {
if (ignored) {
xit(name, testFn)
xit(name) {
callTest(testFn)
}
} else {
it(name, testFn)
it(name) {
callTest(testFn)
}
}
}
}
@@ -30,14 +30,23 @@ internal fun setAdapter(adapter: FrameworkAdapter) {
*/
internal fun suite(name: String, ignored: Boolean, suiteFn: () -> Unit) {
currentAdapter.suite(name, ignored, suiteFn)
adapter().suite(name, ignored, suiteFn)
}
internal fun test(name: String, ignored: Boolean, testFn: () -> Any?) {
currentAdapter.test(name, ignored, testFn)
adapter().test(name, ignored, testFn)
}
internal var currentAdapter: FrameworkAdapter = TeamcityAdapter()
internal var currentAdapter: FrameworkAdapter? = null
@JsFun("() => typeof describe === 'function' && typeof it === 'function'")
private external fun isJasmine(): Boolean
internal fun adapter(): FrameworkAdapter {
val result = currentAdapter ?: if (isJasmine()) JasmineLikeAdapter() else TeamcityAdapter()
currentAdapter = result
return result
}
// This is called from the js-launcher alongside wasm start function
@JsExport