1#!/bin/sh
   2test_description='word diff colors'
   4. ./test-lib.sh
   6. "$TEST_DIRECTORY"/diff-lib.sh
   7cat >pre.simple <<-\EOF
   9        h(4)
  10        a = b + c
  12EOF
  13cat >post.simple <<-\EOF
  14        h(4),hh[44]
  15        a = b + c
  17        aa = a
  19        aeff = aeff * ( aaa )
  21EOF
  22cat >expect.letter-runs-are-words <<-\EOF
  23        <BOLD>diff --git a/pre b/post<RESET>
  24        <BOLD>index 330b04f..5ed8eff 100644<RESET>
  25        <BOLD>--- a/pre<RESET>
  26        <BOLD>+++ b/post<RESET>
  27        <CYAN>@@ -1,3 +1,7 @@<RESET>
  28        h(4),<GREEN>hh<RESET>[44]
  29        a = b + c<RESET>
  31        <GREEN>aa = a<RESET>
  33        <GREEN>aeff = aeff * ( aaa<RESET> )
  35EOF
  36cat >expect.non-whitespace-is-word <<-\EOF
  37        <BOLD>diff --git a/pre b/post<RESET>
  38        <BOLD>index 330b04f..5ed8eff 100644<RESET>
  39        <BOLD>--- a/pre<RESET>
  40        <BOLD>+++ b/post<RESET>
  41        <CYAN>@@ -1,3 +1,7 @@<RESET>
  42        h(4)<GREEN>,hh[44]<RESET>
  43        a = b + c<RESET>
  45        <GREEN>aa = a<RESET>
  47        <GREEN>aeff = aeff * ( aaa )<RESET>
  49EOF
  50word_diff () {
  52        test_must_fail git diff --no-index "$@" pre post >output &&
  53        test_decode_color <output >output.decrypted &&
  54        test_cmp expect output.decrypted
  55}
  56test_language_driver () {
  58        lang=$1
  59        test_expect_success "diff driver '$lang'" '
  60                cp "$TEST_DIRECTORY/t4034/'"$lang"'/pre" \
  61                        "$TEST_DIRECTORY/t4034/'"$lang"'/post" \
  62                        "$TEST_DIRECTORY/t4034/'"$lang"'/expect" . &&
  63                echo "* diff='"$lang"'" >.gitattributes &&
  64                word_diff --color-words
  65        '
  66}
  67test_expect_success setup '
  69        git config diff.color.old red &&
  70        git config diff.color.new green &&
  71        git config diff.color.func magenta
  72'
  73test_expect_success 'set up pre and post with runs of whitespace' '
  75        cp pre.simple pre &&
  76        cp post.simple post
  77'
  78test_expect_success 'word diff with runs of whitespace' '
  80        cat >expect <<-\EOF &&
  81                <BOLD>diff --git a/pre b/post<RESET>
  82                <BOLD>index 330b04f..5ed8eff 100644<RESET>
  83                <BOLD>--- a/pre<RESET>
  84                <BOLD>+++ b/post<RESET>
  85                <CYAN>@@ -1,3 +1,7 @@<RESET>
  86                <RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET>
  87                a = b + c<RESET>
  89                <GREEN>aa = a<RESET>
  91                <GREEN>aeff = aeff * ( aaa )<RESET>
  93        EOF
  94        word_diff --color-words &&
  95        word_diff --word-diff=color &&
  96        word_diff --color --word-diff=color
  97'
  98test_expect_success '--word-diff=porcelain' '
 100        sed 's/#.*$//' >expect <<-\EOF &&
 101                diff --git a/pre b/post
 102                index 330b04f..5ed8eff 100644
 103                --- a/pre
 104                +++ b/post
 105                @@ -1,3 +1,7 @@
 106                -h(4)
 107                +h(4),hh[44]
 108                ~
 109                 # significant space
 110                ~
 111                 a = b + c
 112                ~
 113                ~
 114                +aa = a
 115                ~
 116                ~
 117                +aeff = aeff * ( aaa )
 118                ~
 119        EOF
 120        word_diff --word-diff=porcelain
 121'
 122test_expect_success '--word-diff=plain' '
 124        cat >expect <<-\EOF &&
 125                diff --git a/pre b/post
 126                index 330b04f..5ed8eff 100644
 127                --- a/pre
 128                +++ b/post
 129                @@ -1,3 +1,7 @@
 130                [-h(4)-]{+h(4),hh[44]+}
 131                a = b + c
 133                {+aa = a+}
 135                {+aeff = aeff * ( aaa )+}
 137        EOF
 138        word_diff --word-diff=plain &&
 139        word_diff --word-diff=plain --no-color
 140'
 141test_expect_success '--word-diff=plain --color' '
 143        cat >expect <<-\EOF &&
 144                <BOLD>diff --git a/pre b/post<RESET>
 145                <BOLD>index 330b04f..5ed8eff 100644<RESET>
 146                <BOLD>--- a/pre<RESET>
 147                <BOLD>+++ b/post<RESET>
 148                <CYAN>@@ -1,3 +1,7 @@<RESET>
 149                <RED>[-h(4)-]<RESET><GREEN>{+h(4),hh[44]+}<RESET>
 150                a = b + c<RESET>
 152                <GREEN>{+aa = a+}<RESET>
 154                <GREEN>{+aeff = aeff * ( aaa )+}<RESET>
 156        EOF
 157        word_diff --word-diff=plain --color
 158'
 159test_expect_success 'word diff without context' '
 161        cat >expect <<-\EOF &&
 162                <BOLD>diff --git a/pre b/post<RESET>
 163                <BOLD>index 330b04f..5ed8eff 100644<RESET>
 164                <BOLD>--- a/pre<RESET>
 165                <BOLD>+++ b/post<RESET>
 166                <CYAN>@@ -1 +1 @@<RESET>
 167                <RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET>
 168                <CYAN>@@ -3,0 +4,4 @@<RESET> <RESET><MAGENTA>a = b + c<RESET>
 169                <GREEN>aa = a<RESET>
 171                <GREEN>aeff = aeff * ( aaa )<RESET>
 173        EOF
 174        word_diff --color-words --unified=0
 175'
 176test_expect_success 'word diff with a regular expression' '
 178        cp expect.letter-runs-are-words expect &&
 179        word_diff --color-words="[a-z]+"
 180'
 181test_expect_success 'set up a diff driver' '
 183        git config diff.testdriver.wordRegex "[^[:space:]]" &&
 184        cat <<-\EOF >.gitattributes
 185                pre diff=testdriver
 186                post diff=testdriver
 187        EOF
 188'
 189test_expect_success 'option overrides .gitattributes' '
 191        cp expect.letter-runs-are-words expect &&
 192        word_diff --color-words="[a-z]+"
 193'
 194test_expect_success 'use regex supplied by driver' '
 196        cp expect.non-whitespace-is-word expect &&
 197        word_diff --color-words
 198'
 199test_expect_success 'set up diff.wordRegex option' '
 201        git config diff.wordRegex "[[:alnum:]]+"
 202'
 203test_expect_success 'command-line overrides config' '
 205        cp expect.letter-runs-are-words expect &&
 206        word_diff --color-words="[a-z]+"
 207'
 208test_expect_success 'command-line overrides config: --word-diff-regex' '
 210        cat >expect <<-\EOF &&
 211                <BOLD>diff --git a/pre b/post<RESET>
 212                <BOLD>index 330b04f..5ed8eff 100644<RESET>
 213                <BOLD>--- a/pre<RESET>
 214                <BOLD>+++ b/post<RESET>
 215                <CYAN>@@ -1,3 +1,7 @@<RESET>
 216                h(4),<GREEN>{+hh+}<RESET>[44]
 217                a = b + c<RESET>
 219                <GREEN>{+aa = a+}<RESET>
 221                <GREEN>{+aeff = aeff * ( aaa+}<RESET> )
 223        EOF
 224        word_diff --color --word-diff-regex="[a-z]+"
 225'
 226test_expect_success '.gitattributes override config' '
 228        cp expect.non-whitespace-is-word expect &&
 229        word_diff --color-words
 230'
 231test_expect_success 'setup: remove diff driver regex' '
 233        test_unconfig diff.testdriver.wordRegex
 234'
 235test_expect_success 'use configured regex' '
 237        cat >expect <<-\EOF &&
 238                <BOLD>diff --git a/pre b/post<RESET>
 239                <BOLD>index 330b04f..5ed8eff 100644<RESET>
 240                <BOLD>--- a/pre<RESET>
 241                <BOLD>+++ b/post<RESET>
 242                <CYAN>@@ -1,3 +1,7 @@<RESET>
 243                h(4),<GREEN>hh[44<RESET>]
 244                a = b + c<RESET>
 246                <GREEN>aa = a<RESET>
 248                <GREEN>aeff = aeff * ( aaa<RESET> )
 250        EOF
 251        word_diff --color-words
 252'
 253test_expect_success 'test parsing words for newline' '
 255        echo "aaa (aaa)" >pre &&
 256        echo "aaa (aaa) aaa" >post &&
 257        cat >expect <<-\EOF &&
 258                <BOLD>diff --git a/pre b/post<RESET>
 259                <BOLD>index c29453b..be22f37 100644<RESET>
 260                <BOLD>--- a/pre<RESET>
 261                <BOLD>+++ b/post<RESET>
 262                <CYAN>@@ -1 +1 @@<RESET>
 263                aaa (aaa) <GREEN>aaa<RESET>
 264        EOF
 265        word_diff --color-words="a+"
 266'
 267test_expect_success 'test when words are only removed at the end' '
 269        echo "(:" >pre &&
 270        echo "(" >post &&
 271        cat >expect <<-\EOF &&
 272                <BOLD>diff --git a/pre b/post<RESET>
 273                <BOLD>index 289cb9d..2d06f37 100644<RESET>
 274                <BOLD>--- a/pre<RESET>
 275                <BOLD>+++ b/post<RESET>
 276                <CYAN>@@ -1 +1 @@<RESET>
 277                (<RED>:<RESET>
 278        EOF
 279        word_diff --color-words=.
 280'
 281test_expect_success '--word-diff=none' '
 283        echo "(:" >pre &&
 284        echo "(" >post &&
 285        cat >expect <<-\EOF &&
 286                diff --git a/pre b/post
 287                index 289cb9d..2d06f37 100644
 288                --- a/pre
 289                +++ b/post
 290                @@ -1 +1 @@
 291                -(:
 292                +(
 293        EOF
 294        word_diff --word-diff=plain --word-diff=none
 295'
 296test_expect_success 'unset default driver' '
 298        test_unconfig diff.wordregex
 299'
 300test_language_driver ada
 302test_language_driver bibtex
 303test_language_driver cpp
 304test_language_driver csharp
 305test_language_driver fortran
 306test_language_driver html
 307test_language_driver java
 308test_language_driver matlab
 309test_language_driver objc
 310test_language_driver pascal
 311test_language_driver perl
 312test_language_driver php
 313test_language_driver python
 314test_language_driver ruby
 315test_language_driver tex
 316test_expect_success 'word-diff with diff.sbe' '
 318        cat >expect <<-\EOF &&
 319        diff --git a/pre b/post
 320        index a1a53b5..bc8fe6d 100644
 321        --- a/pre
 322        +++ b/post
 323        @@ -1,3 +1,3 @@
 324        a
 325        [-b-]{+c+}
 327        EOF
 328        cat >pre <<-\EOF &&
 329        a
 330        b
 332        EOF
 333        cat >post <<-\EOF &&
 334        a
 335        c
 337        EOF
 338        test_config diff.suppress-blank-empty true &&
 339        word_diff --word-diff=plain
 340'
 341test_expect_success 'word-diff with no newline at EOF' '
 343        cat >expect <<-\EOF &&
 344        diff --git a/pre b/post
 345        index 7bf316e..3dd0303 100644
 346        --- a/pre
 347        +++ b/post
 348        @@ -1 +1 @@
 349        a a [-a-]{+ab+} a a
 350        EOF
 351        printf "%s" "a a a a a" >pre &&
 352        printf "%s" "a a ab a a" >post &&
 353        word_diff --word-diff=plain
 354'
 355test_expect_success 'setup history with two files' '
 357        echo "a b; c" >a.tex &&
 358        echo "a b; c" >z.txt &&
 359        git add a.tex z.txt &&
 360        git commit -minitial &&
 361        # modify both
 363        echo "a bx; c" >a.tex &&
 364        echo "a bx; c" >z.txt &&
 365        git commit -mmodified -a
 366'
 367test_expect_success 'wordRegex for the first file does not apply to the second' '
 369        echo "*.tex diff=tex" >.gitattributes &&
 370        test_config diff.tex.wordRegex "[a-z]+|." &&
 371        cat >expect <<-\EOF &&
 372                diff --git a/a.tex b/a.tex
 373                --- a/a.tex
 374                +++ b/a.tex
 375                @@ -1 +1 @@
 376                a [-b-]{+bx+}; c
 377                diff --git a/z.txt b/z.txt
 378                --- a/z.txt
 379                +++ b/z.txt
 380                @@ -1 +1 @@
 381                a [-b;-]{+bx;+} c
 382        EOF
 383        git diff --word-diff HEAD~ >actual &&
 384        compare_diff_patch expect actual
 385'
 386test_done