Files
yvgude--lean-ctx/rust/tests/property_compression.rs
wehub-resource-sync 26382a7ac6
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
JetBrains Plugin / Actionlint (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (rust) (push) Waiting to run
JetBrains Plugin / Validation (push) Waiting to run
JetBrains Plugin / Build (push) Waiting to run
JetBrains Plugin / Test (push) Blocked by required conditions
Security Check / Security Scan (push) Waiting to run
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
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

123 lines
4.1 KiB
Rust

use lean_ctx::core::compressor::safeguard_ratio;
// Property/fuzz tests MUST use the deterministic entry point. The default
// `entropy_compress` runs the #544 semantic-redundancy filter, which self-
// activates the shared neural embedding engine on first use (#551). The
// `cfg!(test)` guard that suppresses that background load only covers *unit*
// tests — this is an *integration* test, so the lib is linked without
// `cfg(test)` and the engine would load and run real per-line GEMM inference
// for every generated case, turning the proptest run into an effective hang on
// any machine that has the embedding model present. The deterministic path is
// purpose-built for run-to-run / machine-to-machine reproducibility and never
// touches the engine, so it exercises the same compression invariants without
// the nondeterministic, model-dependent cost.
use lean_ctx::core::entropy::entropy_compress_deterministic;
use lean_ctx::core::patterns::compress_output;
use lean_ctx::core::tokens::count_tokens;
use proptest::prelude::*;
proptest! {
#[test]
fn safeguard_never_inflates(
original in "[a-zA-Z0-9 \n]{1,500}",
compressed in "[a-zA-Z0-9 \n]{0,500}"
) {
let result = safeguard_ratio(&original, &compressed);
let result_tokens = count_tokens(&result);
let orig_tokens = count_tokens(&original);
let comp_tokens = count_tokens(&compressed);
let max_tokens = orig_tokens.max(comp_tokens);
prop_assert!(
result_tokens <= max_tokens,
"safeguard_ratio returned {} tokens, max(orig={}, comp={}) = {}",
result_tokens, orig_tokens, comp_tokens, max_tokens
);
}
#[test]
fn safeguard_returns_one_of_inputs(
original in "[a-zA-Z0-9 \n]{1,200}",
compressed in "[a-zA-Z0-9 \n]{0,200}"
) {
let result = safeguard_ratio(&original, &compressed);
prop_assert!(
result == original || result == compressed,
"safeguard_ratio must return either original or compressed"
);
}
#[test]
fn entropy_compress_output_is_subset_of_lines(
content in "[a-zA-Z0-9(){};= \n]{10,800}"
) {
let result = entropy_compress_deterministic(&content);
for line in result.output.lines() {
if line.trim().is_empty() {
continue;
}
prop_assert!(
content.contains(line.trim()),
"entropy output line not found in original: {:?}",
line
);
}
}
#[test]
fn entropy_compress_tokens_not_greater(
content in "[a-zA-Z0-9(){};= \n]{10,600}"
) {
let result = entropy_compress_deterministic(&content);
prop_assert!(
result.compressed_tokens <= result.original_tokens,
"compressed {} > original {}",
result.compressed_tokens, result.original_tokens
);
}
#[test]
fn compress_output_never_inflates_tokens(
command in "(git status|cargo test|npm install|ls -la)",
output in "[a-zA-Z0-9:/ \n._-]{20,1000}"
) {
if let Some(compressed) = compress_output(&command, &output) {
let orig_tokens = count_tokens(&output);
let comp_tokens = count_tokens(&compressed);
prop_assert!(
comp_tokens <= orig_tokens,
"compress_output inflated: {} > {} for command '{}'",
comp_tokens, orig_tokens, command
);
}
}
}
#[cfg(test)]
mod fuzz_no_panic {
use super::*;
proptest! {
#[test]
fn compress_output_no_panic_on_arbitrary_utf8(
command in "\\PC{1,100}",
output in "\\PC{0,2000}"
) {
let _ = compress_output(&command, &output);
}
#[test]
fn safeguard_no_panic_on_empty(
text in "\\PC{0,100}"
) {
let _ = safeguard_ratio("", &text);
let _ = safeguard_ratio(&text, "");
}
#[test]
fn entropy_compress_no_panic(
content in "\\PC{0,1000}"
) {
let _ = entropy_compress_deterministic(&content);
}
}
}