From fded73c173d874bb43959840f3ca1accc1a55244 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Sat, 18 Oct 2025 09:33:22 +0100 Subject: [PATCH 1/3] Add grepdiff tests for missing features Add six new test cases for grepdiff features that were previously untested: - grepdiff-number-files: Test -N/--number-files option - grepdiff-status: Test -s/--status option - grepdiff-include-exclude: Test -i/--include and -x/--exclude options - grepdiff-file-regex: Test -f/--file option - grepdiff-annotate: Test --annotate option - grepdiff-with-filename: Test -H/--with-filename and -h/--no-filename All tests pass with the traditional filterdiff.c implementation. With scanner-based patchfilter (--enable-scanner-patchfilter), four tests pass and two are marked as XFAIL since those features are not yet implemented in the scanner-based grepdiff: - grepdiff-status (no -s option) - grepdiff-annotate (no --annotate option) Assisted-by: Claude Code --- Makefile.am | 14 +++++++ tests/grepdiff-annotate/run-test | 34 +++++++++++++++++ tests/grepdiff-file-regex/run-test | 36 ++++++++++++++++++ tests/grepdiff-include-exclude/run-test | 49 +++++++++++++++++++++++++ tests/grepdiff-number-files/run-test | 40 ++++++++++++++++++++ tests/grepdiff-status/run-test | 38 +++++++++++++++++++ tests/grepdiff-with-filename/run-test | 45 +++++++++++++++++++++++ 7 files changed, 256 insertions(+) create mode 100755 tests/grepdiff-annotate/run-test create mode 100755 tests/grepdiff-file-regex/run-test create mode 100755 tests/grepdiff-include-exclude/run-test create mode 100755 tests/grepdiff-number-files/run-test create mode 100755 tests/grepdiff-status/run-test create mode 100755 tests/grepdiff-with-filename/run-test diff --git a/Makefile.am b/Makefile.am index ba2a606f..10c7fb7f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -320,6 +320,12 @@ TESTS = tests/newline1/run-test \ tests/grepdiff8/run-test \ tests/grepdiff9/run-test \ tests/grepdiff-original-line-numbers/run-test \ + tests/grepdiff-number-files/run-test \ + tests/grepdiff-status/run-test \ + tests/grepdiff-include-exclude/run-test \ + tests/grepdiff-file-regex/run-test \ + tests/grepdiff-annotate/run-test \ + tests/grepdiff-with-filename/run-test \ tests/number1/run-test \ tests/number2/run-test \ tests/number3/run-test \ @@ -445,6 +451,14 @@ XFAIL_TESTS += \ tests/lsdiff-exclusion-mode/run-test endif +# grepdiff tests: expected to fail when scanner-patchfilter is enabled +# (features not yet implemented in scanner-based grepdiff) +if USE_SCANNER_PATCHFILTER +XFAIL_TESTS += \ + tests/grepdiff-status/run-test \ + tests/grepdiff-annotate/run-test +endif + test-perms: src/combinediff$(EXEEXT) src/flipdiff$(EXEEXT) \ src/lsdiff$(EXEEXT) src/grepdiff$(EXEEXT) src/patchview$(EXEEXT) \ scripts/splitdiff diff --git a/tests/grepdiff-annotate/run-test b/tests/grepdiff-annotate/run-test new file mode 100755 index 00000000..6ba7bc4e --- /dev/null +++ b/tests/grepdiff-annotate/run-test @@ -0,0 +1,34 @@ +#!/bin/sh + +# Test grepdiff --annotate option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1,2 +1,2 @@ + context +-old ++new +@@ -10 +10 @@ +-another ++change +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +EOF + +${GREPDIFF} --annotate --output-matching=hunk 'new' diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +--- file1 ++++ file1 +@@ -1,2 +1,2 @@ Hunk #1, file1 + context +-old ++new +EOF diff --git a/tests/grepdiff-file-regex/run-test b/tests/grepdiff-file-regex/run-test new file mode 100755 index 00000000..61d74bdd --- /dev/null +++ b/tests/grepdiff-file-regex/run-test @@ -0,0 +1,36 @@ +#!/bin/sh + +# Test grepdiff -f/--file option (read regexes from file) + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1 +1 @@ +-apple ++banana +--- file2 ++++ file2 +@@ -1 +1 @@ +-cherry ++date +--- file3 ++++ file3 +@@ -1 +1 @@ +-elderberry ++fig +EOF + +cat << EOF > patterns +banana +date +EOF + +${GREPDIFF} -f patterns diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +file1 +file2 +EOF diff --git a/tests/grepdiff-include-exclude/run-test b/tests/grepdiff-include-exclude/run-test new file mode 100755 index 00000000..d56c137a --- /dev/null +++ b/tests/grepdiff-include-exclude/run-test @@ -0,0 +1,49 @@ +#!/bin/sh + +# Test grepdiff -i/--include and -x/--exclude options + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- src/file1.c ++++ src/file1.c +@@ -1 +1 @@ +-old ++new +--- docs/readme.txt ++++ docs/readme.txt +@@ -1 +1 @@ +-old ++new +--- src/file2.c ++++ src/file2.c +@@ -1 +1 @@ +-old ++new +EOF + +# Test include pattern +${GREPDIFF} -i '*.c' 'new' diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +src/file1.c +src/file2.c +EOF + +# Test exclude pattern +${GREPDIFF} -x '*.txt' 'new' diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +src/file1.c +src/file2.c +EOF + +# Test combination of include and exclude +${GREPDIFF} -i 'src/*' -x '*file2*' 'new' diff 2>errors >output3 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output3 || exit 1 +src/file1.c +EOF diff --git a/tests/grepdiff-number-files/run-test b/tests/grepdiff-number-files/run-test new file mode 100755 index 00000000..db28bc37 --- /dev/null +++ b/tests/grepdiff-number-files/run-test @@ -0,0 +1,40 @@ +#!/bin/sh + +# Test grepdiff -N/--number-files option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1 +1 @@ +-old ++new +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +--- file3 ++++ file3 +@@ -1 +1 @@ +-test ++result +EOF + +${GREPDIFF} -N 'new' diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +File #1 file1 +EOF + +# Test with multiple matches (pattern matches content in files 1 and 3) +${GREPDIFF} -N '[ot]' diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +File #1 file1 +File #2 file2 +File #3 file3 +EOF diff --git a/tests/grepdiff-status/run-test b/tests/grepdiff-status/run-test new file mode 100755 index 00000000..721a80eb --- /dev/null +++ b/tests/grepdiff-status/run-test @@ -0,0 +1,38 @@ +#!/bin/sh + +# Test grepdiff -s/--status option +# Shows file status: + (addition), - (removal), ! (modification) + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- /dev/null ++++ newfile +@@ -0,0 +1 @@ ++content +--- oldfile ++++ /dev/null +@@ -1 +0,0 @@ +-content +--- modified ++++ modified +@@ -1 +1 @@ +-old ++new +EOF + +${GREPDIFF} -s 'content' diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +! newfile +! oldfile +EOF + +# Test with modification +${GREPDIFF} -s 'new' diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +! modified +EOF diff --git a/tests/grepdiff-with-filename/run-test b/tests/grepdiff-with-filename/run-test new file mode 100755 index 00000000..8ca1f659 --- /dev/null +++ b/tests/grepdiff-with-filename/run-test @@ -0,0 +1,45 @@ +#!/bin/sh + +# Test grepdiff -H/--with-filename and -h/--no-filename options + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > patch1 +--- file1 ++++ file1 +@@ -1 +1 @@ +-old ++new +EOF + +cat << EOF > patch2 +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +EOF + +# Test with multiple patch files (should show filenames by default) +${GREPDIFF} 'new' patch1 patch2 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +patch1:file1 +EOF + +# Test -H explicitly +${GREPDIFF} -H 'new' patch1 patch2 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +patch1:file1 +EOF + +# Test -h to suppress filename +${GREPDIFF} -h 'new' patch1 patch2 2>errors >output3 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output3 || exit 1 +file1 +EOF From 6710e06030741cf549466ac8782149d187abdaf4 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Sat, 18 Oct 2025 09:55:29 +0100 Subject: [PATCH 2/3] Add lsdiff tests for missing features Add five new test cases for lsdiff features that were previously untested: - lsdiff-number-files: Test -N/--number-files option - lsdiff-files-range: Test -F/--files=RANGE option - lsdiff-empty-files-removed: Test -E/--empty-files-as-removed option - lsdiff-addprefix: Test --addprefix option - lsdiff-strip-match: Test -p/--strip-match option All tests pass with the traditional filterdiff.c implementation. With scanner-based patchfilter (--enable-scanner-patchfilter), four tests pass (number-files, files-range, empty-files-removed, addprefix) and one is marked as XFAIL since that feature is not yet implemented in scanner-based lsdiff (strip-match). Assisted-by: Claude Code --- Makefile.am | 12 +++++ tests/lsdiff-addprefix/run-test | 26 ++++++++++ tests/lsdiff-empty-files-removed/run-test | 44 ++++++++++++++++ tests/lsdiff-files-range/run-test | 63 +++++++++++++++++++++++ tests/lsdiff-number-files/run-test | 32 ++++++++++++ tests/lsdiff-strip-match/run-test | 43 ++++++++++++++++ 6 files changed, 220 insertions(+) create mode 100755 tests/lsdiff-addprefix/run-test create mode 100755 tests/lsdiff-empty-files-removed/run-test create mode 100755 tests/lsdiff-files-range/run-test create mode 100755 tests/lsdiff-number-files/run-test create mode 100755 tests/lsdiff-strip-match/run-test diff --git a/Makefile.am b/Makefile.am index 10c7fb7f..69cb3fac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,6 +290,11 @@ TESTS = tests/newline1/run-test \ tests/lsdiff13/run-test \ tests/lsdiff14/run-test \ tests/lsdiff15/run-test \ + tests/lsdiff-number-files/run-test \ + tests/lsdiff-files-range/run-test \ + tests/lsdiff-empty-files-removed/run-test \ + tests/lsdiff-addprefix/run-test \ + tests/lsdiff-strip-match/run-test \ tests/lsdiff-hunks-option/run-test \ tests/lsdiff-lines-option/run-test \ tests/lsdiff-exclusion-combined/run-test \ @@ -459,6 +464,13 @@ XFAIL_TESTS += \ tests/grepdiff-annotate/run-test endif +# lsdiff tests: expected to fail when scanner-patchfilter is enabled +# (features not yet implemented in scanner-based lsdiff) +if USE_SCANNER_PATCHFILTER +XFAIL_TESTS += \ + tests/lsdiff-strip-match/run-test +endif + test-perms: src/combinediff$(EXEEXT) src/flipdiff$(EXEEXT) \ src/lsdiff$(EXEEXT) src/grepdiff$(EXEEXT) src/patchview$(EXEEXT) \ scripts/splitdiff diff --git a/tests/lsdiff-addprefix/run-test b/tests/lsdiff-addprefix/run-test new file mode 100755 index 00000000..e43d5476 --- /dev/null +++ b/tests/lsdiff-addprefix/run-test @@ -0,0 +1,26 @@ +#!/bin/sh + +# Test lsdiff --addprefix option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1 +1 @@ +-old ++new +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +EOF + +${LSDIFF} --addprefix=prefix/ diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +prefix/file1 +prefix/file2 +EOF diff --git a/tests/lsdiff-empty-files-removed/run-test b/tests/lsdiff-empty-files-removed/run-test new file mode 100755 index 00000000..e7abf6d1 --- /dev/null +++ b/tests/lsdiff-empty-files-removed/run-test @@ -0,0 +1,44 @@ +#!/bin/sh + +# Test lsdiff -E/--empty-files-as-removed option + +. ${top_srcdir-.}/tests/common.sh + +# Create diffs where files become empty or start empty +mkdir dir dir.orig + +# File that becomes empty (modified -> empty) +echo content > dir.orig/becomes-empty +touch dir/becomes-empty + +# File that starts empty (empty -> modified) +touch dir.orig/was-empty +echo content > dir/was-empty + +# Normal modification +echo old > dir.orig/modified +echo new > dir/modified + +${DIFF} -uN dir.orig dir > diff + +# Without -E, files that are/become empty show as modifications +${LSDIFF} -s --strip=1 diff 2>errors >output1 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output1 || exit 1 +! becomes-empty +! modified +! was-empty +EOF + +# With -E, treat empty files as absent +# becomes-empty: content->empty = treated as removal +# was-empty: empty->content = treated as addition +${LSDIFF} -sE --strip=1 diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +- becomes-empty +! modified ++ was-empty +EOF diff --git a/tests/lsdiff-files-range/run-test b/tests/lsdiff-files-range/run-test new file mode 100755 index 00000000..573c393a --- /dev/null +++ b/tests/lsdiff-files-range/run-test @@ -0,0 +1,63 @@ +#!/bin/sh + +# Test lsdiff -F/--files=RANGE option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1 +1 @@ +-old ++new +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +--- file3 ++++ file3 +@@ -1 +1 @@ +-test ++result +--- file4 ++++ file4 +@@ -1 +1 @@ +-data ++value +EOF + +# Test single file +${LSDIFF} -F2 diff 2>errors >output1 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output1 || exit 1 +file2 +EOF + +# Test range +${LSDIFF} -F2-3 diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +file2 +file3 +EOF + +# Test open-ended range +${LSDIFF} -F3- diff 2>errors >output3 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output3 || exit 1 +file3 +file4 +EOF + +# Test exclusion range +${LSDIFF} -Fx2-3 diff 2>errors >output4 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output4 || exit 1 +file1 +file4 +EOF diff --git a/tests/lsdiff-number-files/run-test b/tests/lsdiff-number-files/run-test new file mode 100755 index 00000000..f3a2ddc3 --- /dev/null +++ b/tests/lsdiff-number-files/run-test @@ -0,0 +1,32 @@ +#!/bin/sh + +# Test lsdiff -N/--number-files option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- file1 ++++ file1 +@@ -1 +1 @@ +-old ++new +--- file2 ++++ file2 +@@ -1 +1 @@ +-foo ++bar +--- file3 ++++ file3 +@@ -1 +1 @@ +-test ++result +EOF + +${LSDIFF} -N diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +File #1 file1 +File #2 file2 +File #3 file3 +EOF diff --git a/tests/lsdiff-strip-match/run-test b/tests/lsdiff-strip-match/run-test new file mode 100755 index 00000000..ca613caa --- /dev/null +++ b/tests/lsdiff-strip-match/run-test @@ -0,0 +1,43 @@ +#!/bin/sh + +# Test lsdiff -p/--strip-match option + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > diff +--- a/src/file1.c ++++ b/src/file1.c +@@ -1 +1 @@ +-old ++new +--- a/docs/readme.txt ++++ b/docs/readme.txt +@@ -1 +1 @@ +-old ++new +--- a/src/file2.c ++++ b/src/file2.c +@@ -1 +1 @@ +-old ++new +EOF + +# Use -p to strip 'a/' and 'b/' prefixes when matching +# Include only files in src/ directory +# Note: -p affects matching, output still shows original paths from diff +${LSDIFF} -p1 -i 'src/*' diff 2>errors >output || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output || exit 1 +a/src/file1.c +a/src/file2.c +EOF + +# Test that we can use --strip to also strip output +${LSDIFF} -p1 -i 'src/*' --strip=1 diff 2>errors >output2 || exit 1 +[ -s errors ] && exit 1 + +cat << EOF | cmp - output2 || exit 1 +src/file1.c +src/file2.c +EOF From d53d1abf117530e7f8482d9c45890ec469a3f60b Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Sat, 18 Oct 2025 10:14:02 +0100 Subject: [PATCH 3/3] Fix symlink updates when switching configurations Use all-local hook to ensure lsdiff and grepdiff symlinks are built during 'make', so they correctly point to filterdiff or patchfilter depending on the configuration. Previously, after reconfiguring between implementations, running 'make' would not update the symlinks, leaving them pointing to the wrong target. Also ensure the patchview directory exists before creating symlinks in it, which fixes 'make distcheck'. Assisted-by: Claude Code --- Makefile.am | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 69cb3fac..9a12a920 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,8 +5,6 @@ DISTCLEANFILES = src/stamp-h[0-9]* src/config.h bin_PROGRAMS = src/interdiff src/filterdiff src/rediff -# lsdiff is provided by symlink to filterdiff (unless scanner-patchfilter is enabled) - # Scanner-based unified patchfilter tool (experimental) if USE_SCANNER_PATCHFILTER bin_PROGRAMS += src/patchfilter @@ -152,6 +150,11 @@ $(filterdiff_links): src/filterdiff$(EXEEXT) $(patchview_links): patchview/patchview-wrapper$(EXEEXT) ln -sf $(notdir $<) $@ +# Ensure all symlinks are created during build +all-local: $(interdiff_links) $(filterdiff_links) src/lsdiff$(EXEEXT) src/grepdiff$(EXEEXT) + @test -d patchview || mkdir -p patchview + @$(MAKE) $(AM_MAKEFLAGS) $(patchview_links) + install-exec-hook: @for f in $(interdiff_links); do \ ln -sf "`echo interdiff$(EXEEXT) | sed '$(transform)'`" \