use std::fs;
use std::path::Path;
use std::process::Command;
const TOLERANCE_MIB: u64 = 1;
#[test]
fn assert_documented_size_matches_real() {
let cargo_toml = fs::read_to_string("Cargo.toml").expect("Cargo.toml must be readable");
let description_line = cargo_toml
.lines()
.find(|line| line.trim_start().starts_with("description"))
.expect("Cargo.toml must have a description line");
let documented_mib = parse_size_mib_from_description(description_line)
.expect("description must mention binary size (e.g. '14.6 MiB' or '15 MB')");
let binary_path = Path::new("target/release/sqlite-graphrag");
assert!(
binary_path.exists(),
"release binary must exist at target/release/sqlite-graphrag; run `cargo build --release` first"
);
let real_bytes = fs::metadata(binary_path)
.expect("binary metadata must be readable")
.len();
let real_mib = real_bytes / (1024 * 1024);
let delta = real_mib.abs_diff(documented_mib);
assert!(
delta <= TOLERANCE_MIB,
"documented binary size in Cargo.toml ({documented_mib} MiB) diverges from real binary ({real_mib} MiB = {real_bytes} bytes) by more than {TOLERANCE_MIB} MiB"
);
eprintln!(
"GAP-E2E-001 OK: documented {documented_mib} MiB == real {real_mib} MiB ({real_bytes} bytes), delta {delta} MiB"
);
}
fn parse_size_mib_from_description(line: &str) -> Option<u64> {
let lower = line.to_lowercase();
let candidates = [("mib", 1u64), ("mb", 1u64)];
for (unit, divisor_mib) in candidates {
if let Some(idx) = lower.find(unit) {
let prefix = &lower[..idx];
let prefix = prefix.trim_end();
let num_str: String = prefix
.chars()
.rev()
.take_while(|c| c.is_ascii_digit() || *c == '.')
.collect::<String>()
.chars()
.rev()
.collect();
if let Ok(parsed) = num_str.parse::<f64>() {
let mib = (parsed / divisor_mib as f64).round() as u64;
return Some(mib);
}
}
}
None
}
#[test]
fn assert_release_profile_has_size_optimizations() {
let cargo_toml = fs::read_to_string("Cargo.toml").expect("Cargo.toml must be readable");
assert!(
cargo_toml.contains("lto = \"fat\""),
"[profile.release] must keep lto = \"fat\" to minimize binary size"
);
assert!(
cargo_toml.contains("strip = true"),
"[profile.release] must keep strip = true to remove debug symbols"
);
assert!(
cargo_toml.contains("codegen-units = 1"),
"[profile.release] must keep codegen-units = 1 for cross-module LTO"
);
assert!(
cargo_toml.contains("opt-level = 3"),
"[profile.release] must keep opt-level = 3 for maximum optimization"
);
}
#[test]
fn assert_no_six_mb_claim_in_documentation() {
let docs_to_scan = [
"Cargo.toml",
"README.md",
"llms.txt",
"CHANGELOG.md",
"docs/AGENTS.md",
"docs/AGENTS.pt-BR.md",
"docs/HOW_TO_USE.md",
"docs/HOW_TO_USE.pt-BR.md",
"docs/MIGRATION.md",
"docs/MIGRATION.pt-BR.md",
"docs/CROSS_PLATFORM.md",
"docs/CROSS_PLATFORM.pt-BR.md",
"docs/COOKBOOK.md",
"docs/COOKBOOK.pt-BR.md",
"docs/decisions/adr-0019-llm-only-one-shot.md",
"docs/decisions/adr-0019-llm-only-one-shot.pt-BR.md",
];
for path in docs_to_scan {
let full_path = Path::new(path);
if !full_path.exists() {
continue;
}
let content =
fs::read_to_string(full_path).unwrap_or_else(|_| panic!("{path} must be readable"));
let stale_patterns = ["~6 MB", "6 MB binary", " 6 MB)", "6 MB Rust"];
for pattern in stale_patterns {
assert!(
!content.contains(pattern),
"{path} still contains stale binary size claim '{pattern}'; update to real size (14.6 MiB)"
);
}
}
let _ = Command::new("stat")
.args(["-c", "%s", "target/release/sqlite-graphrag"])
.output()
.ok();
}