log: add exhaustive tests for pattern style options & config

Add exhaustive tests for how the different grep.patternType options & the corresponding command-line options affect git-log. Before this change it was possible to patch revision.c so that the --basic-regexp option was synonymous with --extended-regexp, and --perl-regexp wasn't recognized at all, and still have 100% of the test suite pass. This was because the first test being modified here, added in commit 34a4ae55b2 ("log --grep: use the same helper to set -E/-F options as "git grep"", 2012-10-03), didn't actually check whether we'd enabled extended regular expressions as distinct from re-toggling non-fixed string support. Fix that by changing the pattern to a pattern that'll only match if --extended-regexp option is provided, but won't match under the default --basic-regexp option. Other potential regressions were possible since there were no tests for the rest of the combinations of grep.patternType configuration toggles & corresponding git-log command-line options. Add exhaustive tests for those. The patterns being passed to fixed/basic/extended/PCRE are carefully crafted to return the wrong thing if the grep engine were to pick any other matching method than the one it's told to use. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed May 20, 2017 at 21:42 UTC 9df46763ef1ee46f2dc1de768b1403552779d011
1 file changed +97 -1
t/t4202-log.sh
+97 -1
@@ -262,7 +262,30 @@ test_expect_success 'log --grep -i' '
262
263 test_expect_success 'log -F -E --grep=<ere> uses ere' '
264 echo second >expect &&
265 - git log -1 --pretty="tformat:%s" -F -E --grep=s.c.nd >actual &&
265 + # basic would need \(s\) to do the same
266 + git log -1 --pretty="tformat:%s" -F -E --grep="(s).c.nd" >actual &&
267 + test_cmp expect actual
268 +'
269 +
270 +test_expect_success PCRE 'log -F -E --perl-regexp --grep=<pcre> uses PCRE' '
271 + test_when_finished "rm -rf num_commits" &&
272 + git init num_commits &&
273 + (
274 + cd num_commits &&
275 + test_commit 1d &&
276 + test_commit 2e
277 + ) &&
278 +
279 + # In PCRE \d in [\d] is like saying "0-9", and matches the 2
280 + # in 2e...
281 + echo 2e >expect &&
282 + git -C num_commits log -1 --pretty="tformat:%s" -F -E --perl-regexp --grep="[\d]" >actual &&
283 + test_cmp expect actual &&
284 +
285 + # ...in POSIX basic and extended it is the same as [d],
286 + # i.e. "d", which matches 1d, but does not match 2e.
287 + echo 1d >expect &&
288 + git -C num_commits log -1 --pretty="tformat:%s" -F -E --grep="[\d]" >actual &&
289 test_cmp expect actual
290 '
291
@@ -280,6 +303,79 @@ test_expect_success 'log with grep.patternType configuration and command line' '
303 test_cmp expect actual
304 '
305
306 +test_expect_success 'log with various grep.patternType configurations & command-lines' '
307 + git init pattern-type &&
308 + (
309 + cd pattern-type &&
310 + test_commit 1 file A &&
311 +
312 + # The tagname is overridden here because creating a
313 + # tag called "(1|2)" as test_commit would otherwise
314 + # implicitly do would fail on e.g. MINGW.
315 + test_commit "(1|2)" file B 2 &&
316 +
317 + echo "(1|2)" >expect.fixed &&
318 + cp expect.fixed expect.basic &&
319 + cp expect.fixed expect.extended &&
320 + cp expect.fixed expect.perl &&
321 +
322 + # A strcmp-like match with fixed.
323 + git -c grep.patternType=fixed log --pretty=tformat:%s \
324 + --grep="(1|2)" >actual.fixed &&
325 +
326 + # POSIX basic matches (, | and ) literally.
327 + git -c grep.patternType=basic log --pretty=tformat:%s \
328 + --grep="(.|.)" >actual.basic &&
329 +
330 + # POSIX extended needs to have | escaped to match it
331 + # literally, whereas under basic this is the same as
332 + # (|2), i.e. it would also match "1". This test checks
333 + # for extended by asserting that it is not matching
334 + # what basic would match.
335 + git -c grep.patternType=extended log --pretty=tformat:%s \
336 + --grep="\|2" >actual.extended &&
337 + if test_have_prereq PCRE
338 + then
339 + # Only PCRE would match [\d]\| with only
340 + # "(1|2)" due to [\d]. POSIX basic would match
341 + # both it and "1" since similarly to the
342 + # extended match above it is the same as
343 + # \([\d]\|\). POSIX extended would
344 + # match neither.
345 + git -c grep.patternType=perl log --pretty=tformat:%s \
346 + --grep="[\d]\|" >actual.perl &&
347 + test_cmp expect.perl actual.perl
348 + fi &&
349 + test_cmp expect.fixed actual.fixed &&
350 + test_cmp expect.basic actual.basic &&
351 + test_cmp expect.extended actual.extended &&
352 +
353 + git log --pretty=tformat:%s -F \
354 + --grep="(1|2)" >actual.fixed.short-arg &&
355 + git log --pretty=tformat:%s -E \
356 + --grep="\|2" >actual.extended.short-arg &&
357 + test_cmp expect.fixed actual.fixed.short-arg &&
358 + test_cmp expect.extended actual.extended.short-arg &&
359 +
360 + git log --pretty=tformat:%s --fixed-strings \
361 + --grep="(1|2)" >actual.fixed.long-arg &&
362 + git log --pretty=tformat:%s --basic-regexp \
363 + --grep="(.|.)" >actual.basic.long-arg &&
364 + git log --pretty=tformat:%s --extended-regexp \
365 + --grep="\|2" >actual.extended.long-arg &&
366 + if test_have_prereq PCRE
367 + then
368 + git log --pretty=tformat:%s --perl-regexp \
369 + --grep="[\d]\|" >actual.perl.long-arg &&
370 + test_cmp expect.perl actual.perl.long-arg
371 +
372 + fi &&
373 + test_cmp expect.fixed actual.fixed.long-arg &&
374 + test_cmp expect.basic actual.basic.long-arg &&
375 + test_cmp expect.extended actual.extended.long-arg
376 + )
377 +'
378 +
379 cat > expect <<EOF
380 * Second
381 * sixth