use proptest::prelude::*;
use rch_common::admit_preflight::{AdmitRecommendation, preflight};
use rch_common::exec_misuse::detect_exec_misuse;
use rch_common::exec_policy::{
ExecContext, ExecDisposition, decide_exec_policy, mutates_local_state,
};
fn command_like() -> impl Strategy<Value = String> {
let token = prop_oneof![
Just("cargo".to_string()),
Just("build".to_string()),
Just("test".to_string()),
Just("fmt".to_string()),
Just("fix".to_string()),
Just("--release".to_string()),
Just("--target".to_string()),
Just("wasm32-unknown-unknown".to_string()),
Just("+nightly".to_string()),
Just("--offline".to_string()),
Just("bun".to_string()),
Just("install".to_string()),
Just("env".to_string()),
Just("CARGO_TARGET_DIR=/tmp/t".to_string()),
Just("nice".to_string()),
Just("-n".to_string()),
Just("10".to_string()),
Just("ls".to_string()),
Just("&&".to_string()),
Just(";".to_string()),
Just("|".to_string()),
Just("'a quoted str'".to_string()),
"[a-zA-Z0-9._/=+-]{1,10}",
];
proptest::collection::vec(token, 0..9).prop_map(|toks| toks.join(" "))
}
fn any_command() -> impl Strategy<Value = String> {
prop_oneof![command_like(), any::<String>()]
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(1500))]
#[test]
fn preflight_is_total_and_definite(cmd in any_command()) {
for proof in [false, true] {
let p = preflight(&cmd, proof);
prop_assert!(
matches!(
p.base_recommendation,
AdmitRecommendation::Offload | AdmitRecommendation::Local
),
"non-definite base recommendation {:?} for {:?}",
p.base_recommendation,
cmd
);
prop_assert!(!p.compound.is_empty(), "empty compound for {:?}", cmd);
if !p.is_compilation {
prop_assert_eq!(p.base_recommendation, AdmitRecommendation::Local);
}
prop_assert_eq!(preflight(&cmd, proof), p);
}
}
#[test]
fn exec_policy_is_total_and_conservative(cmd in any_command()) {
let _ = mutates_local_state(&cmd); let contexts = [
ExecContext::hook(),
ExecContext::explicit(),
ExecContext { explicit_exec: true, proof_mode: true, force_remote: false },
ExecContext { explicit_exec: true, proof_mode: false, force_remote: true },
];
for ctx in contexts {
let d = decide_exec_policy(&cmd, &ctx);
prop_assert!(matches!(
d.disposition,
ExecDisposition::RunRemote
| ExecDisposition::RunLocalFallback
| ExecDisposition::Reject
));
if d.mutates_local_state && !d.is_compilation {
prop_assert_ne!(
d.disposition,
ExecDisposition::RunRemote,
"mutating non-compilation shipped remote for {:?} ctx {:?}",
cmd,
ctx
);
}
}
}
#[test]
fn exec_misuse_matches_contract(
argv in proptest::collection::vec("[a-zA-Z0-9 _./=+-]{0,24}", 0..4),
had_separator in any::<bool>(),
) {
let report = detect_exec_misuse(&argv, had_separator);
let single_whitespace_token =
argv.len() == 1 && argv[0].split_whitespace().count() > 1;
let expect_misuse = !had_separator && single_whitespace_token;
prop_assert_eq!(report.misuse, expect_misuse, "argv={:?} sep={}", argv, had_separator);
prop_assert_eq!(report.misuse, report.suggestion.is_some());
prop_assert_eq!(report.misuse, report.reason_code.is_some());
}
}
#[test]
fn mutates_stable_under_benign_prefixes() {
assert!(mutates_local_state("cargo fmt"));
for variant in [
"env CARGO_TERM_COLOR=always cargo fmt",
"env A=1 B=2 cargo fmt",
"cargo fmt --all",
"cargo fmt -- --check",
"bun install --frozen-lockfile",
"cargo +nightly fmt",
] {
assert!(mutates_local_state(variant), "expected mutating: {variant}");
}
for safe in ["cargo build", "env A=1 cargo build", "bun test", "ls -la"] {
assert!(!mutates_local_state(safe), "should not be mutating: {safe}");
}
}