Files
yvgude--lean-ctx/rust/tests/cli_anti_inflation.rs
T
wehub-resource-sync 26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

79 lines
3.1 KiB
Rust

//! End-to-end anti-inflation guarantee for the additive one-shot CLI read path
//! (#361). An independent benchmark measured the *CLI* surface (the pi default),
//! yet only the MCP `cap_to_raw` invariant had a test. This exercises the
//! SHIPPED binary end-to-end (resolver → frame → cap → print) and proves that
//! `lean-ctx read <file> --mode auto` can never emit more tokens than the bare
//! file. It complements the in-process `cap_cli_to_raw` unit tests in
//! `cli::read_cmd`.
use std::path::Path;
use std::process::Command;
use lean_ctx::core::tokens::count_tokens;
/// Runs `lean-ctx read <path> --mode auto` fully hermetically and returns stdout.
///
/// Isolation strategy: the daemon socket lives under `dirs::data_local_dir()`
/// (HOME-derived), so pointing `HOME`/XDG at empty temp dirs guarantees no
/// daemon is listening there; `LEAN_CTX_HOOK_CHILD` then short-circuits the
/// daemon client so the in-process CLI path (the code under test) runs even when
/// the developer's real daemon is up. `LEAN_CTX_DATA_DIR` keeps stat tracking
/// out of the real data dir.
fn read_auto(bin: &str, home: &Path, data_dir: &Path, file: &Path) -> String {
let out = Command::new(bin)
.args(["read", file.to_str().unwrap(), "--mode", "auto"])
.env("LEAN_CTX_HOOK_CHILD", "1")
.env("HOME", home)
.env("XDG_DATA_HOME", home.join("share"))
.env("XDG_CONFIG_HOME", home.join("config"))
.env("LEAN_CTX_DATA_DIR", data_dir)
.output()
.expect("run lean-ctx read");
assert!(
out.status.success(),
"read failed for {}: {}",
file.display(),
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).into_owned()
}
#[test]
fn cli_auto_read_never_inflates_tiny_files() {
let bin = env!("CARGO_BIN_EXE_lean-ctx");
let dir = tempfile::tempdir().unwrap();
let home = tempfile::tempdir().unwrap();
let data = tempfile::tempdir().unwrap();
// Tiny, incompressible files across the common types: framing alone would
// exceed the content, so the cap is the load-bearing guarantee here.
let cases = [
("tiny.json", "{\"a\":1}\n"),
("tiny.rs", "fn a() {}\n"),
("tiny.md", "# Hi\n"),
("tiny.txt", "hello world\n"),
("tiny.toml", "x = 1\n"),
("tiny.yaml", "a: 1\n"),
];
for (name, content) in cases {
let path = dir.path().join(name);
std::fs::write(&path, content).unwrap();
let stdout = read_auto(bin, home.path(), data.path(), &path);
let raw_tokens = count_tokens(content);
// Trailing newline from `println!` is a display artifact, not payload.
let emitted = count_tokens(stdout.trim_end_matches('\n'));
assert!(
emitted <= raw_tokens,
"{name}: emitted {emitted} tok > raw {raw_tokens} tok (CLI inflated a read!)\n\
--- stdout ---\n{stdout}"
);
// Capping must never drop data — the file body stays fully present.
assert!(
stdout.contains(content.trim_end()),
"{name}: file content missing from output\n--- stdout ---\n{stdout}"
);
}
}