Files
AndroidJetpack/animeko/datasource/api/test-codegen/src/TestGenerator.kt
T
coco 723ce1af5c a
2026-07-03 15:12:48 +08:00

135 lines
5.3 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package me.him188.ani.datasources.api.test.codegen
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.TypeSpec
import kotlinx.serialization.json.Json
import me.him188.ani.datasources.api.test.codegen.main.TestData
import me.him188.ani.datasources.api.topic.Topic
import me.him188.ani.datasources.api.topic.titles.ParsedTopicTitle
import me.him188.ani.datasources.api.topic.titles.RawTitleParser
import me.him188.ani.datasources.api.topic.titles.parse
val json = Json {
ignoreUnknownKeys = true
prettyPrint = true
}
class TopicSet(
val topics: List<Topic>,
)
class TestSuite(
val originalName: String,
val dataSource: String,
val name: String,
val cases: List<TestCase>
)
class TestCase(
val name: String,
val title: String,
val parsed: ParsedTopicTitle,
)
class TestGenerator(
private val parser: RawTitleParser
) {
fun createSuite(testData: TestData): TestSuite {
fun String.sanitize() = replace("%", "_")
.replace(".", "_")
.replace("-", "_")
.replace("!", "_")
.replace("", "_")
.replace("", "_")
return TestSuite(
originalName = testData.originalName.sanitize(),
name = testData.kotlinClassName.sanitize(),
dataSource = testData.dataSource,
cases = testData.topics.map {
TestCase(
name = it.id.removeSuffix(".html").sanitize(),
title = it.rawTitle,
parsed = parser.parse(it.rawTitle),
)
},
)
}
// 这库真是各种难用
fun generateSuite(suite: TestSuite): FileSpec = FileSpec.builder(
"", // 他会创建目录层级
"PatternTitleParserTest${suite.name}",
).apply {
addAnnotation(
AnnotationSpec.builder(ClassName.bestGuess("Suppress")).apply {
addMember("\"FunctionName\"")
addMember("\"ClassName\"")
addMember("\"RedundantVisibilityModifier\"")
addMember("\"PackageDirectoryMismatch\"")
addMember("\"NonAsciiCharacters\"")
addMember("\"SpellCheckingInspection\"")
}.build(),
)
addImport("me.him188.ani.datasources.api.title", "PatternBasedTitleParserTestSuite")
addImport("kotlin.test", "assertEquals") // 它不允许 "*"
addImport("me.him188.ani.datasources.api", "SubtitleKind") // 它不允许 "*"
addType(
TypeSpec.classBuilder(
ClassName(
"me.him188.ani.datasources.api.title.generated", // 这库并不会写出 package
"PatternTitleParserTest${suite.name}",
),
).apply {
addKdoc(
"""
原名: `${suite.originalName}`
数据源: `${suite.dataSource}`
由 `test-codegen` 的 `GenerateTests.kt` 生成, 不要手动修改!
如果你优化了解析器, 这些 test 可能会失败, 请检查是否它是因为以前解析错误而现在解析正确了.
如果是, 请更新测试数据: 执行 `GenerateTests.kt`.
""".trimIndent(),
)
superclass(ClassName("me.him188.ani.datasources.api.title", "PatternBasedTitleParserTestSuite"))
for (case in suite.cases) case.parsed.run {
addFunction(
FunSpec.builder(case.name)
.addAnnotation(ClassName.bestGuess("kotlin.test.Test"))
// 这库会自动 wrap code, 如果不写 %S 就可能出问题
// 他不会自动换行, 必须要有 + "\n"
.addCode(
"""val r = parse(%S)""" + "\n", case.title,
)
.addCode("assertEquals(%S, r.episodeRange.toString())" + "\n", episodeRange.toString())
.addCode(
"assertEquals(%S, r.subtitleLanguages.sortedBy { it.id }.joinToString { it.id })" + "\n",
subtitleLanguages.sortedBy { it.id }.joinToString { it.id },
)
.addCode(
"assertEquals(%S, r.resolution.toString())" + "\n",
resolution.toString(),
)
.run {
if (subtitleKind == null) {
addCode("assertEquals(null, r.subtitleKind)" + "\n")
} else {
addCode(
"assertEquals(SubtitleKind.%L, r.subtitleKind)" + "\n",
subtitleKind,
)
}
}
.build(),
)
}
}.build(),
)
}.build()
}
private const val Q = "\"\"\""