mirror of
https://github.com/uutils/grep.git
synced 2026-06-10 16:15:11 -07:00
test: cover slow-path modes that literal tests no longer reach
The buffer-at-a-time fast path now serves the literal patterns that the existing -l/-L/-q and binary tests used, leaving the line-at-a-time engine's equivalents uncovered. Add bracket-class (non-literal) tests for -l/-L/-q and binary handling (notice, -a text, without-match bail, and the finalize-time notice), plus a fast-path test for a NUL that is only discovered after a line was already printed. No dead code was found: the remaining uncovered lines are writer I/O error-propagation arms and pre-existing filesystem error handlers.
This commit is contained in:
@@ -1339,3 +1339,103 @@ fn literal_buffer_path_spans_many_chunks() {
|
||||
.succeeds()
|
||||
.stdout_only(expected_n);
|
||||
}
|
||||
|
||||
// Plain literals run on the buffer-at-a-time fast path, so the following tests
|
||||
// use bracket-class patterns (non-literal) to keep the line-at-a-time engine's
|
||||
// `-l` / `-L` / `-q` and binary-handling paths exercised too.
|
||||
|
||||
#[test]
|
||||
fn slow_path_list_and_quiet_modes() {
|
||||
let (scene, _) = ucmd();
|
||||
scene.fixtures.write("hit", "yes\n");
|
||||
scene.fixtures.write("miss", "no\n");
|
||||
|
||||
// -l: list matching files.
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-l", "[y]es", "hit", "miss"])
|
||||
.succeeds()
|
||||
.stdout_is("hit\n");
|
||||
|
||||
// -L with a match in one file: only the non-matching file is listed.
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-L", "[y]es", "hit", "miss"])
|
||||
.succeeds()
|
||||
.stdout_is("miss\n");
|
||||
|
||||
// -L with no match anywhere: both files listed, exit 1.
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-L", "[z]z", "hit", "miss"])
|
||||
.fails_with_code(1)
|
||||
.stdout_is("hit\nmiss\n");
|
||||
|
||||
// -q stops at the first match (exit 0) or reports no match (exit 1).
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-q", "[y]es", "hit"])
|
||||
.succeeds()
|
||||
.no_output();
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-q", "[z]z", "hit"])
|
||||
.fails_with_code(1)
|
||||
.no_output();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slow_path_binary_handling() {
|
||||
let (scene, _) = ucmd();
|
||||
// NOTE: avoid the name "nul" here — it's a reserved device name on Windows,
|
||||
// so writing/reading it hits the null device instead of a real file.
|
||||
scene.fixtures.write_bytes("nulbin", b"hit\0\n");
|
||||
scene.fixtures.write_bytes("bad", b"a\x9d\n");
|
||||
|
||||
// Binary notice on the line-at-a-time engine (regex pattern).
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["[h]it", "nulbin"])
|
||||
.succeeds()
|
||||
.no_stdout()
|
||||
.stderr_contains("binary file matches");
|
||||
|
||||
// -a forces text mode: the NUL line is printed verbatim.
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["-a", "[h]it", "nulbin"])
|
||||
.succeeds()
|
||||
.stdout_is_bytes(b"hit\0\n");
|
||||
|
||||
// --binary-files=without-match bails out on an invalid-UTF-8 match.
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["--binary-files=without-match", "[a]", "bad"])
|
||||
.fails_with_code(1)
|
||||
.no_output();
|
||||
|
||||
// A NUL after the matched line means binariness is discovered at EOF, so
|
||||
// the line is printed first and the notice is emitted during finalization.
|
||||
scene.fixtures.write_bytes("late", b"hit\nno\0\n");
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["[h]it", "late"])
|
||||
.succeeds()
|
||||
.stdout_is("hit\n")
|
||||
.stderr_contains("binary file matches");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fast_path_binary_detected_after_a_printed_line() {
|
||||
// A NUL that appears only after the last match in the buffer marks the file
|
||||
// binary on the fast path *after* an earlier match was already printed: the
|
||||
// printed line stays and the trailing notice is still emitted.
|
||||
let (scene, _) = ucmd();
|
||||
scene.fixtures.write_bytes("b", b"hit\nno\0\n");
|
||||
scene
|
||||
.cmd(env!("CARGO_BIN_EXE_grep"))
|
||||
.args(&["hit", "b"])
|
||||
.succeeds()
|
||||
.stdout_is("hit\n")
|
||||
.stderr_contains("binary file matches");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user