use super::InvariantArgs;
use anyhow::{Context, Result};
use colored::*;
pub fn run(args: &InvariantArgs) -> Result<()> {
eprintln!("{}", "🔬 Forge Guard — Invariant Testing".bold());
eprintln!(" Runs: {}", args.runs);
eprintln!(" Depth: {}", args.depth);
eprintln!(
" Contract: {}",
args.contract.as_deref().unwrap_or("all")
);
let mut cmd = std::process::Command::new("forge");
cmd.arg("test");
cmd.arg("--invariant-runs").arg(args.runs.to_string());
cmd.arg("--invariant-depth").arg(args.depth.to_string());
if args.fail_on_revert {
cmd.arg("--fail-on-revert");
}
if let Some(contract) = &args.contract {
cmd.arg("--match-contract").arg(contract);
}
eprintln!("\n🚀 Running invariant tests...\n");
let status = cmd.status().context("Failed to run forge test")?;
if !status.success() {
anyhow::bail!("Invariant tests failed — invariants broken!");
}
eprintln!(
"\n{}",
"✅ Invariant tests passed — all invariants hold."
.green()
.bold()
);
Ok(())
}