172 lines
4.8 KiB
Bash
Executable File
172 lines
4.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# tests/test_grep.sh - Tests for grep/egrep/fgrep applets
|
|
_test_name="grep"
|
|
. "$(dirname "$0")/harness.sh"
|
|
|
|
setup_tmpdir
|
|
GREP="$VX grep"
|
|
EGREP="$VX egrep"
|
|
FGREP="$VX fgrep"
|
|
|
|
echo "Running grep tests..."
|
|
|
|
# --- create test files ---
|
|
cat > haystack.txt <<'EOF'
|
|
Hello World
|
|
hello world
|
|
HELLO WORLD
|
|
foo bar baz
|
|
The quick brown fox
|
|
jumps over the lazy dog
|
|
line with numbers 12345
|
|
another line here
|
|
foobar
|
|
EOF
|
|
|
|
cat > patterns.txt <<'EOF'
|
|
foo
|
|
bar
|
|
EOF
|
|
|
|
# --- basic match ---
|
|
_got="$($GREP 'Hello' haystack.txt)"
|
|
check_eq "$_got" "Hello World" "basic: literal match"
|
|
|
|
# --- case insensitive ---
|
|
_count="$($GREP -ic 'hello' haystack.txt)"
|
|
check_eq "$_count" "3" "iflag: case insensitive count"
|
|
|
|
# --- -v invert ---
|
|
_count="$($GREP -vic 'hello' haystack.txt | tr -d ' ')"
|
|
_total="$(wc -l < haystack.txt | tr -d ' ')"
|
|
_expect=$((${_total} - 3))
|
|
check_eq "$_count" "$_expect" "vflag: invert count"
|
|
|
|
# --- -n line numbers ---
|
|
_got="$($GREP -n 'foo bar' haystack.txt)"
|
|
check_eq "$_got" "4:foo bar baz" "nflag: line number"
|
|
|
|
# --- -c count ---
|
|
_got="$($GREP -c 'line' haystack.txt)"
|
|
check_eq "$_got" "2" "cflag: count lines"
|
|
|
|
# --- -l files-with-matches ---
|
|
_got="$($GREP -l 'Hello' haystack.txt)"
|
|
check_eq "$_got" "haystack.txt" "lflag: filename"
|
|
|
|
# --- -L files-without-match ---
|
|
echo "no match here" > other.txt
|
|
_got="$($GREP -L 'Hello' haystack.txt other.txt)"
|
|
check_eq "$_got" "other.txt" "Lflag: no-match filename"
|
|
|
|
# --- -w word match ---
|
|
_got="$($GREP -wc 'foo' haystack.txt)"
|
|
check_eq "$_got" "1" "wflag: word boundary (foo not foobar)"
|
|
|
|
# --- -x line match ---
|
|
_got="$($GREP -x 'foobar' haystack.txt)"
|
|
check_eq "$_got" "foobar" "xflag: exact line match"
|
|
|
|
# --- -o only matching ---
|
|
_got="$($GREP -o 'fox' haystack.txt)"
|
|
check_eq "$_got" "fox" "oflag: only matching part"
|
|
|
|
# --- -m max count ---
|
|
_got="$($GREP -m1 'line' haystack.txt)"
|
|
_count="$(printf '%s\n' "$_got" | wc -l | tr -d ' ')"
|
|
check_eq "$_count" "1" "mflag: max count 1"
|
|
|
|
# --- -e multiple patterns ---
|
|
_count="$($GREP -c -e 'Hello' -e 'quick' haystack.txt)"
|
|
check_eq "$_count" "2" "eflag: multiple patterns"
|
|
|
|
# --- -f pattern file ---
|
|
_count="$($GREP -c -f patterns.txt haystack.txt)"
|
|
check_eq "$_count" "2" "fflag: pattern file (foo, bar match 2 lines)"
|
|
|
|
# --- -q quiet mode ---
|
|
$GREP -q 'Hello' haystack.txt
|
|
check_eq "$?" "0" "qflag: quiet match exits 0"
|
|
$GREP -q 'NOMATCH_XYZ' haystack.txt
|
|
check_eq "$?" "1" "qflag: quiet no-match exits 1"
|
|
|
|
# --- -s suppress errors ---
|
|
$GREP -s 'test' nonexistent_file 2>err_out
|
|
_err="$(cat err_out)"
|
|
check_eq "$_err" "" "sflag: suppresses error messages"
|
|
|
|
# --- -b byte offset ---
|
|
_got="$($GREP -b 'foo bar' haystack.txt | cut -d: -f1)"
|
|
# "foo bar" is on line 4, after 3 lines + newlines
|
|
test -n "$_got"
|
|
check_eq "$?" "0" "bflag: byte offset present"
|
|
|
|
# --- -H / -h filename control ---
|
|
_got="$($GREP -H 'Hello' haystack.txt)"
|
|
echo "$_got" | grep -q '^haystack.txt:'
|
|
check_eq "$?" "0" "Hflag: filename shown"
|
|
|
|
_got="$($GREP -h 'Hello' haystack.txt)"
|
|
echo "$_got" | grep -qv ':'
|
|
check_eq "$?" "0" "hflag: no filename"
|
|
|
|
# --- extended regex (egrep / -E) ---
|
|
_got="$($GREP -Ec 'foo|quick' haystack.txt)"
|
|
check_eq "$_got" "3" "Eflag: extended regex"
|
|
|
|
_got="$($EGREP -c 'foo|quick' haystack.txt)"
|
|
check_eq "$_got" "3" "egrep: dispatch works"
|
|
|
|
# --- fixed strings (fgrep / -F) ---
|
|
_got="$($FGREP -c 'foo' haystack.txt)"
|
|
check_eq "$_got" "2" "fgrep: fixed strings"
|
|
|
|
# --- context: -A after ---
|
|
_count="$($GREP -A1 'quick' haystack.txt | wc -l | tr -d ' ')"
|
|
check_eq "$_count" "2" "Aflag: after context"
|
|
|
|
# --- context: -B before ---
|
|
_count="$($GREP -B1 'quick' haystack.txt | wc -l | tr -d ' ')"
|
|
check_eq "$_count" "2" "Bflag: before context"
|
|
|
|
# --- context: -C both ---
|
|
_count="$($GREP -C1 'quick' haystack.txt | wc -l | tr -d ' ')"
|
|
check_eq "$_count" "3" "Cflag: context both sides"
|
|
|
|
# --- stdin ---
|
|
_got="$(echo 'test line' | $GREP 'test')"
|
|
check_eq "$_got" "test line" "stdin: pipe works"
|
|
|
|
# --- exit codes ---
|
|
check_exit "exit: match returns 0" 0 $GREP -q 'Hello' haystack.txt
|
|
check_exit "exit: no match returns 1" 1 $GREP -q 'ZZZNOTFOUND' haystack.txt
|
|
check_exit "exit: error returns 2" 2 $GREP 'test' --bogus-flag 2>/dev/null
|
|
|
|
# --- recursive ---
|
|
mkdir -p subdir
|
|
echo "findme here" > subdir/nested.txt
|
|
_got="$($GREP -r 'findme' .)"
|
|
echo "$_got" | grep -q 'nested.txt'
|
|
check_eq "$?" "0" "rflag: recursive find"
|
|
|
|
# --- --include ---
|
|
echo "match" > inc_yes.c
|
|
echo "match" > inc_no.txt
|
|
_got="$($GREP -r --include='*.c' 'match' .)"
|
|
echo "$_got" | grep -q 'inc_yes.c'
|
|
check_eq "$?" "0" "include: *.c matches"
|
|
echo "$_got" | grep -q 'inc_no.txt'
|
|
check_eq "$?" "1" "include: *.txt excluded"
|
|
|
|
# --- --exclude ---
|
|
_got="$($GREP -r --exclude='*.txt' 'match' .)"
|
|
echo "$_got" | grep -q 'inc_yes.c'
|
|
check_eq "$?" "0" "exclude: *.c still matches"
|
|
|
|
# --- -z null data ---
|
|
printf 'aaa\0bbb\0ccc\0' > nulldata
|
|
_count="$($GREP -zc 'bbb' nulldata)"
|
|
check_eq "$_count" "1" "zflag: null-delimited"
|
|
|
|
summary
|