Sync with Git 2.24.1
[git] / t / t4034-diff-words.sh
1 #!/bin/sh
2
3 test_description='word diff colors'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/diff-lib.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 'set up a diff driver' '
188         git config diff.testdriver.wordRegex "[^[:space:]]" &&
189         cat <<-\EOF >.gitattributes
190                 pre diff=testdriver
191                 post diff=testdriver
192         EOF
193 '
194
195 test_expect_success 'option overrides .gitattributes' '
196         cp expect.letter-runs-are-words expect &&
197         word_diff --color-words="[a-z]+"
198 '
199
200 test_expect_success 'use regex supplied by driver' '
201         cp expect.non-whitespace-is-word expect &&
202         word_diff --color-words
203 '
204
205 test_expect_success 'set up diff.wordRegex option' '
206         git config diff.wordRegex "[[:alnum:]]+"
207 '
208
209 test_expect_success 'command-line overrides config' '
210         cp expect.letter-runs-are-words expect &&
211         word_diff --color-words="[a-z]+"
212 '
213
214 test_expect_success 'command-line overrides config: --word-diff-regex' '
215         cat >expect <<-EOF &&
216                 <BOLD>diff --git a/pre b/post<RESET>
217                 <BOLD>index $pre..$post 100644<RESET>
218                 <BOLD>--- a/pre<RESET>
219                 <BOLD>+++ b/post<RESET>
220                 <CYAN>@@ -1,3 +1,7 @@<RESET>
221                 h(4),<GREEN>{+hh+}<RESET>[44]
222
223                 a = b + c<RESET>
224
225                 <GREEN>{+aa = a+}<RESET>
226
227                 <GREEN>{+aeff = aeff * ( aaa+}<RESET> )
228         EOF
229         word_diff --color --word-diff-regex="[a-z]+"
230 '
231
232 test_expect_success '.gitattributes override config' '
233         cp expect.non-whitespace-is-word expect &&
234         word_diff --color-words
235 '
236
237 test_expect_success 'setup: remove diff driver regex' '
238         test_unconfig diff.testdriver.wordRegex
239 '
240
241 test_expect_success 'use configured regex' '
242         cat >expect <<-EOF &&
243                 <BOLD>diff --git a/pre b/post<RESET>
244                 <BOLD>index $pre..$post 100644<RESET>
245                 <BOLD>--- a/pre<RESET>
246                 <BOLD>+++ b/post<RESET>
247                 <CYAN>@@ -1,3 +1,7 @@<RESET>
248                 h(4),<GREEN>hh[44<RESET>]
249
250                 a = b + c<RESET>
251
252                 <GREEN>aa = a<RESET>
253
254                 <GREEN>aeff = aeff * ( aaa<RESET> )
255         EOF
256         word_diff --color-words
257 '
258
259 test_expect_success 'test parsing words for newline' '
260         echo "aaa (aaa)" >pre &&
261         echo "aaa (aaa) aaa" >post &&
262         pre=$(git rev-parse --short $(git hash-object pre)) &&
263         post=$(git rev-parse --short $(git hash-object post)) &&
264         cat >expect <<-EOF &&
265                 <BOLD>diff --git a/pre b/post<RESET>
266                 <BOLD>index $pre..$post 100644<RESET>
267                 <BOLD>--- a/pre<RESET>
268                 <BOLD>+++ b/post<RESET>
269                 <CYAN>@@ -1 +1 @@<RESET>
270                 aaa (aaa) <GREEN>aaa<RESET>
271         EOF
272         word_diff --color-words="a+"
273 '
274
275 test_expect_success 'test when words are only removed at the end' '
276         echo "(:" >pre &&
277         echo "(" >post &&
278         pre=$(git rev-parse --short $(git hash-object pre)) &&
279         post=$(git rev-parse --short $(git hash-object post)) &&
280         cat >expect <<-EOF &&
281                 <BOLD>diff --git a/pre b/post<RESET>
282                 <BOLD>index $pre..$post 100644<RESET>
283                 <BOLD>--- a/pre<RESET>
284                 <BOLD>+++ b/post<RESET>
285                 <CYAN>@@ -1 +1 @@<RESET>
286                 (<RED>:<RESET>
287         EOF
288         word_diff --color-words=.
289 '
290
291 test_expect_success '--word-diff=none' '
292         echo "(:" >pre &&
293         echo "(" >post &&
294         pre=$(git rev-parse --short $(git hash-object pre)) &&
295         post=$(git rev-parse --short $(git hash-object post)) &&
296         cat >expect <<-EOF &&
297                 diff --git a/pre b/post
298                 index $pre..$post 100644
299                 --- a/pre
300                 +++ b/post
301                 @@ -1 +1 @@
302                 -(:
303                 +(
304         EOF
305         word_diff --word-diff=plain --word-diff=none
306 '
307
308 test_expect_success 'unset default driver' '
309         test_unconfig diff.wordregex
310 '
311
312 test_language_driver ada
313 test_language_driver bibtex
314 test_language_driver cpp
315 test_language_driver csharp
316 test_language_driver css
317 test_language_driver dts
318 test_language_driver fortran
319 test_language_driver html
320 test_language_driver java
321 test_language_driver matlab
322 test_language_driver objc
323 test_language_driver pascal
324 test_language_driver perl
325 test_language_driver php
326 test_language_driver python
327 test_language_driver ruby
328 test_language_driver tex
329
330 test_expect_success 'word-diff with diff.sbe' '
331         cat >pre <<-\EOF &&
332         a
333
334         b
335         EOF
336         cat >post <<-\EOF &&
337         a
338
339         c
340         EOF
341         pre=$(git rev-parse --short $(git hash-object pre)) &&
342         post=$(git rev-parse --short $(git hash-object post)) &&
343         cat >expect <<-EOF &&
344         diff --git a/pre b/post
345         index $pre..$post 100644
346         --- a/pre
347         +++ b/post
348         @@ -1,3 +1,3 @@
349         a
350
351         [-b-]{+c+}
352         EOF
353         test_config diff.suppress-blank-empty true &&
354         word_diff --word-diff=plain
355 '
356
357 test_expect_success 'word-diff with no newline at EOF' '
358         printf "%s" "a a a a a" >pre &&
359         printf "%s" "a a ab a a" >post &&
360         pre=$(git rev-parse --short $(git hash-object pre)) &&
361         post=$(git rev-parse --short $(git hash-object post)) &&
362         cat >expect <<-EOF &&
363         diff --git a/pre b/post
364         index $pre..$post 100644
365         --- a/pre
366         +++ b/post
367         @@ -1 +1 @@
368         a a [-a-]{+ab+} a a
369         EOF
370         word_diff --word-diff=plain
371 '
372
373 test_expect_success 'setup history with two files' '
374         echo "a b; c" >a.tex &&
375         echo "a b; c" >z.txt &&
376         git add a.tex z.txt &&
377         git commit -minitial &&
378
379         # modify both
380         echo "a bx; c" >a.tex &&
381         echo "a bx; c" >z.txt &&
382         git commit -mmodified -a
383 '
384
385 test_expect_success 'wordRegex for the first file does not apply to the second' '
386         echo "*.tex diff=tex" >.gitattributes &&
387         test_config diff.tex.wordRegex "[a-z]+|." &&
388         cat >expect <<-\EOF &&
389                 diff --git a/a.tex b/a.tex
390                 --- a/a.tex
391                 +++ b/a.tex
392                 @@ -1 +1 @@
393                 a [-b-]{+bx+}; c
394                 diff --git a/z.txt b/z.txt
395                 --- a/z.txt
396                 +++ b/z.txt
397                 @@ -1 +1 @@
398                 a [-b;-]{+bx;+} c
399         EOF
400         git diff --word-diff HEAD~ >actual &&
401         compare_diff_patch expect actual
402 '
403
404 test_done