Raw
1 #!/bin/sh
2
3 test_description='git blame ignore fuzzy heuristic'
4
5 . ./test-lib.sh
6
7 pick_author='s/^[0-9a-f^]* *(\([^ ]*\) .*/\1/'
8
9 # Each test is composed of 4 variables:
10 # titleN - the test name
11 # aN - the initial content
12 # bN - the final content
13 # expectedN - the line numbers from aN that we expect git blame
14 # on bN to identify, or "Final" if bN itself should
15 # be identified as the origin of that line.
16
17 # We start at test 2 because setup will show as test 1
18 title2="Regression test for partially overlapping search ranges"
19 cat <<EOF >a2
20 1
21 2
22 3
23 abcdef
24 5
25 6
26 7
27 ijkl
28 9
29 10
30 11
31 pqrs
32 13
33 14
34 15
35 wxyz
36 17
37 18
38 19
39 EOF
40 cat <<EOF >b2
41 abcde
42 ijk
43 pqr
44 wxy
45 EOF
46 cat <<EOF >expected2
47 4
48 8
49 12
50 16
51 EOF
52
53 title3="Combine 3 lines into 2"
54 cat <<EOF >a3
55 if ((maxgrow==0) ||
56 ( single_line_field && (field->dcols < maxgrow)) ||
57 (!single_line_field && (field->drows < maxgrow)))
58 EOF
59 cat <<EOF >b3
60 if ((maxgrow == 0) || (single_line_field && (field->dcols < maxgrow)) ||
61 (!single_line_field && (field->drows < maxgrow))) {
62 EOF
63 cat <<EOF >expected3
64 2
65 3
66 EOF
67
68 title4="Add curly brackets"
69 cat <<EOF >a4
70 if (rows) *rows = field->rows;
71 if (cols) *cols = field->cols;
72 if (frow) *frow = field->frow;
73 if (fcol) *fcol = field->fcol;
74 EOF
75 cat <<EOF >b4
76 if (rows) {
77 *rows = field->rows;
78 }
79 if (cols) {
80 *cols = field->cols;
81 }
82 if (frow) {
83 *frow = field->frow;
84 }
85 if (fcol) {
86 *fcol = field->fcol;
87 }
88 EOF
89 cat <<EOF >expected4
90 1
91 1
92 Final
93 2
94 2
95 Final
96 3
97 3
98 Final
99 4
100 4
101 Final
102 EOF
103
104
105 title5="Combine many lines and change case"
106 cat <<EOF >a5
107 for(row=0,pBuffer=field->buf;
108 row<height;
109 row++,pBuffer+=width )
110 {
111 if ((len = (int)( After_End_Of_Data( pBuffer, width ) - pBuffer )) > 0)
112 {
113 wmove( win, row, 0 );
114 waddnstr( win, pBuffer, len );
115 EOF
116 cat <<EOF >b5
117 for (Row = 0, PBuffer = field->buf; Row < Height; Row++, PBuffer += Width) {
118 if ((Len = (int)(afterEndOfData(PBuffer, Width) - PBuffer)) > 0) {
119 wmove(win, Row, 0);
120 waddnstr(win, PBuffer, Len);
121 EOF
122 cat <<EOF >expected5
123 1
124 5
125 7
126 8
127 EOF
128
129 title6="Rename and combine lines"
130 cat <<EOF >a6
131 bool need_visual_update = ((form != (FORM *)0) &&
132 (form->status & _POSTED) &&
133 (form->current==field));
134
135 if (need_visual_update)
136 Synchronize_Buffer(form);
137
138 if (single_line_field)
139 {
140 growth = field->cols * amount;
141 if (field->maxgrow)
142 growth = Minimum(field->maxgrow - field->dcols,growth);
143 field->dcols += growth;
144 if (field->dcols == field->maxgrow)
145 EOF
146 cat <<EOF >b6
147 bool NeedVisualUpdate = ((Form != (FORM *)0) && (Form->status & _POSTED) &&
148 (Form->current == field));
149
150 if (NeedVisualUpdate) {
151 synchronizeBuffer(Form);
152 }
153
154 if (SingleLineField) {
155 Growth = field->cols * amount;
156 if (field->maxgrow) {
157 Growth = Minimum(field->maxgrow - field->dcols, Growth);
158 }
159 field->dcols += Growth;
160 if (field->dcols == field->maxgrow) {
161 EOF
162 cat <<EOF >expected6
163 1
164 3
165 4
166 5
167 6
168 Final
169 7
170 8
171 10
172 11
173 12
174 Final
175 13
176 14
177 EOF
178
179 # Both lines match identically so position must be used to tie-break.
180 title7="Same line twice"
181 cat <<EOF >a7
182 abc
183 abc
184 EOF
185 cat <<EOF >b7
186 abcd
187 abcd
188 EOF
189 cat <<EOF >expected7
190 1
191 2
192 EOF
193
194 title8="Enforce line order"
195 cat <<EOF >a8
196 abcdef
197 ghijkl
198 ab
199 EOF
200 cat <<EOF >b8
201 ghijk
202 abcd
203 EOF
204 cat <<EOF >expected8
205 2
206 3
207 EOF
208
209 title9="Expand lines and rename variables"
210 cat <<EOF >a9
211 int myFunction(int ArgumentOne, Thing *ArgTwo, Blah XuglyBug) {
212 Squiggle FabulousResult = squargle(ArgumentOne, *ArgTwo,
213 XuglyBug) + EwwwGlobalWithAReallyLongNameYepTooLong;
214 return FabulousResult * 42;
215 }
216 EOF
217 cat <<EOF >b9
218 int myFunction(int argument_one, Thing *arg_asdfgh,
219 Blah xugly_bug) {
220 Squiggle fabulous_result = squargle(argument_one,
221 *arg_asdfgh, xugly_bug)
222 + g_ewww_global_with_a_really_long_name_yep_too_long;
223 return fabulous_result * 42;
224 }
225 EOF
226 cat <<EOF >expected9
227 1
228 1
229 2
230 3
231 3
232 4
233 5
234 EOF
235
236 title10="Two close matches versus one less close match"
237 cat <<EOF >a10
238 abcdef
239 abcdef
240 ghijkl
241 EOF
242 cat <<EOF >b10
243 gh
244 abcdefx
245 EOF
246 cat <<EOF >expected10
247 Final
248 2
249 EOF
250
251 # The first line of b matches best with the last line of a, but the overall
252 # match is better if we match it with the first line of a.
253 title11="Piggy in the middle"
254 cat <<EOF >a11
255 abcdefg
256 ijklmn
257 abcdefgh
258 EOF
259 cat <<EOF >b11
260 abcdefghx
261 ijklm
262 EOF
263 cat <<EOF >expected11
264 1
265 2
266 EOF
267
268 title12="No trailing newline"
269 printf "abc\ndef" >a12
270 printf "abx\nstu" >b12
271 cat <<EOF >expected12
272 1
273 Final
274 EOF
275
276 title13="Reorder includes"
277 cat <<EOF >a13
278 #include "c.h"
279 #include "b.h"
280 #include "a.h"
281 #include "e.h"
282 #include "d.h"
283 EOF
284 cat <<EOF >b13
285 #include "a.h"
286 #include "b.h"
287 #include "c.h"
288 #include "d.h"
289 #include "e.h"
290 EOF
291 cat <<EOF >expected13
292 3
293 2
294 1
295 5
296 4
297 EOF
298
299 last_test=13
300
301 test_expect_success setup '
302 for i in $(test_seq 2 $last_test)
303 do
304 # Append each line in a separate commit to make it easy to
305 # check which original line the blame output relates to.
306
307 line_count=0 &&
308 while IFS= read line
309 do
310 line_count=$((line_count+1)) &&
311 echo "$line" >>"$i" &&
312 git add "$i" &&
313 test_tick &&
314 GIT_AUTHOR_NAME="$line_count" git commit -m "$line_count" || return 1
315 done <"a$i"
316 done &&
317
318 for i in $(test_seq 2 $last_test)
319 do
320 # Overwrite the files with the final content.
321 cp b$i $i &&
322 git add $i || return 1
323 done &&
324 test_tick &&
325
326 # Commit the final content all at once so it can all be
327 # referred to with the same commit ID.
328 GIT_AUTHOR_NAME=Final git commit -m Final &&
329
330 IGNOREME=$(git rev-parse HEAD)
331 '
332
333 for i in $(test_seq 2 $last_test); do
334 eval title="\$title$i"
335 test_expect_success "$title" \
336 "git blame -M9 --ignore-rev $IGNOREME $i >output &&
337 sed -e \"$pick_author\" output >actual &&
338 test_cmp expected$i actual"
339 done
340
341 # This invoked a null pointer dereference when the chunk callback was called
342 # with a zero length parent chunk and there were no more suspects.
343 test_expect_success 'Diff chunks with no suspects' '
344 test_write_lines xy1 A B C xy1 >file &&
345 git add file &&
346 test_tick &&
347 GIT_AUTHOR_NAME=1 git commit -m 1 &&
348
349 test_write_lines xy2 A B xy2 C xy2 >file &&
350 git add file &&
351 test_tick &&
352 GIT_AUTHOR_NAME=2 git commit -m 2 &&
353 REV_2=$(git rev-parse HEAD) &&
354
355 test_write_lines xy3 A >file &&
356 git add file &&
357 test_tick &&
358 GIT_AUTHOR_NAME=3 git commit -m 3 &&
359 REV_3=$(git rev-parse HEAD) &&
360
361 test_write_lines 1 1 >expected &&
362
363 git blame --ignore-rev $REV_2 --ignore-rev $REV_3 file >output &&
364 sed -e "$pick_author" output >actual &&
365
366 test_cmp expected actual
367 '
368
369 test_expect_success 'position matching' '
370 test_write_lines abc def >file2 &&
371 git add file2 &&
372 test_tick &&
373 GIT_AUTHOR_NAME=1 git commit -m 1 &&
374
375 test_write_lines abc def abc def >file2 &&
376 git add file2 &&
377 test_tick &&
378 GIT_AUTHOR_NAME=2 git commit -m 2 &&
379
380 test_write_lines abcx defx abcx defx >file2 &&
381 git add file2 &&
382 test_tick &&
383 GIT_AUTHOR_NAME=3 git commit -m 3 &&
384 REV_3=$(git rev-parse HEAD) &&
385
386 test_write_lines abcy defy abcx defx >file2 &&
387 git add file2 &&
388 test_tick &&
389 GIT_AUTHOR_NAME=4 git commit -m 4 &&
390 REV_4=$(git rev-parse HEAD) &&
391
392 test_write_lines 1 1 2 2 >expected &&
393
394 git blame --ignore-rev $REV_3 --ignore-rev $REV_4 file2 >output &&
395 sed -e "$pick_author" output >actual &&
396
397 test_cmp expected actual
398 '
399
400 # This fails if each blame entry is processed independently instead of
401 # processing each diff change in full.
402 test_expect_success 'preserve order' '
403 test_write_lines bcde >file3 &&
404 git add file3 &&
405 test_tick &&
406 GIT_AUTHOR_NAME=1 git commit -m 1 &&
407
408 test_write_lines bcde fghij >file3 &&
409 git add file3 &&
410 test_tick &&
411 GIT_AUTHOR_NAME=2 git commit -m 2 &&
412
413 test_write_lines bcde fghij abcd >file3 &&
414 git add file3 &&
415 test_tick &&
416 GIT_AUTHOR_NAME=3 git commit -m 3 &&
417
418 test_write_lines abcdx fghijx bcdex >file3 &&
419 git add file3 &&
420 test_tick &&
421 GIT_AUTHOR_NAME=4 git commit -m 4 &&
422 REV_4=$(git rev-parse HEAD) &&
423
424 test_write_lines abcdx fghijy bcdex >file3 &&
425 git add file3 &&
426 test_tick &&
427 GIT_AUTHOR_NAME=5 git commit -m 5 &&
428 REV_5=$(git rev-parse HEAD) &&
429
430 test_write_lines 1 2 3 >expected &&
431
432 git blame --ignore-rev $REV_4 --ignore-rev $REV_5 file3 >output &&
433 sed -e "$pick_author" output >actual &&
434
435 test_cmp expected actual
436 '
437
438 test_done