2
0

TestMiraiConosle.kt 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright 2019-2021 Mamoe Technologies and contributors.
  3. *
  4. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  5. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
  6. *
  7. * https://github.com/mamoe/mirai/blob/dev/LICENSE
  8. */
  9. package net.mamoe.mirai.console
  10. import kotlinx.coroutines.*
  11. import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
  12. import net.mamoe.mirai.console.command.CommandManager
  13. import net.mamoe.mirai.console.data.MemoryPluginDataStorage
  14. import net.mamoe.mirai.console.data.PluginDataStorage
  15. import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
  16. import net.mamoe.mirai.console.plugin.loader.PluginLoader
  17. import net.mamoe.mirai.console.util.ConsoleInput
  18. import net.mamoe.mirai.console.util.ConsoleInternalApi
  19. import net.mamoe.mirai.console.util.SemVersion
  20. import net.mamoe.mirai.message.data.Message
  21. import net.mamoe.mirai.utils.BotConfiguration
  22. import net.mamoe.mirai.utils.LoginSolver
  23. import net.mamoe.mirai.utils.MiraiLogger
  24. import net.mamoe.mirai.utils.PlatformLogger
  25. import java.nio.file.Path
  26. import kotlin.coroutines.Continuation
  27. import kotlin.coroutines.CoroutineContext
  28. import kotlin.coroutines.resume
  29. import kotlin.io.path.createTempDirectory
  30. import kotlin.test.assertNotNull
  31. @OptIn(ConsoleInternalApi::class, kotlin.io.path.ExperimentalPathApi::class)
  32. fun initTestEnvironment() {
  33. object : MiraiConsoleImplementation {
  34. override val rootPath: Path = createTempDirectory()
  35. override val frontEndDescription: MiraiConsoleFrontEndDescription
  36. get() = object : MiraiConsoleFrontEndDescription {
  37. override val name: String
  38. get() = "Test"
  39. override val vendor: String
  40. get() = "Test"
  41. override val version: SemVersion
  42. get() = SemVersion("1.0.0")
  43. }
  44. override val builtInPluginLoaders: List<Lazy<PluginLoader<*, *>>> = listOf(lazy { JvmPluginLoader })
  45. override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl =
  46. object : MiraiConsoleImplementation.ConsoleCommandSenderImpl {
  47. override suspend fun sendMessage(message: Message) {
  48. println(message)
  49. }
  50. override suspend fun sendMessage(message: String) {
  51. println(message)
  52. }
  53. }
  54. override val dataStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage()
  55. override val configStorageForJvmPluginLoader: PluginDataStorage = MemoryPluginDataStorage()
  56. override val dataStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage()
  57. override val configStorageForBuiltIns: PluginDataStorage = MemoryPluginDataStorage()
  58. override val consoleInput: ConsoleInput = object : ConsoleInput {
  59. override suspend fun requestInput(hint: String): String {
  60. println(hint)
  61. return readLine() ?: error("No stdin")
  62. }
  63. }
  64. override fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver =
  65. LoginSolver.Default!!
  66. override fun createLogger(identity: String?): MiraiLogger {
  67. return PlatformLogger(identity)
  68. }
  69. override val coroutineContext: CoroutineContext = SupervisorJob() + CoroutineExceptionHandler { _, throwable ->
  70. throwable.printStackTrace()
  71. }
  72. }.start()
  73. CommandManager
  74. }
  75. internal object Testing {
  76. @Volatile
  77. internal var cont: Continuation<Any?>? = null
  78. @Suppress("UNCHECKED_CAST")
  79. suspend fun <R> withTesting(timeout: Long = 50000L, block: suspend () -> Unit): R {
  80. @Suppress("RemoveExplicitTypeArguments") // bug
  81. return if (timeout != -1L) {
  82. withTimeout<R>(timeout) {
  83. suspendCancellableCoroutine<R> { ct ->
  84. [email protected] = ct as Continuation<Any?>
  85. runBlocking { block() }
  86. }
  87. }
  88. } else {
  89. suspendCancellableCoroutine<R> { ct ->
  90. this.cont = ct as Continuation<Any?>
  91. runBlocking { block() }
  92. }
  93. }
  94. }
  95. fun ok(result: Any? = Unit) {
  96. val cont = cont
  97. assertNotNull(cont)
  98. cont.resume(result)
  99. }
  100. }