//! P1 工具结果瘦身 — 端到端集成验证。 //! //! 独立测试二进制(独立进程):`tool_offload::init_base` 的 OnceLock 全局态不外泄, //! 不污染 lib 单测(反之亦然)。这是验证「超阈值 → 落盘句柄 → 可无损读回」全链的唯一安全方式。 use df_ai::context_helpers::{extract_key_info, READ_FILE_OFFLOAD_BYTES}; use df_ai::tool_offload; fn tmp_base(tag: &str) -> std::path::PathBuf { std::env::temp_dir().join(format!("df-ai-ctx-offload-{tag}-{}", std::process::id())) } /// 从句柄行里粗取落盘路径(格式:`[...已外置: —— ...]`)。 fn path_of(handle_line: &str) -> String { handle_line .split("已外置: ") .nth(1) .and_then(|s| s.split(" ——").next()) .expect("句柄行应含路径") .trim() .to_string() } #[test] fn large_read_file_summarized_with_lossless_handle() { let base = tmp_base("large"); let _ = std::fs::remove_dir_all(&base); tool_offload::init_base(base.clone()); // 造一个超阈值的 read_file 结果(代码风格多行文本) let body: String = (1..=800) .map(|i| format!("line {i}: fn sample_{i}() {{ let x = {i}; }}\n")) .collect(); assert!(body.len() > READ_FILE_OFFLOAD_BYTES, "夹具须超阈值"); let out = extract_key_info(&body, "read_file"); assert!(out.len() < body.len(), "超阈值 read_file 应被压缩"); assert!(out.contains("已外置"), "应追加落盘句柄:\n{out}"); assert!(out.contains("read_file 读该路径"), "句柄应指引读回方式"); // 无损性:按句柄路径读回 = 原文逐字节一致 let line = out.lines().find(|l| l.contains("已外置")).expect("应有句柄行"); let back = tool_offload::read_offloaded(&path_of(line)).expect("句柄路径应可读回"); assert_eq!(back, body, "落盘原文须与输入逐字节一致(无损)"); // 摘要确实变小(瘦身生效) let ratio = out.len() as f64 / body.len() as f64; assert!(ratio < 0.2, "压缩比应显著(<0.2),实际 {ratio:.3}"); let _ = std::fs::remove_dir_all(&base); } #[test] fn small_read_file_still_exempt() { let base = tmp_base("small"); tool_offload::init_base(base); let small = "line1: fn a() {}\nline2: fn b() {}\n"; assert_eq!( extract_key_info(small, "read_file"), small, "阈值内 read_file 应原样返回(保 AI 定向读代码语义)" ); } #[test] fn non_read_file_large_result_also_gets_handle() { let base = tmp_base("other"); let _ = std::fs::remove_dir_all(&base); tool_offload::init_base(base.clone()); // 中性行夹具:不得含 error/panic/.rs: 等错误行信号——错误行保留策略会全量保留 // 命中行,用信号行做夹具会让「应被压缩」断言先天不成立(测的是普通大结果外置) let body: String = (1..=1200).map(|i| format!("match {i}: src/foo.txt:{i}\n")).collect(); assert!(body.len() >= 8 * 1024, "夹具须 ≥8KB(句柄追加下限)"); let out = extract_key_info(&body, "grep"); assert!(out.len() < body.len(), "应被压缩"); assert!(out.contains("已外置"), "≥8KB 结果应带落盘句柄"); let line = out.lines().find(|l| l.contains("已外置")).expect("应有句柄行"); assert_eq!( tool_offload::read_offloaded(&path_of(line)).expect("应可读回"), body ); let _ = std::fs::remove_dir_all(&base); }