Files
vx/tests/test_grep.sh

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