use koala_core::invariant::Context;
use koala_drift::{format_github_annotations, Registry as DriftRegistry};
use std::fs;
use tempfile::TempDir;
fn write(dir: &std::path::Path, rel: &str, body: &str) {
let p = dir.join(rel);
fs::create_dir_all(p.parent().unwrap()).unwrap();
fs::write(p, body).unwrap();
}
#[test]
fn cli_emits_annotations_with_line() {
let tmp = TempDir::new().unwrap();
let body = "---\n\
id: x\n\
status: in-progress\n\
---\n\
# X\n\n\
## Acceptance criteria(机械可验证)\n\n\
- [ ] does the thing\n\
→ crates/x/tests/missing.rs#none\n";
write(tmp.path(), "wiki/features/x.md", body);
let ctx = Context::new(tmp.path().to_path_buf());
let reg = DriftRegistry::builtin();
let findings = reg.run_all(&ctx);
let out = format_github_annotations(&findings);
assert!(
out.contains("::error"),
"expected ::error annotation: {out}"
);
assert!(
out.contains("file=wiki/features/x.md"),
"expected file= field: {out}"
);
assert!(
out.contains("line=10"),
"expected line=10 (the `→` row): {out}"
);
assert!(
out.contains("[feature.acceptance-test-ref]"),
"expected check id label: {out}"
);
}
#[test]
fn empty_findings_emits_no_lines() {
let tmp = TempDir::new().unwrap();
let ctx = Context::new(tmp.path().to_path_buf());
let reg = DriftRegistry::builtin();
let findings = reg.run_all(&ctx);
let out = format_github_annotations(&findings);
assert!(
out.is_empty(),
"expected empty output for clean repo: {out}"
);
}
#[test]
fn advisory_findings_use_warning_level() {
let tmp = TempDir::new().unwrap();
let dir = tmp.path().join("wiki/decisions");
fs::create_dir_all(&dir).unwrap();
fs::write(
dir.join("0001-bootstrap.md"),
"---\n\
id: 0001\n\
title: Bootstrap\n\
status: accepted\n\
date: 2024-01-01\n\
---\n\n\
# ADR-0001\n",
)
.unwrap();
let ctx = Context::new(tmp.path().to_path_buf());
let reg = DriftRegistry::builtin();
let findings = reg.run_all(&ctx);
let out = format_github_annotations(&findings);
if findings
.iter()
.any(|f| matches!(f.severity, koala_drift::Severity::Advisory))
{
assert!(
out.contains("::warning"),
"advisory finding should map to ::warning: {out}"
);
}
}