diff options
Diffstat (limited to 't/t4124-apply-ws-rule.sh')
-rwxr-xr-x | t/t4124-apply-ws-rule.sh | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh new file mode 100755 index 0000000000..d350065f25 --- /dev/null +++ b/t/t4124-apply-ws-rule.sh @@ -0,0 +1,525 @@ +#!/bin/sh + +test_description='core.whitespace rules and git apply' + +. ./test-lib.sh + +prepare_test_file () { + + # A line that has character X is touched iff RULE is in effect: + # X RULE + # ! trailing-space + # @ space-before-tab + # # indent-with-non-tab (default tab width 8) + # = indent-with-non-tab,tabwidth=16 + # % tab-in-indent + sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF + An_SP in an ordinary line>and a HT. + >A HT (%). + _>A SP and a HT (@%). + _>_A SP, a HT and a SP (@%). + _______Seven SP. + ________Eight SP (#). + _______>Seven SP and a HT (@%). + ________>Eight SP and a HT (@#%). + _______>_Seven SP, a HT and a SP (@%). + ________>_Eight SP, a HT and a SP (@#%). + _______________Fifteen SP (#). + _______________>Fifteen SP and a HT (@#%). + ________________Sixteen SP (#=). + ________________>Sixteen SP and a HT (@#%=). + _____a__Five SP, a non WS, two SP. + A line with a (!) trailing SP_ + A line with a (!) trailing HT> + EOF +} + +apply_patch () { + >target && + sed -e "s|\([ab]\)/file|\1/target|" <patch | + git apply "$@" +} + +test_fix () { + # fix should not barf + apply_patch --whitespace=fix || return 1 + + # find touched lines + $DIFF file target | sed -n -e "s/^> //p" >fixed + + # the changed lines are all expected to change + fixed_cnt=$(wc -l <fixed) + case "$1" in + '') expect_cnt=$fixed_cnt ;; + ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # and we are not missing anything + case "$1" in + '') expect_cnt=0 ;; + ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # Get the patch actually applied + git diff-files -p target >fixed-patch + test -s fixed-patch && return 0 + + # Make sure it is complaint-free + >target + git apply --whitespace=error-all <fixed-patch + +} + +test_expect_success setup ' + + >file && + git add file && + prepare_test_file >file && + git diff-files -p >patch && + >target && + git add target + +' + +test_expect_success 'whitespace=nowarn, default rule' ' + + apply_patch --whitespace=nowarn && + test_cmp file target + +' + +test_expect_success 'whitespace=warn, default rule' ' + + apply_patch --whitespace=warn && + test_cmp file target + +' + +test_expect_success 'whitespace=error-all, default rule' ' + + test_must_fail apply_patch --whitespace=error-all && + ! test -s target + +' + +test_expect_success 'whitespace=error-all, no rule' ' + + git config core.whitespace -trailing,-space-before,-indent && + apply_patch --whitespace=error-all && + test_cmp file target + +' + +test_expect_success 'whitespace=error-all, no rule (attribute)' ' + + git config --unset core.whitespace && + echo "target -whitespace" >.gitattributes && + apply_patch --whitespace=error-all && + test_cmp file target + +' + +test_expect_success 'spaces inserted by tab-in-indent' ' + + git config core.whitespace -trailing,-space,-indent,tab && + rm -f .gitattributes && + test_fix % && + sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF >expect && + An_SP in an ordinary line>and a HT. + ________A HT (%). + ________A SP and a HT (@%). + _________A SP, a HT and a SP (@%). + _______Seven SP. + ________Eight SP (#). + ________Seven SP and a HT (@%). + ________________Eight SP and a HT (@#%). + _________Seven SP, a HT and a SP (@%). + _________________Eight SP, a HT and a SP (@#%). + _______________Fifteen SP (#). + ________________Fifteen SP and a HT (@#%). + ________________Sixteen SP (#=). + ________________________Sixteen SP and a HT (@#%=). + _____a__Five SP, a non WS, two SP. + A line with a (!) trailing SP_ + A line with a (!) trailing HT> + EOF + test_cmp expect target + +' + +for t in - '' +do + case "$t" in '') tt='!' ;; *) tt= ;; esac + for s in - '' + do + case "$s" in '') ts='@' ;; *) ts= ;; esac + for i in - '' + do + case "$i" in '') ti='#' ti16='=';; *) ti= ti16= ;; esac + for h in - '' + do + [ -z "$h$i" ] && continue + case "$h" in '') th='%' ;; *) th= ;; esac + rule=${t}trailing,${s}space,${i}indent,${h}tab + + rm -f .gitattributes + test_expect_success "rule=$rule" ' + git config core.whitespace "$rule" && + test_fix "$tt$ts$ti$th" + ' + + test_expect_success "rule=$rule,tabwidth=16" ' + git config core.whitespace "$rule,tabwidth=16" && + test_fix "$tt$ts$ti16$th" + ' + + test_expect_success "rule=$rule (attributes)" ' + git config --unset core.whitespace && + echo "target whitespace=$rule" >.gitattributes && + test_fix "$tt$ts$ti$th" + ' + + test_expect_success "rule=$rule,tabwidth=16 (attributes)" ' + echo "target whitespace=$rule,tabwidth=16" >.gitattributes && + test_fix "$tt$ts$ti16$th" + ' + + done + done + done +done + +create_patch () { + sed -e "s/_/ /" <<-\EOF + diff --git a/target b/target + index e69de29..8bd6648 100644 + --- a/target + +++ b/target + @@ -0,0 +1,3 @@ + +An empty line follows + + + +A line with trailing whitespace and no newline_ + \ No newline at end of file + EOF +} + +test_expect_success 'trailing whitespace & no newline at the end of file' ' + >target && + create_patch >patch-file && + git apply --whitespace=fix patch-file && + grep "newline$" target && + grep "^$" target +' + +test_expect_success 'blank at EOF with --whitespace=fix (1)' ' + test_might_fail git config --unset core.whitespace && + rm -f .gitattributes && + + { echo a; echo b; echo c; } >one && + git add one && + { echo a; echo b; echo c; } >expect && + { cat expect; echo; } >one && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=fix patch && + test_cmp expect one +' + +test_expect_success 'blank at EOF with --whitespace=fix (2)' ' + { echo a; echo b; echo c; } >one && + git add one && + { echo a; echo c; } >expect && + { cat expect; echo; echo; } >one && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=fix patch && + test_cmp expect one +' + +test_expect_success 'blank at EOF with --whitespace=fix (3)' ' + { echo a; echo b; echo; } >one && + git add one && + { echo a; echo c; echo; } >expect && + { cat expect; echo; echo; } >one && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=fix patch && + test_cmp expect one +' + +test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' ' + { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one && + git add one && + { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect && + cp expect one && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=fix patch && + test_cmp expect one +' + +test_expect_success 'blank at EOF with --whitespace=warn' ' + { echo a; echo b; echo c; } >one && + git add one && + echo >>one && + cat one >expect && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=warn patch 2>error && + test_cmp expect one && + grep "new blank line at EOF" error +' + +test_expect_success 'blank at EOF with --whitespace=error' ' + { echo a; echo b; echo c; } >one && + git add one && + cat one >expect && + echo >>one && + git diff -- one >patch && + + git checkout one && + test_must_fail git apply --whitespace=error patch 2>error && + test_cmp expect one && + grep "new blank line at EOF" error +' + +test_expect_success 'blank but not empty at EOF' ' + { echo a; echo b; echo c; } >one && + git add one && + echo " " >>one && + cat one >expect && + git diff -- one >patch && + + git checkout one && + git apply --whitespace=warn patch 2>error && + test_cmp expect one && + grep "new blank line at EOF" error +' + +test_expect_success 'applying beyond EOF requires one non-blank context line' ' + { echo; echo; echo; echo; } >one && + git add one && + { echo b; } >>one && + git diff -- one >patch && + + git checkout one && + { echo a; echo; } >one && + cp one expect && + test_must_fail git apply --whitespace=fix patch && + test_cmp one expect && + test_must_fail git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'tons of blanks at EOF should not apply' ' + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do + echo; echo; echo; echo; + done >one && + git add one && + echo a >>one && + git diff -- one >patch && + + >one && + test_must_fail git apply --whitespace=fix patch && + test_must_fail git apply --ignore-space-change --whitespace=fix patch +' + +test_expect_success 'missing blank line at end with --whitespace=fix' ' + echo a >one && + echo >>one && + git add one && + echo b >>one && + cp one expect && + git diff -- one >patch && + echo a >one && + cp one saved-one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv saved-one one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'two missing blank lines at end with --whitespace=fix' ' + { echo a; echo; echo b; echo c; } >one && + cp one no-blank-lines && + { echo; echo; } >>one && + git add one && + echo d >>one && + cp one expect && + echo >>one && + git diff -- one >patch && + cp no-blank-lines one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv no-blank-lines one && + test_must_fail git apply patch && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' ' + { echo a; echo; } >one && + git add one && + { echo b; echo a; echo; } >one && + cp one expect && + git diff -- one >patch && + echo a >one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'shrink file with tons of missing blanks at end of file' ' + { echo a; echo b; echo c; } >one && + cp one no-blank-lines && + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do + echo; echo; echo; echo; + done >>one && + git add one && + echo a >one && + cp one expect && + git diff -- one >patch && + cp no-blank-lines one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv no-blank-lines one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'missing blanks at EOF must only match blank lines' ' + { echo a; echo b; } >one && + git add one && + { echo c; echo d; } >>one && + git diff -- one >patch && + + echo a >one && + test_must_fail git apply patch && + test_must_fail git apply --whitespace=fix patch && + test_must_fail git apply --ignore-space-change --whitespace=fix patch +' + +sed -e's/Z//' >one <<EOF +a +b +c + Z +EOF + +test_expect_success 'missing blank line should match context line with spaces' ' + git add one && + echo d >>one && + git diff -- one >patch && + { echo a; echo b; echo c; } >one && + cp one expect && + { echo; echo d; } >>expect && + git add one && + + git apply --whitespace=fix patch && + test_cmp one expect +' + +sed -e's/Z//' >one <<EOF +a +b +c + Z +EOF + +test_expect_success 'same, but with the --ignore-space-option' ' + git add one && + echo d >>one && + cp one expect && + git diff -- one >patch && + { echo a; echo b; echo c; } >one && + git add one && + + git checkout-index -f one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' ' + git config core.whitespace cr-at-eol && + printf "a\r\n" >one && + printf "b\r\n" >>one && + printf "c\r\n" >>one && + cp one save-one && + printf " \r\n" >>one && + git add one && + printf "d\r\n" >>one && + cp one expect && + git diff -- one >patch && + mv save-one one && + + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' ' + git config --unset core.whitespace && + printf "a\r\n" >one && + printf "b\r\n" >>one && + printf "c\r\n" >>one && + cp one save-one && + printf " \r\n" >>one && + git add one && + cp one expect && + printf "d\r\n" >>one && + git diff -- one >patch && + mv save-one one && + echo d >>expect && + + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'whitespace=fix to expand' ' + qz_to_tab_space >preimage <<-\EOF && + QQa + QQb + QQc + ZZZZZZZZZZZZZZZZd + QQe + QQf + QQg + EOF + qz_to_tab_space >patch <<-\EOF && + diff --git a/preimage b/preimage + --- a/preimage + +++ b/preimage + @@ -1,7 +1,6 @@ + QQa + QQb + QQc + -QQd + QQe + QQf + QQg + EOF + git -c core.whitespace=tab-in-indent apply --whitespace=fix patch +' + +test_expect_success 'whitespace check skipped for excluded paths' ' + git config core.whitespace blank-at-eol && + >used && + >unused && + git add used unused && + echo "used" >used && + echo "unused " >unused && + git diff-files -p used unused >patch && + git apply --include=used --stat --whitespace=error <patch +' + +test_done |