Skip to content

Commit 1916c07

Browse files
committed
Merge branch 'mm/test-grep-lint' into next
The test suite has been updated to use the 'test_grep' helper instead of bare 'grep' for test assertions, allowing file contents to be printed on failure for easier debugging. A new 'greplint' linter has been introduced to detect and prevent new bare 'grep' assertions from being added to the test suite. * mm/test-grep-lint: t: add greplint to detect bare grep assertions t: convert grep assertions to test_grep t: fix Lexer line count for $() inside double-quoted strings t: extract chainlint's parser into shared module t: fix grep assertions missing file arguments t/README: document test_grep helper
2 parents fe82b5d + be7112d commit 1916c07

385 files changed

Lines changed: 3810 additions & 3328 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

t/.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
t[0-9][0-9][0-9][0-9]/* -whitespace
22
/chainlint/*.expect eol=lf -whitespace
3+
/greplint/*.expect eol=lf -whitespace
4+
/greplint/*.test eol=lf -whitespace
35
/t0110/url-* binary
46
/t3206/* eol=lf
57
/t3900/*.txt eol=lf

t/Makefile

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ TEST_LINT ?= test-lint
2727
ifdef TEST_OUTPUT_DIRECTORY
2828
TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results
2929
CHAINLINTTMP = $(TEST_OUTPUT_DIRECTORY)/chainlinttmp
30+
GREPLINTTMP = $(TEST_OUTPUT_DIRECTORY)/greplinttmp
3031
else
3132
TEST_RESULTS_DIRECTORY = test-results
3233
CHAINLINTTMP = chainlinttmp
34+
GREPLINTTMP = greplinttmp
3335
endif
3436

3537
# Shell quote;
@@ -38,13 +40,15 @@ TEST_SHELL_PATH_SQ = $(subst ','\'',$(TEST_SHELL_PATH))
3840
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
3941
TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
4042
CHAINLINTTMP_SQ = $(subst ','\'',$(CHAINLINTTMP))
43+
GREPLINTTMP_SQ = $(subst ','\'',$(GREPLINTTMP))
4144

4245
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
4346
THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))
4447
TLIBS = $(sort $(wildcard lib-*.sh)) annotate-tests.sh
4548
TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh))
4649
TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh))
4750
CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test)))
51+
GREPLINTTESTS = $(sort $(patsubst greplint/%.test,%,$(wildcard greplint/*.test)))
4852
CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl
4953
UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c)
5054
UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$(X),$(UNIT_TEST_SOURCES))
@@ -63,8 +67,8 @@ test: pre-clean check-meson $(TEST_LINT)
6367
$(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup
6468

6569
ifneq ($(PERL_PATH),)
66-
test: check-chainlint
67-
prove: check-chainlint
70+
test: check-chainlint check-greplint
71+
prove: check-chainlint check-greplint
6872
endif
6973

7074
failed:
@@ -102,7 +106,7 @@ unit-tests-test-tool:
102106
pre-clean:
103107
$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
104108

105-
clean-except-prove-cache: clean-chainlint
109+
clean-except-prove-cache: clean-chainlint clean-greplint
106110
$(RM) -r 'trash directory'.*
107111
$(RM) -r valgrind/bin
108112

@@ -120,6 +124,17 @@ check-chainlint:
120124
{ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \
121125
diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual
122126

127+
clean-greplint:
128+
$(RM) -r '$(GREPLINTTMP_SQ)'
129+
130+
check-greplint:
131+
@mkdir -p '$(GREPLINTTMP_SQ)' && \
132+
'$(PERL_PATH_SQ)' greplint-cat.pl '$(GREPLINTTMP_SQ)' $(GREPLINTTESTS) && \
133+
{ '$(PERL_PATH_SQ)' greplint.pl \
134+
$(patsubst %,greplint/%.test,$(GREPLINTTESTS)) \
135+
>'$(GREPLINTTMP_SQ)'/actual 2>&1 || true; } && \
136+
diff -u '$(GREPLINTTMP_SQ)'/expect '$(GREPLINTTMP_SQ)'/actual
137+
123138
check-meson:
124139
@# awk acts up when trying to match single quotes, so we use \047 instead.
125140
@mkdir -p mesontmp && \
@@ -139,7 +154,7 @@ check-meson:
139154
test-lint: test-lint-duplicates test-lint-executable \
140155
test-lint-filenames
141156
ifneq ($(PERL_PATH),)
142-
test-lint: test-lint-shell-syntax
157+
test-lint: test-lint-shell-syntax test-greplint
143158
else
144159
GIT_TEST_CHAIN_LINT = 0
145160
endif
@@ -160,6 +175,9 @@ test-lint-executable:
160175
test-lint-shell-syntax:
161176
@'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T) $(THELPERS) $(TPERF)
162177

178+
test-greplint:
179+
@'$(PERL_PATH_SQ)' greplint.pl $(T) $(THELPERS) $(TPERF)
180+
163181
test-lint-filenames:
164182
@# We do *not* pass a glob to ls-files but use grep instead, to catch
165183
@# non-ASCII characters (which are quoted within double-quotes)
@@ -185,7 +203,8 @@ perf:
185203
$(MAKE) -C perf/ all
186204

187205
.PHONY: pre-clean $(T) aggregate-results clean valgrind perf \
188-
check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS)
206+
check-chainlint clean-chainlint test-chainlint \
207+
check-greplint clean-greplint test-greplint $(UNIT_TESTS)
189208

190209
.PHONY: libgit-sys-test libgit-rs-test
191210
libgit-sys-test:

t/README

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,40 @@ see test-lib-functions.sh for the full list and their options.
10391039

10401040
Check whether a file has the length it is expected to.
10411041

1042+
- test_grep [!] [<grep-options>] <pattern> <file>
1043+
1044+
Check whether <file> contains a line matching <pattern>, or
1045+
with '!' that no line matches. Use this instead of bare
1046+
'grep <pattern> <file>' in test assertions. On failure,
1047+
test_grep prints the contents of <file> for easier debugging,
1048+
whereas a bare 'grep' would fail silently.
1049+
1050+
For negation, pass '!' as the first argument:
1051+
1052+
test_grep ! "^diff --git" actual
1053+
1054+
Do not negate by writing '! test_grep', as that suppresses the
1055+
diagnostic output.
1056+
1057+
test_grep should only be used as a test assertion. When grep
1058+
is used as a data filter (e.g. 'grep -v "^index" actual >filtered')
1059+
or inside a command substitution (e.g. '$(grep -c ...)'), plain
1060+
'grep' is the right choice because the exit code is not the
1061+
assertion itself.
1062+
1063+
test_grep requires <file> to exist and will BUG otherwise, so
1064+
use it only where the file is guaranteed to exist at that point.
1065+
When a file's presence is conditional (a backend-specific file,
1066+
or a path that only exists on some platforms, such as an NTFS
1067+
8.3 short name), guard the assertion on that condition (a
1068+
prerequisite, or a 'test -e' on the path) and use test_grep
1069+
inside the guard:
1070+
1071+
if test_have_prereq REFFILES
1072+
then
1073+
test_grep ! "$refname" .git/packed-refs
1074+
fi
1075+
10421076
- test_path_is_file <path>
10431077
test_path_is_dir <path>
10441078
test_path_is_missing <path>

0 commit comments

Comments
 (0)