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