1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-03-09 11:30:11 +08:00

Add multiplatform DynamicTest

This commit is contained in:
Him188 2022-07-18 02:42:06 +08:00
parent 3bcdf9b640
commit 699718f958
4 changed files with 147 additions and 0 deletions
mirai-core/src
commonTest/kotlin/testFramework
jvmBaseTest/kotlin
nativeTest/kotlin/testFramework

View File

@ -0,0 +1,68 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmName("DynamicTestKt_common")
package net.mamoe.mirai.internal.testFramework
import kotlin.jvm.JvmName
import kotlin.test.Test
/**
* Annotates a function to be a [Test] factory that returns a [DynamicTestsResult].
*
* On JVM, this delegates to JUnit's `TestFactory`. On Native, test functions are executed in-place.
*
* Tips: To run [TestFactory]s in IDEA, you can press `Ctrl + Shift + R`(for both macOS and Windows) with caret in the test function.
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
expect annotation class TestFactory()
/**
* @see dynamicTest
*/
expect open class DynamicTest // = junit.DynamicTest
/**
* @see runDynamicTests
*/
expect class DynamicTestsResult
/**
* Creates a dynamic test
*/
expect fun dynamicTest(displayName: String, action: () -> Unit): DynamicTest
/**
* The returned value must be returned from the function annotated with [TestFactory], otherwise the tests won't be executed on some platforms.
*/
expect fun runDynamicTests(dynamicTests: List<DynamicTest>): DynamicTestsResult
/**
* The returned value must be returned from the function annotated with [TestFactory], otherwise the tests won't be executed on some platforms.
*/
fun runDynamicTests(vararg dynamicTests: Iterable<DynamicTest>): DynamicTestsResult =
runDynamicTests(dynamicTests = dynamicTests.flatMap { it })
/**
* The returned value must be returned from the function annotated with [TestFactory], otherwise the tests won't be executed on some platforms.
*/
fun runDynamicTests(vararg dynamicTests: Sequence<DynamicTest>): DynamicTestsResult =
runDynamicTests(dynamicTests = dynamicTests.flatMap { it })
/**
* The returned value must be returned from the function annotated with [TestFactory], otherwise the tests won't be executed on some platforms.
*/
fun runDynamicTests(vararg dynamicTests: DynamicTest): DynamicTestsResult = runDynamicTests(dynamicTests.toList())
/**
* The returned value must be returned from the function annotated with [TestFactory], otherwise the tests won't be executed on some platforms.
*/
fun runDynamicTests(dynamicTests: Sequence<DynamicTest>): DynamicTestsResult = runDynamicTests(dynamicTests.toList())

View File

@ -13,15 +13,38 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.debug.DebugProbes
import net.mamoe.mirai.IMirai
import net.mamoe.mirai.internal.network.framework.SynchronizedStdoutLogger
import net.mamoe.mirai.internal.testFramework.DynamicTest
import net.mamoe.mirai.internal.testFramework.TestFactory
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.setSystemProp
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.TestInfo
import org.junit.jupiter.api.Timeout
import java.util.concurrent.TimeUnit
import kotlin.jvm.optionals.getOrNull
import kotlin.reflect.full.functions
import kotlin.reflect.full.hasAnnotation
@Timeout(value = 7, unit = TimeUnit.MINUTES)
internal actual abstract class AbstractTest actual constructor() : CommonAbstractTest() {
@OptIn(ExperimentalCoroutinesApi::class)
actual companion object {
@OptIn(ExperimentalStdlibApi::class)
@BeforeAll
private fun checkTestFactories(testInfo: TestInfo) {
val clazz = testInfo.testClass.getOrNull()?.kotlin ?: return
for (function in clazz.functions) {
if (function.hasAnnotation<TestFactory>()) {
check(function.returnType.classifier == List::class) {
"Illegal TestFactory function. A such function must return DynamicTestsResult."
}
check(function.returnType.arguments.singleOrNull()?.type?.classifier == DynamicTest::class) {
"Illegal TestFactory function. A such function must return DynamicTestsResult."
}
}
}
}
init {
initPlatform()

View File

@ -0,0 +1,24 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.testFramework
actual typealias TestFactory = org.junit.jupiter.api.TestFactory
actual typealias DynamicTest = org.junit.jupiter.api.DynamicTest
@Suppress("ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE", "ACTUAL_WITHOUT_EXPECT")
actual typealias DynamicTestsResult = List<*>
actual fun dynamicTest(displayName: String, action: () -> Unit): DynamicTest {
return DynamicTest.dynamicTest(displayName, action)
}
actual fun runDynamicTests(dynamicTests: List<DynamicTest>): DynamicTestsResult = dynamicTests

View File

@ -0,0 +1,32 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.testFramework
import kotlin.test.Test
actual typealias TestFactory = Test
actual open class DynamicTest(
val displayName: String,
val action: () -> Unit,
)
@Suppress("ACTUAL_WITHOUT_EXPECT")
actual typealias DynamicTestsResult = Unit
actual fun dynamicTest(displayName: String, action: () -> Unit): DynamicTest = DynamicTest(displayName, action)
actual fun runDynamicTests(dynamicTests: List<DynamicTest>) {
for (dynamicTest in dynamicTests) {
println("=".repeat(32) + " ${dynamicTest.displayName} " + "=".repeat(32))
dynamicTest.action.invoke()
println("=".repeat(32) + "=".repeat(dynamicTest.displayName.length + 2) + "=".repeat(32))
}
}