t / t4051-diff-function-context.shon commit xdiff: fix merging of hunks with -W context and -u context (45d2f75)
   1#!/bin/sh
   2
   3test_description='diff function context'
   4
   5. ./test-lib.sh
   6
   7dir="$TEST_DIRECTORY/t4051"
   8
   9commit_and_tag () {
  10        tag=$1 &&
  11        shift &&
  12        git add "$@" &&
  13        test_tick &&
  14        git commit -m "$tag" &&
  15        git tag "$tag"
  16}
  17
  18first_context_line () {
  19        awk '
  20                found {print; exit}
  21                /^@@/ {found = 1}
  22        '
  23}
  24
  25last_context_line () {
  26        sed -ne \$p
  27}
  28
  29check_diff () {
  30        name=$1
  31        desc=$2
  32        options="-W $3"
  33
  34        test_expect_success "$desc" '
  35                git diff $options "$name^" "$name" >"$name.diff"
  36        '
  37
  38        test_expect_success ' diff applies' '
  39                test_when_finished "git reset --hard" &&
  40                git checkout --detach "$name^" &&
  41                git apply --index "$name.diff" &&
  42                git diff --exit-code "$name"
  43        '
  44}
  45
  46test_expect_success 'setup' '
  47        cat "$dir/includes.c" "$dir/dummy.c" "$dir/dummy.c" "$dir/hello.c" \
  48                "$dir/dummy.c" "$dir/dummy.c" >file.c &&
  49        commit_and_tag initial file.c &&
  50
  51        grep -v "delete me from hello" <file.c >file.c.new &&
  52        mv file.c.new file.c &&
  53        commit_and_tag changed_hello file.c &&
  54
  55        grep -v "delete me from includes" <file.c >file.c.new &&
  56        mv file.c.new file.c &&
  57        commit_and_tag changed_includes file.c &&
  58
  59        cat "$dir/appended1.c" >>file.c &&
  60        commit_and_tag appended file.c &&
  61
  62        cat "$dir/appended2.c" >>file.c &&
  63        commit_and_tag extended file.c &&
  64
  65        grep -v "Begin of second part" <file.c >file.c.new &&
  66        mv file.c.new file.c &&
  67        commit_and_tag long_common_tail file.c &&
  68
  69        git checkout initial &&
  70        cat "$dir/hello.c" "$dir/dummy.c" >file.c &&
  71        commit_and_tag hello_dummy file.c &&
  72
  73        # overlap function context of 1st change and -u context of 2nd change
  74        grep -v "delete me from hello" <"$dir/hello.c" >file.c &&
  75        sed 2p <"$dir/dummy.c" >>file.c &&
  76        commit_and_tag changed_hello_dummy file.c &&
  77
  78        git checkout initial &&
  79        grep -v "delete me from hello" <file.c >file.c.new &&
  80        mv file.c.new file.c &&
  81        cat "$dir/appended1.c" >>file.c &&
  82        commit_and_tag changed_hello_appended file.c
  83'
  84
  85check_diff changed_hello 'changed function'
  86
  87test_expect_success ' context includes begin' '
  88        grep "^ .*Begin of hello" changed_hello.diff
  89'
  90
  91test_expect_success ' context includes end' '
  92        grep "^ .*End of hello" changed_hello.diff
  93'
  94
  95test_expect_success ' context does not include other functions' '
  96        test $(grep -c "^[ +-].*Begin" changed_hello.diff) -le 1
  97'
  98
  99test_expect_success ' context does not include preceding empty lines' '
 100        test "$(first_context_line <changed_hello.diff)" != " "
 101'
 102
 103test_expect_success ' context does not include trailing empty lines' '
 104        test "$(last_context_line <changed_hello.diff)" != " "
 105'
 106
 107check_diff changed_includes 'changed includes'
 108
 109test_expect_success ' context includes begin' '
 110        grep "^ .*Begin.h" changed_includes.diff
 111'
 112
 113test_expect_success ' context includes end' '
 114        grep "^ .*End.h" changed_includes.diff
 115'
 116
 117test_expect_success ' context does not include other functions' '
 118        test $(grep -c "^[ +-].*Begin" changed_includes.diff) -le 1
 119'
 120
 121test_expect_success ' context does not include trailing empty lines' '
 122        test "$(last_context_line <changed_includes.diff)" != " "
 123'
 124
 125check_diff appended 'appended function'
 126
 127test_expect_success ' context includes begin' '
 128        grep "^[+].*Begin of first part" appended.diff
 129'
 130
 131test_expect_success ' context includes end' '
 132        grep "^[+].*End of first part" appended.diff
 133'
 134
 135test_expect_success ' context does not include other functions' '
 136        test $(grep -c "^[ +-].*Begin" appended.diff) -le 1
 137'
 138
 139check_diff extended 'appended function part'
 140
 141test_expect_success ' context includes begin' '
 142        grep "^ .*Begin of first part" extended.diff
 143'
 144
 145test_expect_success ' context includes end' '
 146        grep "^[+].*End of second part" extended.diff
 147'
 148
 149test_expect_success ' context does not include other functions' '
 150        test $(grep -c "^[ +-].*Begin" extended.diff) -le 2
 151'
 152
 153test_expect_success ' context does not include preceding empty lines' '
 154        test "$(first_context_line <extended.diff)" != " "
 155'
 156
 157check_diff long_common_tail 'change with long common tail and no context' -U0
 158
 159test_expect_success ' context includes begin' '
 160        grep "^ .*Begin of first part" long_common_tail.diff
 161'
 162
 163test_expect_success ' context includes end' '
 164        grep "^ .*End of second part" long_common_tail.diff
 165'
 166
 167test_expect_success ' context does not include other functions' '
 168        test $(grep -c "^[ +-].*Begin" long_common_tail.diff) -le 2
 169'
 170
 171test_expect_success ' context does not include preceding empty lines' '
 172        test "$(first_context_line <long_common_tail.diff.diff)" != " "
 173'
 174
 175check_diff changed_hello_appended 'changed function plus appended function'
 176
 177test_expect_success ' context includes begin' '
 178        grep "^ .*Begin of hello" changed_hello_appended.diff &&
 179        grep "^[+].*Begin of first part" changed_hello_appended.diff
 180'
 181
 182test_expect_success ' context includes end' '
 183        grep "^ .*End of hello" changed_hello_appended.diff &&
 184        grep "^[+].*End of first part" changed_hello_appended.diff
 185'
 186
 187test_expect_success ' context does not include other functions' '
 188        test $(grep -c "^[ +-].*Begin" changed_hello_appended.diff) -le 2
 189'
 190
 191check_diff changed_hello_dummy 'changed two consecutive functions'
 192
 193test_expect_success ' context includes begin' '
 194        grep "^ .*Begin of hello" changed_hello_dummy.diff &&
 195        grep "^ .*Begin of dummy" changed_hello_dummy.diff
 196'
 197
 198test_expect_success ' context includes end' '
 199        grep "^ .*End of hello" changed_hello_dummy.diff &&
 200        grep "^ .*End of dummy" changed_hello_dummy.diff
 201'
 202
 203test_expect_success ' overlapping hunks are merged' '
 204        test $(grep -c "^@@" changed_hello_dummy.diff) -eq 1
 205'
 206
 207test_done