///|
/// 联调结果收集与最终报告。
///
/// 每测一个端点就调用 `check` 记一条结果(同时打一行「测了什么、结果如何」),
/// 程序结束时 `report_summary` 汇总通过 / 失败 / 跳过的数量与明细。原始 JSON 由
/// `console.mbt` 的 `dump_raw` 作为证据打在结论之后。
///|
/// 单条结果的状态。
pub enum CaseStatus {
Passed
Failed
Skipped
}
///|
/// 状态名。
pub fn CaseStatus::name(self : CaseStatus) -> String {
match self {
Passed => "通过"
Failed => "失败"
Skipped => "跳过"
}
}
///|
/// 一条端点的测试结果。
pub struct CaseResult {
seq : Int
api : String
label : String
status : CaseStatus
detail : String
}
///|
/// 本次联调的全部结果(模块级单例,进程内有效)。
let cases : Array[CaseResult] = []
///|
/// 记一条结果并打一行结果行。
async fn record(
api : String,
label : String,
status : CaseStatus,
detail : String,
) -> Unit {
let seq = cases.length() + 1
cases.push({ seq, api, label, status, detail, })
let mark = match status {
Passed => "✔"
Failed => "✗"
Skipped => "-"
}
@stdio.stdout.write(
"[\{seq}] \{mark} \{CaseStatus::name(status)} \{api} | \{label}:\{detail}\n",
)
}
///|
/// 测一个类型化调用:打结果行并记录;成功时把值返回给调用方继续用。
pub async fn[T] check(
api : String,
label : String,
outcome : Result[T, @lib.OpenListError],
show : (T) -> String,
) -> T? {
match outcome {
Ok(value) => {
record(api, label, Passed, show(value))
Some(value)
}
Err(error) => {
record(api, label, Failed, error.message())
None
}
}
}
///|
/// 记一条「跳过」(权限不够、环境不满足等)。
pub async fn skip(api : String, label : String, reason : String) -> Unit {
record(api, label, Skipped, reason)
}
///|
/// 打最终测试报告:总数、通过 / 失败 / 跳过,以及失败与跳过的明细。
pub async fn report_summary() -> Unit {
section("测试汇总")
let mut passed = 0
let mut failed = 0
let mut skipped_count = 0
let failed_lines : Array[String] = []
let skipped_lines : Array[String] = []
for item in cases {
match item.status {
Passed => passed = passed + 1
Failed => {
failed = failed + 1
failed_lines.push(
" ✗ [\{item.seq}] \{item.api} | \{item.label}:\{item.detail}",
)
}
Skipped => {
skipped_count = skipped_count + 1
skipped_lines.push(
" - [\{item.seq}] \{item.api} | \{item.label}:\{item.detail}",
)
}
}
}
say(
"共测 \{cases.length()} 项:通过 \{passed},失败 \{failed},跳过 \{skipped_count}",
)
if !failed_lines.is_empty() {
say("失败明细:")
say(failed_lines.join("\n"))
}
if !skipped_lines.is_empty() {
say("跳过明细:")
say(skipped_lines.join("\n"))
}
if failed == 0 && skipped_count == 0 {
say("全部通过。")
}
}