Raw
1 #!/bin/sh
2
3 test_description='Test diff-highlight'
4
5 CURR_DIR=$(pwd)
6 TEST_OUTPUT_DIRECTORY=$(pwd)
7 TEST_DIRECTORY="$CURR_DIR"/../../../t
8 DIFF_HIGHLIGHT="$CURR_DIR"/../diff-highlight
9
10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12 . "$TEST_DIRECTORY"/test-lib.sh
13
14 if ! test_have_prereq PERL
15 then
16 skip_all='skipping diff-highlight tests; perl not available'
17 test_done
18 fi
19
20 # dh_test is a test helper function which takes 3 file names as parameters. The
21 # first 2 files are used to generate diff and commit output, which is then
22 # piped through diff-highlight. The 3rd file should contain the expected output
23 # of diff-highlight (minus the diff/commit header, ie. everything after and
24 # including the first @@ line).
25 dh_test () {
26 a="$1" b="$2" &&
27
28 cat >patch.exp &&
29
30 {
31 cat "$a" >file &&
32 git add file &&
33 git commit -m "Add a file" &&
34
35 cat "$b" >file &&
36 git diff file >diff.raw &&
37 git commit -a -m "Update a file" &&
38 git show >commit.raw
39 } >/dev/null &&
40
41 "$DIFF_HIGHLIGHT" <diff.raw >diff.hi &&
42 test_strip_patch_header <diff.hi | test_decode_color >diff.act &&
43 "$DIFF_HIGHLIGHT" <commit.raw >commit.hi &&
44 test_strip_patch_header <commit.hi | test_decode_color >commit.act &&
45 test_cmp patch.exp diff.act &&
46 test_cmp patch.exp commit.act
47 }
48
49 test_strip_patch_header () {
50 sed -n '/^@@/,$p' $*
51 }
52
53 # dh_test_setup_history generates a contrived graph such that we have at least
54 # 1 nesting (E) and 2 nestings (F).
55 #
56 # A---B master
57 # /
58 # D---E---F branch
59 #
60 # git log --all --graph
61 # * commit
62 # | B
63 # | * commit
64 # | | F
65 # * | commit
66 # | | A
67 # | * commit
68 # |/
69 # | E
70 # * commit
71 # D
72 #
73 dh_test_setup_history () {
74 echo file1 >file &&
75 git add file &&
76 test_tick &&
77 git commit -m "D" &&
78
79 git checkout -b branch &&
80 echo file2 >file &&
81 test_tick &&
82 git commit -a -m "E" &&
83
84 git checkout master &&
85 echo file2 >file &&
86 test_tick &&
87 git commit -a -m "A" &&
88
89 git checkout branch &&
90 echo file3 >file &&
91 test_tick &&
92 git commit -a -m "F" &&
93
94 git checkout master &&
95 echo file3 >file &&
96 test_tick &&
97 git commit -a -m "B"
98 }
99
100 left_trim () {
101 "$PERL_PATH" -pe 's/^\s+//'
102 }
103
104 trim_graph () {
105 # graphs start with * or |
106 # followed by a space or / or \
107 "$PERL_PATH" -pe 's@^((\*|\|)( |/|\\))+@@'
108 }
109
110 test_expect_success 'diff-highlight highlights the beginning of a line' '
111 cat >a <<-\EOF &&
112 aaa
113 bbb
114 ccc
115 EOF
116
117 cat >b <<-\EOF &&
118 aaa
119 0bb
120 ccc
121 EOF
122
123 dh_test a b <<-EOF
124 @@ -1,3 +1,3 @@
125 aaa
126 -<REVERSE>b<NOREVERSE>bb
127 +<REVERSE>0<NOREVERSE>bb
128 ccc
129 EOF
130 '
131
132 test_expect_success 'diff-highlight highlights the end of a line' '
133 cat >a <<-\EOF &&
134 aaa
135 bbb
136 ccc
137 EOF
138
139 cat >b <<-\EOF &&
140 aaa
141 bb0
142 ccc
143 EOF
144
145 dh_test a b <<-EOF
146 @@ -1,3 +1,3 @@
147 aaa
148 -bb<REVERSE>b<NOREVERSE>
149 +bb<REVERSE>0<NOREVERSE>
150 ccc
151 EOF
152 '
153
154 test_expect_success 'diff-highlight highlights the middle of a line' '
155 cat >a <<-\EOF &&
156 aaa
157 bbb
158 ccc
159 EOF
160
161 cat >b <<-\EOF &&
162 aaa
163 b0b
164 ccc
165 EOF
166
167 dh_test a b <<-EOF
168 @@ -1,3 +1,3 @@
169 aaa
170 -b<REVERSE>b<NOREVERSE>b
171 +b<REVERSE>0<NOREVERSE>b
172 ccc
173 EOF
174 '
175
176 test_expect_success 'diff-highlight does not highlight whole line' '
177 cat >a <<-\EOF &&
178 aaa
179 bbb
180 ccc
181 EOF
182
183 cat >b <<-\EOF &&
184 aaa
185 000
186 ccc
187 EOF
188
189 dh_test a b <<-EOF
190 @@ -1,3 +1,3 @@
191 aaa
192 -bbb
193 +000
194 ccc
195 EOF
196 '
197
198 test_expect_failure 'diff-highlight highlights mismatched hunk size' '
199 cat >a <<-\EOF &&
200 aaa
201 bbb
202 EOF
203
204 cat >b <<-\EOF &&
205 aaa
206 b0b
207 ccc
208 EOF
209
210 dh_test a b <<-EOF
211 @@ -1,3 +1,3 @@
212 aaa
213 -b<REVERSE>b<NOREVERSE>b
214 +b<REVERSE>0<NOREVERSE>b
215 +ccc
216 EOF
217 '
218
219 # These two code points share the same leading byte in UTF-8 representation;
220 # a naive byte-wise diff would highlight only the second byte.
221 #
222 # - U+00f3 ("o" with acute)
223 o_accent=$(printf '\303\263')
224 # - U+00f8 ("o" with stroke)
225 o_stroke=$(printf '\303\270')
226
227 test_expect_success 'diff-highlight treats multibyte utf-8 as a unit' '
228 echo "unic${o_accent}de" >a &&
229 echo "unic${o_stroke}de" >b &&
230 dh_test a b <<-EOF
231 @@ -1 +1 @@
232 -unic<REVERSE>${o_accent}<NOREVERSE>de
233 +unic<REVERSE>${o_stroke}<NOREVERSE>de
234 EOF
235 '
236
237 # Unlike the UTF-8 above, these are combining code points which are meant
238 # to modify the character preceding them:
239 #
240 # - U+0301 (combining acute accent)
241 combine_accent=$(printf '\314\201')
242 # - U+0302 (combining circumflex)
243 combine_circum=$(printf '\314\202')
244
245 test_expect_failure 'diff-highlight treats combining code points as a unit' '
246 echo "unico${combine_accent}de" >a &&
247 echo "unico${combine_circum}de" >b &&
248 dh_test a b <<-EOF
249 @@ -1 +1 @@
250 -unic<REVERSE>o${combine_accent}<NOREVERSE>de
251 +unic<REVERSE>o${combine_circum}<NOREVERSE>de
252 EOF
253 '
254
255 test_expect_success 'diff-highlight works with the --graph option' '
256 dh_test_setup_history &&
257
258 # date-order so that the commits are interleaved for both
259 # trim graph elements so we can do a diff
260 # trim leading space because our trim_graph is not perfect
261 git log --branches -p --date-order |
262 "$DIFF_HIGHLIGHT" | left_trim >graph.exp &&
263 git log --branches -p --date-order --graph |
264 "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph.act &&
265 test_cmp graph.exp graph.act
266 '
267
268 # Just reuse the previous graph test, but with --color. Our trimming
269 # doesn't know about color, so just sanity check that something got
270 # highlighted.
271 test_expect_success 'diff-highlight works with color graph' '
272 git log --branches -p --date-order --graph --color |
273 "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph &&
274 grep "\[7m" graph
275 '
276
277 # Most combined diffs won't meet diff-highlight's line-number filter. So we
278 # create one here where one side drops a line and the other modifies it. That
279 # should result in a diff like:
280 #
281 # - modified content
282 # ++resolved content
283 #
284 # which naively looks like one side added "+resolved".
285 test_expect_success 'diff-highlight ignores combined diffs' '
286 echo "content" >file &&
287 git add file &&
288 git commit -m base &&
289
290 >file &&
291 git commit -am master &&
292
293 git checkout -b other HEAD^ &&
294 echo "modified content" >file &&
295 git commit -am other &&
296
297 test_must_fail git merge master &&
298 echo "resolved content" >file &&
299 git commit -am resolved &&
300
301 cat >expect <<-\EOF &&
302 --- a/file
303 +++ b/file
304 @@@ -1,1 -1,0 +1,1 @@@
305 - modified content
306 ++resolved content
307 EOF
308
309 git show -c | "$DIFF_HIGHLIGHT" >actual.raw &&
310 sed -n "/^---/,\$p" <actual.raw >actual &&
311 test_cmp expect actual
312 '
313
314 test_expect_success 'diff-highlight handles --graph with leading dash' '
315 cat >file <<-\EOF &&
316 before
317 the old line
318 -leading dash
319 EOF
320 git add file &&
321 git commit -m before &&
322
323 sed s/old/new/ <file >file.tmp &&
324 mv file.tmp file &&
325 git add file &&
326 git commit -m after &&
327
328 cat >expect <<-EOF &&
329 --- a/file
330 +++ b/file
331 @@ -1,3 +1,3 @@
332 before
333 -the <REVERSE>old<NOREVERSE> line
334 +the <REVERSE>new<NOREVERSE> line
335 -leading dash
336 EOF
337 git log --graph -p -1 | "$DIFF_HIGHLIGHT" >actual.raw &&
338 trim_graph <actual.raw | sed -n "/^---/,\$p" | test_decode_color >actual &&
339 test_cmp expect actual
340 '
341
342 test_expect_success 'highlight diff that removes final newline' '
343 printf "content\n" >a &&
344 printf "content" >b &&
345 dh_test a b <<-\EOF
346 @@ -1 +1 @@
347 -content
348 +content
349 \ No newline at end of file
350 EOF
351 '
352
353 test_expect_success 'configure set/reset colors' '
354 test_config color.diff-highlight.oldhighlight bold &&
355 test_config color.diff-highlight.oldreset nobold &&
356 test_config color.diff-highlight.newhighlight italic &&
357 test_config color.diff-highlight.newreset noitalic &&
358 echo "prefix a suffix" >a &&
359 echo "prefix b suffix" >b &&
360 dh_test a b <<-\EOF
361 @@ -1 +1 @@
362 -prefix <BOLD>a<NORMAL_INTENSITY> suffix
363 +prefix <ITALIC>b<NOITALIC> suffix
364 EOF
365 '
366
367 test_expect_success 'configure normal/highlight colors' '
368 test_config color.diff-highlight.oldnormal red &&
369 test_config color.diff-highlight.oldhighlight magenta &&
370 test_config color.diff-highlight.newnormal green &&
371 test_config color.diff-highlight.newhighlight yellow &&
372 echo "prefix a suffix" >a &&
373 echo "prefix b suffix" >b &&
374 dh_test a b <<-\EOF
375 @@ -1 +1 @@
376 <RED>-prefix <RESET><MAGENTA>a<RESET><RED> suffix<RESET>
377 <GREEN>+prefix <RESET><YELLOW>b<RESET><GREEN> suffix<RESET>
378 EOF
379 '
380
381 test_done