use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;
static RSPEC_PASS_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?m)^\s+\.\n?").unwrap());
static DOTS_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?m)^[\.F\*]+\n?").unwrap());
static RAKE_TASK_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?m)^\(in /[^\)]+\)\n?").unwrap());
pub fn compress_rspec(raw: &str, exit_code: i32) -> String {
let cleaned = compactor::normalise(raw);
if exit_code == 0 {
let kept: Vec<&str> = cleaned
.lines()
.filter(|l| {
l.contains("example") && (l.contains("failure") || l.contains("pending"))
|| l.contains("Finished in")
|| l.contains("seconds")
})
.collect();
if !kept.is_empty() {
return kept.join("\n");
}
}
let s = DOTS_RE.replace_all(&cleaned, "");
let s = RSPEC_PASS_RE.replace_all(&s, "");
compactor::collapse_blanks(&s)
}
pub fn compress_minitest(raw: &str, exit_code: i32) -> String {
let cleaned = compactor::normalise(raw);
if exit_code == 0 {
let kept: Vec<&str> = cleaned
.lines()
.filter(|l| l.contains("runs, ") || l.contains("assertions, "))
.collect();
if !kept.is_empty() {
return kept.join("\n");
}
}
cleaned
.lines()
.filter(|l| !l.trim_start().starts_with('.'))
.collect::<Vec<_>>()
.join("\n")
}
pub fn compress_rake(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = RAKE_TASK_RE.replace_all(&cleaned, "");
compactor::collapse_blanks(&s)
}
pub fn compress_ruby_test(prog: &str, raw: &str, exit_code: i32) -> String {
match prog {
"rspec" => compress_rspec(raw, exit_code),
"minitest" => compress_minitest(raw, exit_code),
"rake" => compress_rake(raw),
_ => compress_rspec(raw, exit_code),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rspec_success_keeps_summary() {
let raw = "....\nFinished in 0.012 seconds\n4 examples, 0 failures\n";
let out = compress_rspec(raw, 0);
assert!(out.contains("examples"), "{out}");
assert!(!out.contains("...."), "{out}");
}
#[test]
fn rspec_failure_strips_dots() {
let raw = "...F.\n\nFailures:\n 1) MyClass does foo\n Failure/Error: expect(1).to eq(2)\n5 examples, 1 failure\n";
let out = compress_rspec(raw, 1);
assert!(!out.contains("...F"), "{out}");
assert!(out.contains("Failure") || out.contains("failure"), "{out}");
}
#[test]
fn rake_strips_working_dir() {
let raw = "(in /home/user/project)\ntask1: building\ntask1: done\n";
let out = compress_rake(raw);
assert!(!out.contains("(in /home/"), "{out}");
assert!(out.contains("task1"), "{out}");
}
}