111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
//! 摘要与格式化辅助的测试。
|
||
//! Tests for summary & formatting helpers.
|
||
|
||
use focus_json::JsonValue;
|
||
use focus_tui::format::{
|
||
caret_position, display_width, format_duration, format_tokens, summarize_tool, truncate,
|
||
truncate_lines, wrap_text,
|
||
};
|
||
|
||
fn obj(pairs: &[(&str, JsonValue)]) -> JsonValue {
|
||
let mut o = JsonValue::obj();
|
||
for (k, v) in pairs {
|
||
o.insert(*k, v.clone()).ok();
|
||
}
|
||
o
|
||
}
|
||
|
||
#[test]
|
||
fn tool_summaries_show_concrete_content() {
|
||
// read → 路径 + 行范围。
|
||
// read → path + line range.
|
||
let args = obj(&[
|
||
("path", "src/main.rs".into()),
|
||
("startLine", 10u64.into()),
|
||
("endLine", 20u64.into()),
|
||
]);
|
||
assert_eq!(
|
||
summarize_tool("read", &args),
|
||
"read src/main.rs lines 10-20"
|
||
);
|
||
|
||
// write → 路径 + 字节数。
|
||
// write → path + byte count.
|
||
let args = obj(&[("path", "a.txt".into()), ("content", "hello world".into())]);
|
||
assert_eq!(summarize_tool("write", &args), "write a.txt (11 bytes)");
|
||
|
||
// edit → 路径 + 编辑数。
|
||
// edit → path + edit count.
|
||
let edits = JsonValue::Arr(vec![JsonValue::obj(), JsonValue::obj()]);
|
||
let args = obj(&[("path", "b.rs".into()), ("edits", edits)]);
|
||
assert_eq!(summarize_tool("edit", &args), "edit b.rs (2 edits)");
|
||
|
||
// shell → 命令(截断)。
|
||
// shell → the command (truncated).
|
||
let args = obj(&[("command", "cargo test --workspace".into())]);
|
||
assert_eq!(
|
||
summarize_tool("shell", &args),
|
||
"shell: cargo test --workspace"
|
||
);
|
||
|
||
// 未知工具 → 紧凑 JSON。
|
||
// Unknown tool → compact JSON.
|
||
let args = obj(&[("x", 1u64.into())]);
|
||
assert_eq!(summarize_tool("weird", &args), "weird {\"x\":1}");
|
||
}
|
||
|
||
#[test]
|
||
fn durations() {
|
||
assert_eq!(format_duration(0), "0ms");
|
||
assert_eq!(format_duration(450), "450ms");
|
||
assert_eq!(format_duration(12_300), "12.3s");
|
||
assert_eq!(format_duration(125_000), "2m 05s");
|
||
}
|
||
|
||
#[test]
|
||
fn token_formatting() {
|
||
assert_eq!(format_tokens(0), "0");
|
||
assert_eq!(format_tokens(999), "999");
|
||
assert_eq!(format_tokens(12_345), "12,345");
|
||
assert_eq!(format_tokens(1_000_000), "1,000,000");
|
||
}
|
||
|
||
#[test]
|
||
fn truncation() {
|
||
assert_eq!(truncate("hello", 10), "hello");
|
||
assert_eq!(truncate("hello world", 5), "hello…");
|
||
let multi = "a\nb\nc\nd\ne\nf\ng";
|
||
let out = truncate_lines(multi, 4, 100);
|
||
assert!(out.contains("truncated"), "got: {}", out);
|
||
assert!(out.contains('a'));
|
||
assert!(out.contains('g'));
|
||
}
|
||
|
||
#[test]
|
||
fn wrapping_and_width() {
|
||
assert_eq!(display_width("abc"), 3);
|
||
assert_eq!(display_width("中文"), 4);
|
||
let wrapped = wrap_text("aaaaaa", 3);
|
||
assert_eq!(wrapped, vec!["aaa".to_string(), "aaa".to_string()]);
|
||
// 保留显式换行。
|
||
// Preserve explicit newlines.
|
||
let wrapped = wrap_text("ab\ncd", 10);
|
||
assert_eq!(wrapped, vec!["ab".to_string(), "cd".to_string()]);
|
||
}
|
||
|
||
#[test]
|
||
fn caret_positioning() {
|
||
// 单行:caret 在末尾。
|
||
// Single line: caret at the end.
|
||
let (row, col, total) = caret_position("hello", 5, 10);
|
||
assert_eq!((row, col, total), (0, 5, 1));
|
||
// 换行后:caret 在第二行开头。
|
||
// After a newline: caret at the start of line 2.
|
||
let (row, col, total) = caret_position("ab\ncd", 3, 10);
|
||
assert_eq!((row, col, total), (1, 0, 2));
|
||
// 超宽行会折行。
|
||
// Over-wide lines wrap.
|
||
let (row, col, total) = caret_position("aaaaaa", 6, 3);
|
||
assert_eq!((row, col, total), (1, 3, 2));
|
||
}
|