//! End-to-end tests for `ripgrab tail`.
use std::io::Write;
use std::thread;
use std::time::Duration;
use assert_cmd::Command;
use predicates::str::contains;
use tempfile::NamedTempFile;
fn bin() -> Command {
Command::cargo_bin("ripgrab").unwrap()
}
#[test]
fn tail_with_include_filter_reads_matching_lines() {
let mut tmp = NamedTempFile::new().unwrap();
writeln!(tmp, "request ok status=200").unwrap();
writeln!(tmp, "request failed status=503").unwrap();
writeln!(tmp, "request ok status=200").unwrap();
tmp.flush().unwrap();
bin()
.args(["tail", tmp.path().to_str().unwrap(), "-i", "status=5\\d\\d"])
.env("NO_COLOR", "1")
.assert()
.success()
.stdout(contains("status=503"))
.stdout(contains("status=200").not());
}
#[test]
fn tail_with_exclude_filter_drops_matching_lines() {
let mut tmp = NamedTempFile::new().unwrap();
writeln!(tmp, "heartbeat ok").unwrap();
writeln!(tmp, "request ok").unwrap();
tmp.flush().unwrap();
bin()
.args(["tail", tmp.path().to_str().unwrap(), "-e", "heartbeat"])
.env("NO_COLOR", "1")
.assert()
.success()
.stdout(contains("request ok"))
.stdout(contains("heartbeat").not());
}
#[test]
fn tail_no_origin_hides_filename_column() {
let mut tmp = NamedTempFile::new().unwrap();
writeln!(tmp, "hello").unwrap();
tmp.flush().unwrap();
let out = bin()
.args(["tail", tmp.path().to_str().unwrap(), "--no-origin"])
.env("NO_COLOR", "1")
.output()
.unwrap();
let stdout = String::from_utf8(out.stdout).unwrap();
assert_eq!(stdout.trim_end(), "hello");
}
#[test]
fn tail_from_end_skips_existing_lines() {
let mut tmp = NamedTempFile::new().unwrap();
for i in 0..5 {
writeln!(tmp, "old-{}", i).unwrap();
}
tmp.flush().unwrap();
let cmd = bin()
.args([
"tail",
tmp.path().to_str().unwrap(),
"--from-end", "2",
])
.env("NO_COLOR", "1")
.output()
.unwrap();
let stdout = String::from_utf8(cmd.stdout).unwrap();
assert!(!stdout.contains("old-0"));
assert!(stdout.contains("old-3") || stdout.contains("old-4"));
}
#[test]
fn tail_stdin_input() {
bin()
.args(["tail", "-"])
.env("NO_COLOR", "1")
.write_stdin("from stdin\n")
.assert()
.success()
.stdout(contains("from stdin"));
}
#[test]
fn tail_rejects_missing_path() {
bin()
.args(["tail", "/does/not/exist"])
.assert()
.failure();
thread::sleep(Duration::from_millis(10));
}