forked from mamoe/mirai
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Eritque arcus <[email protected]> Co-authored-by: Him188 <[email protected]>
- Loading branch information
1 parent
2eb2c3a
commit 2db9804
Showing
85 changed files
with
8,018 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Mirai - Mocking | ||
|
||
本章节介绍 mirai 模拟环境 | ||
|
||
> mirai 模拟环境从 `2.13` 开始支持 | ||
> | ||
> 注: | ||
> - **不支持**同时运行模拟环境和真实环境 | ||
> - **不支持**从模拟环境切换回真实环境 | ||
----------------------------------- | ||
|
||
# 在非 console 中进行模拟 | ||
|
||
## 环境准备 | ||
|
||
要使用 mirai 模拟环境测试框架, 首先需要额外添加一项依赖 | ||
|
||
```kotlin | ||
dependencies { | ||
testImplementation("net.mamoe:mirai-core-mock:$VERSION") | ||
} | ||
``` | ||
|
||
并在本地的测试入口添加以下的代码 | ||
|
||
```kotlin | ||
internal fun main() { | ||
MockBotFactory.initialize() | ||
// ..... | ||
} | ||
``` | ||
|
||
## 创建 Bot | ||
|
||
对于创建 `MockBot`, 更好的方法是使用 `MockBotFactory.newMockBotBuilder()` | ||
|
||
也可以使用原始的 `BotFactory` 来创建一个新的 `MockBot`, 系统会使用默认值填充相关的信息 | ||
|
||
## 使用 | ||
|
||
关于 `MockBot` 可以在 [这里](https://github.com/mamoe/mirai/tree/dev/mirai-core-mock/test/mock) | ||
找到 mirai-core-mock 的相关用法 | ||
|
||
---------------- | ||
|
||
# 在 console 中进行模拟 | ||
|
||
Work In Progress... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# mirai-core-mock | ||
|
||
mirai 模拟环境测试框架 | ||
|
||
> 模拟环境目前仅支持 JVM | ||
-------------- | ||
|
||
# src 架构 | ||
|
||
- `contact` - 与 `mirai-core-api` 架构一致 | ||
- `database` - 数据库, 用于存储一些临时的零碎数据 | ||
- `resserver` - 资源服务 | ||
- `userprofile` - 与 `UserProfile` 相关的一些服务 | ||
- `utils` - 工具类 | ||
|
||
# test 架构 | ||
|
||
- `<toplevel>` 与 mirai-core-api 关系不大或者一些独立的组件的测试 | ||
- `.mock` 模拟的各个部分的测试, 每个测试都继承 `MockBotTestBase` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* 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 | ||
*/ | ||
|
||
|
||
plugins { | ||
kotlin("jvm") | ||
kotlin("plugin.serialization") | ||
`maven-publish` | ||
id("me.him188.kotlin-jvm-blocking-bridge") | ||
} | ||
|
||
version = Versions.project | ||
description = "Mirai core mock testing framework" | ||
|
||
kotlin { | ||
explicitApiWarning() | ||
} | ||
|
||
dependencies { | ||
api(project(":mirai-core-api")) | ||
implementation(project(":mirai-core-utils")) | ||
implementation(project(":mirai-core")) | ||
|
||
implementation(`ktor-server-core`) | ||
implementation(`ktor-server-netty`) | ||
implementation(`java-in-memory-file-system`) | ||
|
||
} | ||
|
||
configurePublishing("mirai-core-mock") | ||
tasks.named("shadowJar") { enabled = false } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* 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.mock | ||
|
||
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge | ||
import net.mamoe.mirai.Bot | ||
import net.mamoe.mirai.contact.Friend | ||
import net.mamoe.mirai.contact.Group | ||
import net.mamoe.mirai.contact.MemberPermission | ||
import net.mamoe.mirai.contact.User | ||
import net.mamoe.mirai.event.broadcast | ||
import net.mamoe.mirai.event.events.* | ||
import net.mamoe.mirai.message.MessageReceipt | ||
import net.mamoe.mirai.message.data.MessageChain | ||
import net.mamoe.mirai.message.data.MessageSource | ||
import net.mamoe.mirai.message.data.OnlineMessageSource | ||
import net.mamoe.mirai.message.data.source | ||
import net.mamoe.mirai.mock.contact.MockFriend | ||
import net.mamoe.mirai.mock.contact.MockNormalMember | ||
import net.mamoe.mirai.mock.contact.MockStranger | ||
import net.mamoe.mirai.mock.contact.MockUserOrBot | ||
import net.mamoe.mirai.mock.database.removeMessageInfo | ||
import net.mamoe.mirai.mock.utils.NudgeDsl | ||
import net.mamoe.mirai.mock.utils.mock | ||
import net.mamoe.mirai.mock.utils.nudged0 | ||
import net.mamoe.mirai.utils.cast | ||
|
||
@JvmBlockingBridge | ||
public object MockActions { | ||
|
||
/** | ||
* 修改 [MockUserOrBot.nick] 并广播相关事件 (如 [FriendNickChangedEvent]) | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireNickChanged(target: MockUserOrBot, value: String) { | ||
when (target) { | ||
is MockFriend -> { | ||
val ov = target.nick | ||
target.mockApi.nick = value | ||
FriendNickChangedEvent(target, ov, target.nick).broadcast() | ||
} | ||
|
||
is MockStranger -> { | ||
target.mockApi.nick = value | ||
// TODO: StrangerNickChangedEvent | ||
} | ||
|
||
is MockNormalMember -> { | ||
val friend0 = target.bot.getFriend(target.id) | ||
if (friend0 != null) { | ||
return fireNickChanged(friend0, value) | ||
} | ||
target.mockApi.nick = value | ||
} | ||
|
||
is MockBot -> { | ||
target.nick = value | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* 修改 [MockNormalMember.nameCard] 并广播 [MemberCardChangeEvent] | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireNameCardChanged(member: MockNormalMember, value: String) { | ||
val ov = member.nameCard | ||
member.mockApi.nameCard = value | ||
MemberCardChangeEvent(ov, value, member).broadcast() | ||
} | ||
|
||
/** | ||
* 修改 [MockNormalMember.specialTitle] 并广播 [MemberSpecialTitleChangeEvent] | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireSpecialTitleChanged(member: MockNormalMember, value: String) { | ||
val ov = member.specialTitle | ||
member.mockApi.specialTitle = value | ||
MemberSpecialTitleChangeEvent( | ||
ov, | ||
value, | ||
member, | ||
operator = member.group.owner.takeIf { it.id != member.bot.id }, | ||
).broadcast() | ||
} | ||
|
||
/** | ||
* 修改一名成员的权限并广播 [MemberPermissionChangeEvent] | ||
*/ | ||
@JvmStatic | ||
public suspend fun firePermissionChanged(member: MockNormalMember, perm: MemberPermission) { | ||
if (perm == MemberPermission.OWNER || member == member.group.owner) { | ||
error("Use group.changeOwner to modify group owner") | ||
} | ||
val ov = member.permission | ||
member.mockApi.permission = perm | ||
if (member.id == member.bot.id) { | ||
BotGroupPermissionChangeEvent(member.group, ov, perm) | ||
} else { | ||
MemberPermissionChangeEvent(member, ov, perm) | ||
}.broadcast() | ||
} | ||
|
||
/** | ||
* 令 [operator] 撤回一条消息 | ||
* | ||
* @param operator 当 [operator] 为 null 时代表是发送者自己撤回 | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireMessageRecalled(chain: MessageChain, operator: User? = null) { | ||
return fireMessageRecalled(chain.source, operator) | ||
} | ||
|
||
/** | ||
* 令 [operator] 撤回一条消息 | ||
* | ||
* @param operator 当 [operator] 为 null 时代表是发送者自己撤回 | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireMessageRecalled(source: MessageSource, operator: User? = null) { | ||
if (source is OnlineMessageSource) { | ||
val from = source.sender | ||
when (val target = source.target) { | ||
is Group -> { | ||
from.bot.mock().msgDatabase.removeMessageInfo(source) | ||
MessageRecallEvent.GroupRecall( | ||
source.bot, | ||
from.id, | ||
source.ids, | ||
source.internalIds, | ||
source.time, | ||
operator?.cast(), | ||
target, | ||
when (from) { | ||
is Bot -> target.botAsMember | ||
else -> from.cast() | ||
} | ||
).broadcast() | ||
return | ||
} | ||
|
||
is Friend -> { | ||
from.bot.mock().msgDatabase.removeMessageInfo(source) | ||
MessageRecallEvent.FriendRecall( | ||
source.bot, | ||
source.ids, | ||
source.internalIds, | ||
source.time, | ||
from.id, | ||
from.cast() | ||
).broadcast() | ||
return | ||
} | ||
} | ||
} | ||
error("Unsupported message source type: ${source.javaClass}") | ||
} | ||
|
||
/** | ||
* 令 [operator] 撤回一条消息 | ||
* | ||
* @param operator 当 [operator] 为 null 时代表是发送者自己撤回 | ||
*/ | ||
@JvmStatic | ||
public suspend fun mockFireRecalled(receipt: MessageReceipt<*>, operator: User? = null) { | ||
return fireMessageRecalled(receipt.source, operator) | ||
} | ||
|
||
/** | ||
* 令 [actor] 戳一下 [actee] | ||
* | ||
* @param actor 发起戳一戳的人 | ||
* @param actee 被戳的人 | ||
*/ | ||
@JvmStatic | ||
public suspend fun fireNudge(actor: MockUserOrBot, actee: MockUserOrBot, dsl: NudgeDsl) { | ||
actor.nudged0(actee, dsl) | ||
} | ||
|
||
} |
Oops, something went wrong.