Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions tests/test_grep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,11 @@ fn quiet_match_overrides_file_error() {
// With -q, a match makes grep exit 0 even if an earlier file could not be
// opened. Without -q the missing file still yields exit 2, and -q with no
// match keeps the error status.
// -q exits at the first match without draining stdin, so the harness's
// write can lose the race and fail with EPIPE; that error is expected here.
let (_s, mut c) = ucmd();
c.args(&["-q", "abc", "no-such-file", "-"])
.ignore_stdin_write_error()
.pipe_in("abcd\n")
.succeeds()
.no_output();
Expand Down Expand Up @@ -430,16 +433,21 @@ fn line_regexp() {

#[test]
fn max_count() {
// -m makes grep stop before draining stdin, so the harness's write may fail
// with EPIPE. That is expected and must not fail the test.

// Basic cap.
let (_s, mut c) = ucmd();
c.args(&["-m", "2", "a"])
.ignore_stdin_write_error()
.pipe_in("a\na\na\na\n")
.succeeds()
.stdout_only("a\na\n");

// -m 0 means zero. Exit 1, no output.
let (_s, mut c) = ucmd();
c.args(&["-m", "0", "a"])
.ignore_stdin_write_error()
.pipe_in("a\n")
.fails_with_code(1)
.no_stdout();
Expand All @@ -462,13 +470,15 @@ fn max_count() {
// -A trailing context still printed after the cutoff.
let (_s, mut c) = ucmd();
c.args(&["-m", "1", "-A", "2", "match"])
.ignore_stdin_write_error()
.pipe_in("noise\nmatch\nctx1\nctx2\ntail\n")
.succeeds()
.stdout_only("match\nctx1\nctx2\n");

// -c is capped by -m.
let (_s, mut c) = ucmd();
c.args(&["-c", "-m", "1", "a"])
.ignore_stdin_write_error()
.pipe_in("a\na\na\n")
.succeeds()
.stdout_only("1\n");
Expand Down Expand Up @@ -557,8 +567,11 @@ fn empty_pattern_matches_every_line() {

#[test]
fn inverted_empty_pattern_short_circuits() {
// grep short-circuits without reading stdin at all, so the harness's write
// races grep's exit and may fail with EPIPE.
let (_s, mut c) = ucmd();
c.args(&["-e", "", "-v", "-c"])
.ignore_stdin_write_error()
.pipe_in("a\nb\n")
.fails_with_code(1)
.no_output();
Expand All @@ -568,8 +581,10 @@ fn inverted_empty_pattern_short_circuits() {
.fails_with_code(1)
.no_output();

// Pattern compilation fails before any input is read.
let (_s, mut c) = ucmd();
c.args(&["-e", "", "-e", "[", "-v"])
.ignore_stdin_write_error()
.pipe_in("a\n")
.fails_with_code(2)
.no_stdout()
Expand Down Expand Up @@ -758,9 +773,14 @@ fn only_matching() {

#[test]
fn quiet_modes() {
// Match: exit 0, no output.
// Match: exit 0, no output. -q stops at the first match, so an EPIPE on the
// harness's stdin write is expected.
let (_s, mut c) = ucmd();
c.args(&["-q", "a"]).pipe_in("a\n").succeeds().no_output();
c.args(&["-q", "a"])
.ignore_stdin_write_error()
.pipe_in("a\n")
.succeeds()
.no_output();

// No match: exit 1, no output.
let (_s, mut c) = ucmd();
Expand Down Expand Up @@ -1569,9 +1589,11 @@ fn repeated_options_are_accepted() {
.succeeds()
.stdout_only("ABC\n");

// Repeated value options take the last value (here: -m 1 wins).
// Repeated value options take the last value (here: -m 1 wins). -m stops
// grep before stdin is drained, hence the ignored write error.
let (_s, mut c) = ucmd();
c.args(&["-m", "5", "-m", "1", "x"])
.ignore_stdin_write_error()
.pipe_in("x\nx\nx\n")
.succeeds()
.stdout_only("x\n");
Expand Down Expand Up @@ -1603,9 +1625,10 @@ fn literal_buffer_path_prefixes_and_max() {
.succeeds()
.stdout_only("2\n");

// -m caps printed matches.
// -m caps printed matches; grep exits before stdin is drained.
let (_s, mut c) = ucmd();
c.args(&["-m", "2", "x"])
.ignore_stdin_write_error()
.pipe_in("x\ny\nx\nz\nx\n")
.succeeds()
.stdout_only("x\nx\n");
Expand Down
Loading