t / t4124-apply-ws-rule.shon commit t/t1304: use 'test -r' to test readability rather than looking at mode bits (71c4d6c)
   1#!/bin/sh
   2
   3test_description='core.whitespace rules and git apply'
   4
   5. ./test-lib.sh
   6
   7prepare_test_file () {
   8
   9        # A line that has character X is touched iff RULE is in effect:
  10        #       X  RULE
  11        #       !  trailing-space
  12        #       @  space-before-tab
  13        #       #  indent-with-non-tab
  14        sed -e "s/_/ /g" -e "s/>/       /" <<-\EOF
  15                An_SP in an ordinary line>and a HT.
  16                >A HT.
  17                _>A SP and a HT (@).
  18                _>_A SP, a HT and a SP (@).
  19                _______Seven SP.
  20                ________Eight SP (#).
  21                _______>Seven SP and a HT (@).
  22                ________>Eight SP and a HT (@#).
  23                _______>_Seven SP, a HT and a SP (@).
  24                ________>_Eight SP, a HT and a SP (@#).
  25                _______________Fifteen SP (#).
  26                _______________>Fifteen SP and a HT (@#).
  27                ________________Sixteen SP (#).
  28                ________________>Sixteen SP and a HT (@#).
  29                _____a__Five SP, a non WS, two SP.
  30                A line with a (!) trailing SP_
  31                A line with a (!) trailing HT>
  32        EOF
  33}
  34
  35apply_patch () {
  36        >target &&
  37        sed -e "s|\([ab]\)/file|\1/target|" <patch |
  38        git apply "$@"
  39}
  40
  41test_fix () {
  42
  43        # fix should not barf
  44        apply_patch --whitespace=fix || return 1
  45
  46        # find touched lines
  47        diff file target | sed -n -e "s/^> //p" >fixed
  48
  49        # the changed lines are all expeced to change
  50        fixed_cnt=$(wc -l <fixed)
  51        case "$1" in
  52        '') expect_cnt=$fixed_cnt ;;
  53        ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;;
  54        esac
  55        test $fixed_cnt -eq $expect_cnt || return 1
  56
  57        # and we are not missing anything
  58        case "$1" in
  59        '') expect_cnt=0 ;;
  60        ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;;
  61        esac
  62        test $fixed_cnt -eq $expect_cnt || return 1
  63
  64        # Get the patch actually applied
  65        git diff-files -p target >fixed-patch
  66        test -s fixed-patch && return 0
  67
  68        # Make sure it is complaint-free
  69        >target
  70        git apply --whitespace=error-all <fixed-patch
  71
  72}
  73
  74test_expect_success setup '
  75
  76        >file &&
  77        git add file &&
  78        prepare_test_file >file &&
  79        git diff-files -p >patch &&
  80        >target &&
  81        git add target
  82
  83'
  84
  85test_expect_success 'whitespace=nowarn, default rule' '
  86
  87        apply_patch --whitespace=nowarn &&
  88        diff file target
  89
  90'
  91
  92test_expect_success 'whitespace=warn, default rule' '
  93
  94        apply_patch --whitespace=warn &&
  95        diff file target
  96
  97'
  98
  99test_expect_success 'whitespace=error-all, default rule' '
 100
 101        apply_patch --whitespace=error-all && return 1
 102        test -s target && return 1
 103        : happy
 104
 105'
 106
 107test_expect_success 'whitespace=error-all, no rule' '
 108
 109        git config core.whitespace -trailing,-space-before,-indent &&
 110        apply_patch --whitespace=error-all &&
 111        diff file target
 112
 113'
 114
 115test_expect_success 'whitespace=error-all, no rule (attribute)' '
 116
 117        git config --unset core.whitespace &&
 118        echo "target -whitespace" >.gitattributes &&
 119        apply_patch --whitespace=error-all &&
 120        diff file target
 121
 122'
 123
 124for t in - ''
 125do
 126        case "$t" in '') tt='!' ;; *) tt= ;; esac
 127        for s in - ''
 128        do
 129                case "$s" in '') ts='@' ;; *) ts= ;; esac
 130                for i in - ''
 131                do
 132                        case "$i" in '') ti='#' ;; *) ti= ;; esac
 133                        rule=${t}trailing,${s}space,${i}indent
 134
 135                        rm -f .gitattributes
 136                        test_expect_success "rule=$rule" '
 137                                git config core.whitespace "$rule" &&
 138                                test_fix "$tt$ts$ti"
 139                        '
 140
 141                        test_expect_success "rule=$rule (attributes)" '
 142                                git config --unset core.whitespace &&
 143                                echo "target whitespace=$rule" >.gitattributes &&
 144                                test_fix "$tt$ts$ti"
 145                        '
 146
 147                done
 148        done
 149done
 150
 151create_patch () {
 152        sed -e "s/_/ /" <<-\EOF
 153                diff --git a/target b/target
 154                index e69de29..8bd6648 100644
 155                --- a/target
 156                +++ b/target
 157                @@ -0,0 +1,3 @@
 158                +An empty line follows
 159                +
 160                +A line with trailing whitespace and no newline_
 161                \ No newline at end of file
 162        EOF
 163}
 164
 165test_expect_success 'trailing whitespace & no newline at the end of file' '
 166        >target &&
 167        create_patch >patch-file &&
 168        git apply --whitespace=fix patch-file &&
 169        grep "newline$" target &&
 170        grep "^$" target
 171'
 172
 173test_expect_success 'blank at EOF with --whitespace=fix (1)' '
 174        : these can fail depending on what we did before
 175        git config --unset core.whitespace
 176        rm -f .gitattributes
 177
 178        { echo a; echo b; echo c; } >one &&
 179        git add one &&
 180        { echo a; echo b; echo c; } >expect &&
 181        { cat expect; echo; } >one &&
 182        git diff -- one >patch &&
 183
 184        git checkout one &&
 185        git apply --whitespace=fix patch &&
 186        test_cmp expect one
 187'
 188
 189test_expect_success 'blank at EOF with --whitespace=fix (2)' '
 190        { echo a; echo b; echo c; } >one &&
 191        git add one &&
 192        { echo a; echo c; } >expect &&
 193        { cat expect; echo; echo; } >one &&
 194        git diff -- one >patch &&
 195
 196        git checkout one &&
 197        git apply --whitespace=fix patch &&
 198        test_cmp expect one
 199'
 200
 201test_expect_success 'blank at EOF with --whitespace=fix (3)' '
 202        { echo a; echo b; echo; } >one &&
 203        git add one &&
 204        { echo a; echo c; echo; } >expect &&
 205        { cat expect; echo; echo; } >one &&
 206        git diff -- one >patch &&
 207
 208        git checkout one &&
 209        git apply --whitespace=fix patch &&
 210        test_cmp expect one
 211'
 212
 213test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
 214        { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
 215        git add one &&
 216        { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
 217        cp expect one &&
 218        git diff -- one >patch &&
 219
 220        git checkout one &&
 221        git apply --whitespace=fix patch &&
 222        test_cmp expect one
 223'
 224
 225test_expect_success 'blank at EOF with --whitespace=warn' '
 226        { echo a; echo b; echo c; } >one &&
 227        git add one &&
 228        echo >>one &&
 229        cat one >expect &&
 230        git diff -- one >patch &&
 231
 232        git checkout one &&
 233        git apply --whitespace=warn patch 2>error &&
 234        test_cmp expect one &&
 235        grep "new blank line at EOF" error
 236'
 237
 238test_expect_success 'blank at EOF with --whitespace=error' '
 239        { echo a; echo b; echo c; } >one &&
 240        git add one &&
 241        cat one >expect &&
 242        echo >>one &&
 243        git diff -- one >patch &&
 244
 245        git checkout one &&
 246        test_must_fail git apply --whitespace=error patch 2>error &&
 247        test_cmp expect one &&
 248        grep "new blank line at EOF" error
 249'
 250
 251test_expect_success 'blank but not empty at EOF' '
 252        { echo a; echo b; echo c; } >one &&
 253        git add one &&
 254        echo "   " >>one &&
 255        cat one >expect &&
 256        git diff -- one >patch &&
 257
 258        git checkout one &&
 259        git apply --whitespace=warn patch 2>error &&
 260        test_cmp expect one &&
 261        grep "new blank line at EOF" error
 262'
 263
 264test_done