use std::io::Write;
use std::process::Command;
use assert_cmd::prelude::*;
use predicates::prelude::*;
use tempfile::NamedTempFile;
fn bin() -> Command {
Command::cargo_bin("ripgrab").expect("binary built")
}
fn seed_file(lines: &[&str]) -> NamedTempFile {
let mut f = NamedTempFile::new().expect("tempfile");
for line in lines {
writeln!(f, "{line}").unwrap();
}
f.flush().unwrap();
f
}
#[test]
fn requires_a_path() {
bin()
.assert()
.failure()
.stderr(predicate::str::contains("required"));
}
#[test]
fn prints_matches_in_no_follow_mode() {
let f = seed_file(&[
"INFO: started",
"ERROR: disk full",
"INFO: ticked",
"ERROR: timeout",
]);
bin()
.arg("--no-follow")
.arg("--no-color")
.arg("--match")
.arg("ERROR")
.arg("-n")
.arg("100")
.arg(f.path())
.assert()
.success()
.stdout(predicate::str::contains("disk full"))
.stdout(predicate::str::contains("timeout"))
.stdout(predicate::str::contains("ticked").not());
}
#[test]
fn extract_renders_named_fields() {
let f = seed_file(&[
"t=1 rid=aaa111 ms=5 path=/a",
"t=2 rid=bbb222 ms=42 path=/b",
"t=3 no match here",
]);
let output = bin()
.arg("--no-follow")
.arg("--no-color")
.arg("-n")
.arg("100")
.arg("--extract")
.arg(r"rid=(?P<rid>\w+) ms=(?P<ms>\d+)")
.arg(f.path())
.assert()
.success()
.get_output()
.stdout
.clone();
let stdout = String::from_utf8(output).unwrap();
assert!(stdout.contains("rid=aaa111"));
assert!(stdout.contains("ms=42"));
}
#[test]
fn rejects_extract_without_named_groups() {
bin()
.arg("--no-follow")
.arg("--extract")
.arg(r"\d+")
.arg("/dev/null")
.assert()
.failure()
.stderr(predicate::str::contains("named capture"));
}