mirror of
https://github.com/LamGC/ScalaBot.git
synced 2025-04-30 06:37:29 +00:00
test(config): 补充相关的单元测试.
经检查, 已确定完全覆盖代码, 为完成单元测试的编写, 稍微改了一下 AppPaths 的代码, 不会有影响的 :P
This commit is contained in:
parent
8c4e48e3eb
commit
92b7e84b3a
@ -167,6 +167,21 @@ internal enum class AppPaths(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个内部方法, 用于将 [initialized] 状态重置.
|
||||||
|
*
|
||||||
|
* 如果不重置该状态, 将使得单元测试无法让 AppPath 重新初始化文件.
|
||||||
|
*
|
||||||
|
* 警告: 该方法不应该被非测试代码调用.
|
||||||
|
*/
|
||||||
|
@Suppress("unused")
|
||||||
|
private fun reset() {
|
||||||
|
log.warn {
|
||||||
|
"初始化状态已重置: `${this.name}`, 如果在非测试环境中重置状态, 请报告该问题."
|
||||||
|
}
|
||||||
|
initialized.set(false)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,38 @@ import com.github.stefanbirkner.systemlambda.SystemLambda
|
|||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
|
import mu.KotlinLogging
|
||||||
|
import net.lamgc.scalabot.config.MavenRepositoryConfig
|
||||||
|
import net.lamgc.scalabot.config.ProxyConfig
|
||||||
|
import net.lamgc.scalabot.config.ProxyType
|
||||||
|
import org.junit.jupiter.api.assertThrows
|
||||||
import org.junit.jupiter.api.io.TempDir
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
import org.telegram.telegrambots.bots.DefaultBotOptions
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.Test
|
import java.io.IOException
|
||||||
import kotlin.test.assertEquals
|
import java.net.URL
|
||||||
import kotlin.test.assertNotNull
|
import java.nio.file.Files
|
||||||
import kotlin.test.assertTrue
|
import java.nio.file.Path
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
internal class AppPathsTest {
|
internal class AppPathsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Data root path priority`() {
|
fun `Data root path priority`() {
|
||||||
System.setProperty("bot.path.data", "fromSystemProperties")
|
System.setProperty(AppPaths.PathConst.PROP_DATA_PATH, "fromSystemProperties")
|
||||||
|
|
||||||
assertEquals("fromSystemProperties", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有优先返回 Property 的值.")
|
assertEquals("fromSystemProperties", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有优先返回 Property 的值.")
|
||||||
System.getProperties().remove("bot.path.data")
|
System.getProperties().remove(AppPaths.PathConst.PROP_DATA_PATH)
|
||||||
|
|
||||||
val expectEnvValue = "fromEnvironmentVariable"
|
val expectEnvValue = "fromEnvironmentVariable"
|
||||||
SystemLambda.withEnvironmentVariable("BOT_DATA_PATH", expectEnvValue).execute {
|
SystemLambda.withEnvironmentVariable(AppPaths.PathConst.ENV_DATA_PATH, expectEnvValue).execute {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
expectEnvValue, AppPaths.DATA_ROOT.file.path,
|
expectEnvValue, AppPaths.DATA_ROOT.file.path,
|
||||||
"`DATA_ROOT`没有优先返回 env 的值."
|
"`DATA_ROOT`没有优先返回 env 的值."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemLambda.withEnvironmentVariable("BOT_DATA_PATH", null).execute {
|
SystemLambda.withEnvironmentVariable(AppPaths.PathConst.ENV_DATA_PATH, null).execute {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
System.getProperty("user.dir"), AppPaths.DATA_ROOT.file.path,
|
System.getProperty("user.dir"), AppPaths.DATA_ROOT.file.path,
|
||||||
"`DATA_ROOT`没有返回 System.properties `user.dir` 的值."
|
"`DATA_ROOT`没有返回 System.properties `user.dir` 的值."
|
||||||
@ -116,5 +123,270 @@ internal class AppPathsTest {
|
|||||||
defaultInitializerMethod.isAccessible = false
|
defaultInitializerMethod.isAccessible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@Test
|
||||||
|
fun `loadBotConfig test`(@TempDir testDir: File) {
|
||||||
|
assertNull(loadBotConfigJson(File("/NOT_EXISTS_FILE")), "加载 BotConfigs 失败时应该返回 null.")
|
||||||
|
|
||||||
|
SystemLambda.withEnvironmentVariable(AppPaths.PathConst.ENV_DATA_PATH, testDir.canonicalPath).execute {
|
||||||
|
assertNull(loadBotConfigJson(), "加载 BotConfigs 失败时应该返回 null.")
|
||||||
|
|
||||||
|
File(testDir, "bot.json").apply {
|
||||||
|
//language=JSON5
|
||||||
|
writeText(
|
||||||
|
"""
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"enabled": false,
|
||||||
|
"account": {
|
||||||
|
"name": "TestBot",
|
||||||
|
"token": "123456789:AAHErDroUTznQsOd_oZPJ6cQEj4Z5mGHO10",
|
||||||
|
"creatorId": 123456789
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 8080,
|
||||||
|
"type": "HTTP"
|
||||||
|
},
|
||||||
|
"disableBuiltInAbility": false,
|
||||||
|
"autoUpdateCommandList": true,
|
||||||
|
"extensions": [
|
||||||
|
"org.example.test:test-extension:1.0.0"
|
||||||
|
],
|
||||||
|
"baseApiUrl": "http://localhost:8080"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val botConfigJsons = loadBotConfigJson()
|
||||||
|
assertNotNull(botConfigJsons)
|
||||||
|
assertEquals(1, botConfigJsons.size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `loadAppConfig test`(@TempDir testDir: File) {
|
||||||
|
assertThrows<IOException>("加载失败时应该抛出 IOException.") {
|
||||||
|
loadAppConfig(File("/NOT_EXISTS_FILE"))
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemLambda.withEnvironmentVariable(AppPaths.PathConst.ENV_DATA_PATH, testDir.canonicalPath).execute {
|
||||||
|
assertThrows<IOException>("加载失败时应该抛出 IOException.") {
|
||||||
|
loadAppConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
File(testDir, "config.json").apply {
|
||||||
|
//language=JSON5
|
||||||
|
writeText(
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"proxy": {
|
||||||
|
"type": "HTTP",
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 8080
|
||||||
|
},
|
||||||
|
"metrics": {
|
||||||
|
"enable": true,
|
||||||
|
"port": 8800,
|
||||||
|
"bindAddress": "127.0.0.1",
|
||||||
|
"authenticator": {
|
||||||
|
"username": "username",
|
||||||
|
"password": "password"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mavenRepositories": [
|
||||||
|
{
|
||||||
|
"url": "https://repository.maven.apache.org/maven2/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mavenLocalRepository": "file:///tmp/maven-local-repository"
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val appConfigs = loadAppConfig()
|
||||||
|
assertNotNull(appConfigs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ProxyType_toTelegramBotsType test`() {
|
||||||
|
val expectTypeMapping = mapOf(
|
||||||
|
ProxyType.NO_PROXY to DefaultBotOptions.ProxyType.NO_PROXY,
|
||||||
|
ProxyType.SOCKS5 to DefaultBotOptions.ProxyType.SOCKS5,
|
||||||
|
ProxyType.SOCKS4 to DefaultBotOptions.ProxyType.SOCKS4,
|
||||||
|
ProxyType.HTTP to DefaultBotOptions.ProxyType.HTTP,
|
||||||
|
ProxyType.HTTPS to DefaultBotOptions.ProxyType.HTTP
|
||||||
|
)
|
||||||
|
|
||||||
|
for (proxyType in ProxyType.values()) {
|
||||||
|
assertEquals(
|
||||||
|
expectTypeMapping[proxyType],
|
||||||
|
proxyType.toTelegramBotsType(),
|
||||||
|
"ProxyType 转换失败."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ProxyConfig_toAetherProxy test`() {
|
||||||
|
val host = "proxy.example.org"
|
||||||
|
val port = 1080
|
||||||
|
|
||||||
|
val expectNotNullProxyType = setOf(
|
||||||
|
ProxyType.HTTP,
|
||||||
|
ProxyType.HTTPS
|
||||||
|
)
|
||||||
|
for (proxyType in ProxyType.values()) {
|
||||||
|
val proxyConfig = ProxyConfig(proxyType, host, port)
|
||||||
|
val aetherProxy = proxyConfig.toAetherProxy()
|
||||||
|
if (expectNotNullProxyType.contains(proxyType)) {
|
||||||
|
assertNotNull(aetherProxy, "支持的代理类型应该不为 null.")
|
||||||
|
assertEquals(host, aetherProxy.host)
|
||||||
|
assertEquals(port, aetherProxy.port)
|
||||||
|
} else {
|
||||||
|
assertNull(aetherProxy, "不支持的代理类型应该返回 null.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `MavenRepositoryConfig_toRemoteRepository test`() {
|
||||||
|
val defaultMavenRepositoryConfig = MavenRepositoryConfig(
|
||||||
|
url = URL(MavenRepositoryExtensionFinder.MAVEN_CENTRAL_URL),
|
||||||
|
enableReleases = true,
|
||||||
|
enableSnapshots = false
|
||||||
|
)
|
||||||
|
val remoteRepositoryWithoutId = defaultMavenRepositoryConfig.toRemoteRepository(
|
||||||
|
ProxyConfig(ProxyType.NO_PROXY, "", 0)
|
||||||
|
)
|
||||||
|
assertEquals(MavenRepositoryExtensionFinder.MAVEN_CENTRAL_URL, remoteRepositoryWithoutId.url.toString())
|
||||||
|
assertNotNull(remoteRepositoryWithoutId.id)
|
||||||
|
assertTrue(remoteRepositoryWithoutId.getPolicy(false).isEnabled)
|
||||||
|
assertFalse(remoteRepositoryWithoutId.getPolicy(true).isEnabled)
|
||||||
|
|
||||||
|
val remoteRepositoryWithId = defaultMavenRepositoryConfig.copy(id = "test-repo").toRemoteRepository(
|
||||||
|
ProxyConfig(ProxyType.HTTP, "127.0.0.1", 1080)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals("test-repo", remoteRepositoryWithId.id)
|
||||||
|
assertEquals(MavenRepositoryExtensionFinder.MAVEN_CENTRAL_URL, remoteRepositoryWithId.url.toString())
|
||||||
|
assertEquals("http", remoteRepositoryWithId.proxy.type)
|
||||||
|
assertEquals("127.0.0.1", remoteRepositoryWithId.proxy.host)
|
||||||
|
assertEquals(1080, remoteRepositoryWithId.proxy.port)
|
||||||
|
assertEquals(remoteRepositoryWithId.id, remoteRepositoryWithId.id)
|
||||||
|
|
||||||
|
val remoteRepositoryWithProxy = defaultMavenRepositoryConfig.copy(
|
||||||
|
id = "test-repo",
|
||||||
|
proxy = ProxyConfig(ProxyType.HTTP, "example.org", 1080).toAetherProxy()
|
||||||
|
).toRemoteRepository(ProxyConfig(ProxyType.HTTP, "localhost", 8080))
|
||||||
|
assertEquals("http", remoteRepositoryWithProxy.proxy.type)
|
||||||
|
assertEquals("example.org", remoteRepositoryWithProxy.proxy.host, "未优先使用 MavenRepositoryConfig 中的 proxy 属性.")
|
||||||
|
assertEquals(1080, remoteRepositoryWithProxy.proxy.port, "未优先使用 MavenRepositoryConfig 中的 proxy 属性.")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `checkRepositoryLayout test`() {
|
||||||
|
val noProxyConfig = ProxyConfig(ProxyType.NO_PROXY, "", 0)
|
||||||
|
assertEquals(
|
||||||
|
"default", MavenRepositoryConfig(url = URL("https://repo.example.org"))
|
||||||
|
.toRemoteRepository(noProxyConfig).contentType
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"legacy", MavenRepositoryConfig(url = URL("https://repo.example.org"), layout = "LEgaCY")
|
||||||
|
.toRemoteRepository(noProxyConfig).contentType
|
||||||
|
)
|
||||||
|
assertThrows<IllegalArgumentException> {
|
||||||
|
MavenRepositoryConfig(
|
||||||
|
url = URL("https://repo.example.org"),
|
||||||
|
layout = "NOT_EXISTS_LAYOUT"
|
||||||
|
).toRemoteRepository(noProxyConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initialFiles test`(@TempDir testDir: Path) {
|
||||||
|
// 这么做是为了让日志文件创建在其他地方, 由于日志文件在运行时会持续占用, 在 windows 中文件会被锁定,
|
||||||
|
// 导致测试框架无法正常清除测试所使用的临时文件夹.
|
||||||
|
val logsDir = Files.createTempDirectory("ammmmmm-logs-")
|
||||||
|
System.setProperty(AppPaths.PathConst.PROP_DATA_PATH, logsDir.toString())
|
||||||
|
assertEquals(logsDir.toString(), AppPaths.DATA_ROOT.path, "日志目录设定失败.")
|
||||||
|
KotlinLogging.logger("TEST").error { "日志占用.(无需理会), 日志目录: $logsDir" }
|
||||||
|
AppPaths.DATA_LOGS.file.listFiles { _, name -> name.endsWith(".log") }?.forEach {
|
||||||
|
it.deleteOnExit()
|
||||||
|
}
|
||||||
|
|
||||||
|
val fullInitializeDir = Files.createTempDirectory(testDir, "fullInitialize")
|
||||||
|
System.setProperty(AppPaths.PathConst.PROP_DATA_PATH, fullInitializeDir.toString())
|
||||||
|
assertEquals(fullInitializeDir.toString(), AppPaths.DATA_ROOT.path, "测试路径设定失败.")
|
||||||
|
|
||||||
|
assertTrue(initialFiles(), "方法未能提醒用户编辑初始配置文件.")
|
||||||
|
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertTrue(path.file.exists(), "文件未初始化成功: ${path.path}")
|
||||||
|
if (path.file.isFile) {
|
||||||
|
assertNotEquals(0, path.file.length(), "文件未初始化成功(大小为 0): ${path.path}")
|
||||||
|
}
|
||||||
|
path.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(initialFiles(), "方法试图在配置已初始化的情况下提醒用户编辑初始配置文件.")
|
||||||
|
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertTrue(path.file.exists(), "文件未初始化成功: ${path.path}")
|
||||||
|
if (path.file.isFile) {
|
||||||
|
assertNotEquals(0, path.file.length(), "文件未初始化成功(大小为 0): ${path.path}")
|
||||||
|
}
|
||||||
|
path.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(AppPaths.CONFIG_APPLICATION.file.delete(), "config.json 删除失败.")
|
||||||
|
assertFalse(initialFiles(), "方法试图在部分配置已初始化的情况下提醒用户编辑初始配置文件.")
|
||||||
|
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertTrue(path.file.exists(), "文件未初始化成功: ${path.path}")
|
||||||
|
if (path.file.isFile) {
|
||||||
|
assertNotEquals(0, path.file.length(), "文件未初始化成功(大小为 0): ${path.path}")
|
||||||
|
}
|
||||||
|
path.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(AppPaths.CONFIG_BOT.file.delete(), "bot.json 删除失败.")
|
||||||
|
assertFalse(initialFiles(), "方法试图在部分配置已初始化的情况下提醒用户编辑初始配置文件.")
|
||||||
|
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertTrue(path.file.exists(), "文件未初始化成功: ${path.path}")
|
||||||
|
if (path.file.isFile) {
|
||||||
|
assertNotEquals(0, path.file.length(), "文件未初始化成功(大小为 0): ${path.path}")
|
||||||
|
}
|
||||||
|
path.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(AppPaths.CONFIG_APPLICATION.file.delete(), "config.json 删除失败.")
|
||||||
|
assertTrue(AppPaths.CONFIG_BOT.file.delete(), "bot.json 删除失败.")
|
||||||
|
assertTrue(
|
||||||
|
initialFiles(),
|
||||||
|
"在主要配置文件(config.json 和 bot.json)不存在的情况下初始化文件后, 方法未能提醒用户编辑初始配置文件."
|
||||||
|
)
|
||||||
|
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertTrue(path.file.exists(), "文件未初始化成功: ${path.path}")
|
||||||
|
if (path.file.isFile) {
|
||||||
|
assertNotEquals(0, path.file.length(), "文件未初始化成功(大小为 0): ${path.path}")
|
||||||
|
}
|
||||||
|
path.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
System.getProperties().remove(AppPaths.PathConst.PROP_DATA_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun AppPaths.reset() {
|
||||||
|
val method = AppPaths::class.java.getDeclaredMethod("reset")
|
||||||
|
method.isAccessible = true
|
||||||
|
method.invoke(this)
|
||||||
|
method.isAccessible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user