internal/conformance 教程
本页面向添加或修改符合性前端的维护者,介绍前端如何借助 internal/conformance 的共享模型记录每个用例的结果、汇总一次运行、将其拆分为分片并把各分片合并回来。该包是 Luna-Flow/floating 的内部包,因此这些示例不会针对已发布的模块进行编译;它们是为模块内部代码编写的。
快速入门
在模块内部,于前端的 moon.pkg 中导入该包:
import {
"Luna-Flow/floating/internal/conformance",
}
为每个用例记录一个结果并汇总:
///|
test "summarize a run" {
let results = [
@conformance.CaseResult::executable("add001", true),
@conformance.CaseResult::executable("add002", false, message="expected 3, got 2"),
@conformance.CaseResult::new("add003", @conformance.Diagnostic("placeholder"), false),
]
let summary = @conformance.RunSummary::from_results(3, results)
inspect(summary.executable_cases(), content="2")
inspect(summary.failed_cases(), content="1")
inspect(summary.skipped_cases(), content="1")
inspect(summary.success(), content="false")
}
日常任务
选择处置类型
为每个被选中的用例赋予恰好一种处置类型:
Executable:用例已运行,passed表示结果;Diagnostic(reason):该语料行并非此类测试;Unsupported(reason):该行有效,但缺少相应功能;Legacy(reason):该行遵循旧的约定,不在声明范围之内。
被跳过的结果永远不会使 success() 失败,因此请如实选择 Unsupported:具有严格模式的运行器会把不支持的行变为失败的退出码。
对运行分片
将通过过滤器的用例编号为 ,并保留分片所选中的那些。将过滤后的用例数作为 total 传入:
///|
fn run_shard(ids : Array[String], shard : @conformance.ShardSpec) -> @conformance.RunSummary {
let results = []
for ordinal, id in ids {
if shard.selects(ordinal) {
results.push(@conformance.CaseResult::executable(id, true))
}
}
@conformance.RunSummary::from_results(ids.length(), results)
}
///|
test "shards merge to the serial run" {
let ids = ["a", "b", "c", "d", "e"]
let parts = [0, 1].map(i => run_shard(ids, @conformance.ShardSpec::new(2, i)))
let merged = @conformance.RunSummary::merge(parts)
inspect(merged.total_cases(), content="5")
inspect(merged.selected_cases(), content="5")
}
校验用户输入
命令行分片选项来自用户。请使用 ShardSpec::try_new 并将 Err 转为用法错误;ShardSpec::new 会直接中止。
将模型包装为前端类型
公开的前端不会直接暴露这些类型:gda_expr、mpfr_expr 和 testfloat_expr 将 CaseResult 和 RunSummary 包装在各自的结构体中,并转发它们想要公开的访问器。请遵循同样的模式,这样内部模型的变化就不会破坏前端 API。
深入了解
- 在包含该模块的工作区中运行该包的测试:
moon test -p Luna-Flow/floating/internal/conformance。 - internal/runner_cli 将共享的命令行选项(
--json、--shard-count、--shard-index)解析为ShardSpec。
常见陷阱
- total 错误。
total_cases应统计过滤之后、分片之前的用例数,在每个分片中都是同一个数;merge保留最大值。 - 负的序号。
selects使用%,结果保留序号的符号;请始终从 0 开始计数。 - 被跳过结果上的
passed。 计数器会忽略它;为清晰起见,请将其设为false。