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