| #!/bin/sh |
| |
| test_description='git blame ignore fuzzy heuristic' |
| . ./test-lib.sh |
| |
| pick_author='s/^[0-9a-f^]* *(\([^ ]*\) .*/\1/' |
| |
| # Each test is composed of 4 variables: |
| # titleN - the test name |
| # aN - the initial content |
| # bN - the final content |
| # expectedN - the line numbers from aN that we expect git blame |
| # on bN to identify, or "Final" if bN itself should |
| # be identified as the origin of that line. |
| |
| # We start at test 2 because setup will show as test 1 |
| title2="Regression test for partially overlapping search ranges" |
| cat <<EOF >a2 |
| 1 |
| 2 |
| 3 |
| abcdef |
| 5 |
| 6 |
| 7 |
| ijkl |
| 9 |
| 10 |
| 11 |
| pqrs |
| 13 |
| 14 |
| 15 |
| wxyz |
| 17 |
| 18 |
| 19 |
| EOF |
| cat <<EOF >b2 |
| abcde |
| ijk |
| pqr |
| wxy |
| EOF |
| cat <<EOF >expected2 |
| 4 |
| 8 |
| 12 |
| 16 |
| EOF |
| |
| title3="Combine 3 lines into 2" |
| cat <<EOF >a3 |
| if ((maxgrow==0) || |
| ( single_line_field && (field->dcols < maxgrow)) || |
| (!single_line_field && (field->drows < maxgrow))) |
| EOF |
| cat <<EOF >b3 |
| if ((maxgrow == 0) || (single_line_field && (field->dcols < maxgrow)) || |
| (!single_line_field && (field->drows < maxgrow))) { |
| EOF |
| cat <<EOF >expected3 |
| 2 |
| 3 |
| EOF |
| |
| title4="Add curly brackets" |
| cat <<EOF >a4 |
| if (rows) *rows = field->rows; |
| if (cols) *cols = field->cols; |
| if (frow) *frow = field->frow; |
| if (fcol) *fcol = field->fcol; |
| EOF |
| cat <<EOF >b4 |
| if (rows) { |
| *rows = field->rows; |
| } |
| if (cols) { |
| *cols = field->cols; |
| } |
| if (frow) { |
| *frow = field->frow; |
| } |
| if (fcol) { |
| *fcol = field->fcol; |
| } |
| EOF |
| cat <<EOF >expected4 |
| 1 |
| 1 |
| Final |
| 2 |
| 2 |
| Final |
| 3 |
| 3 |
| Final |
| 4 |
| 4 |
| Final |
| EOF |
| |
| |
| title5="Combine many lines and change case" |
| cat <<EOF >a5 |
| for(row=0,pBuffer=field->buf; |
| row<height; |
| row++,pBuffer+=width ) |
| { |
| if ((len = (int)( After_End_Of_Data( pBuffer, width ) - pBuffer )) > 0) |
| { |
| wmove( win, row, 0 ); |
| waddnstr( win, pBuffer, len ); |
| EOF |
| cat <<EOF >b5 |
| for (Row = 0, PBuffer = field->buf; Row < Height; Row++, PBuffer += Width) { |
| if ((Len = (int)(afterEndOfData(PBuffer, Width) - PBuffer)) > 0) { |
| wmove(win, Row, 0); |
| waddnstr(win, PBuffer, Len); |
| EOF |
| cat <<EOF >expected5 |
| 1 |
| 5 |
| 7 |
| 8 |
| EOF |
| |
| title6="Rename and combine lines" |
| cat <<EOF >a6 |
| bool need_visual_update = ((form != (FORM *)0) && |
| (form->status & _POSTED) && |
| (form->current==field)); |
| |
| if (need_visual_update) |
| Synchronize_Buffer(form); |
| |
| if (single_line_field) |
| { |
| growth = field->cols * amount; |
| if (field->maxgrow) |
| growth = Minimum(field->maxgrow - field->dcols,growth); |
| field->dcols += growth; |
| if (field->dcols == field->maxgrow) |
| EOF |
| cat <<EOF >b6 |
| bool NeedVisualUpdate = ((Form != (FORM *)0) && (Form->status & _POSTED) && |
| (Form->current == field)); |
| |
| if (NeedVisualUpdate) { |
| synchronizeBuffer(Form); |
| } |
| |
| if (SingleLineField) { |
| Growth = field->cols * amount; |
| if (field->maxgrow) { |
| Growth = Minimum(field->maxgrow - field->dcols, Growth); |
| } |
| field->dcols += Growth; |
| if (field->dcols == field->maxgrow) { |
| EOF |
| cat <<EOF >expected6 |
| 1 |
| 3 |
| 4 |
| 5 |
| 6 |
| Final |
| 7 |
| 8 |
| 10 |
| 11 |
| 12 |
| Final |
| 13 |
| 14 |
| EOF |
| |
| # Both lines match identically so position must be used to tie-break. |
| title7="Same line twice" |
| cat <<EOF >a7 |
| abc |
| abc |
| EOF |
| cat <<EOF >b7 |
| abcd |
| abcd |
| EOF |
| cat <<EOF >expected7 |
| 1 |
| 2 |
| EOF |
| |
| title8="Enforce line order" |
| cat <<EOF >a8 |
| abcdef |
| ghijkl |
| ab |
| EOF |
| cat <<EOF >b8 |
| ghijk |
| abcd |
| EOF |
| cat <<EOF >expected8 |
| 2 |
| 3 |
| EOF |
| |
| title9="Expand lines and rename variables" |
| cat <<EOF >a9 |
| int myFunction(int ArgumentOne, Thing *ArgTwo, Blah XuglyBug) { |
| Squiggle FabulousResult = squargle(ArgumentOne, *ArgTwo, |
| XuglyBug) + EwwwGlobalWithAReallyLongNameYepTooLong; |
| return FabulousResult * 42; |
| } |
| EOF |
| cat <<EOF >b9 |
| int myFunction(int argument_one, Thing *arg_asdfgh, |
| Blah xugly_bug) { |
| Squiggle fabulous_result = squargle(argument_one, |
| *arg_asdfgh, xugly_bug) |
| + g_ewww_global_with_a_really_long_name_yep_too_long; |
| return fabulous_result * 42; |
| } |
| EOF |
| cat <<EOF >expected9 |
| 1 |
| 1 |
| 2 |
| 3 |
| 3 |
| 4 |
| 5 |
| EOF |
| |
| title10="Two close matches versus one less close match" |
| cat <<EOF >a10 |
| abcdef |
| abcdef |
| ghijkl |
| EOF |
| cat <<EOF >b10 |
| gh |
| abcdefx |
| EOF |
| cat <<EOF >expected10 |
| Final |
| 2 |
| EOF |
| |
| # The first line of b matches best with the last line of a, but the overall |
| # match is better if we match it with the first line of a. |
| title11="Piggy in the middle" |
| cat <<EOF >a11 |
| abcdefg |
| ijklmn |
| abcdefgh |
| EOF |
| cat <<EOF >b11 |
| abcdefghx |
| ijklm |
| EOF |
| cat <<EOF >expected11 |
| 1 |
| 2 |
| EOF |
| |
| title12="No trailing newline" |
| printf "abc\ndef" >a12 |
| printf "abx\nstu" >b12 |
| cat <<EOF >expected12 |
| 1 |
| Final |
| EOF |
| |
| title13="Reorder includes" |
| cat <<EOF >a13 |
| #include "c.h" |
| #include "b.h" |
| #include "a.h" |
| #include "e.h" |
| #include "d.h" |
| EOF |
| cat <<EOF >b13 |
| #include "a.h" |
| #include "b.h" |
| #include "c.h" |
| #include "d.h" |
| #include "e.h" |
| EOF |
| cat <<EOF >expected13 |
| 3 |
| 2 |
| 1 |
| 5 |
| 4 |
| EOF |
| |
| last_test=13 |
| |
| test_expect_success setup ' |
| for i in $(test_seq 2 $last_test) |
| do |
| # Append each line in a separate commit to make it easy to |
| # check which original line the blame output relates to. |
| |
| line_count=0 && |
| while IFS= read line |
| do |
| line_count=$((line_count+1)) && |
| echo "$line" >>"$i" && |
| git add "$i" && |
| test_tick && |
| GIT_AUTHOR_NAME="$line_count" git commit -m "$line_count" |
| done <"a$i" |
| done && |
| |
| for i in $(test_seq 2 $last_test) |
| do |
| # Overwrite the files with the final content. |
| cp b$i $i && |
| git add $i |
| done && |
| test_tick && |
| |
| # Commit the final content all at once so it can all be |
| # referred to with the same commit ID. |
| GIT_AUTHOR_NAME=Final git commit -m Final && |
| |
| IGNOREME=$(git rev-parse HEAD) |
| ' |
| |
| for i in $(test_seq 2 $last_test); do |
| eval title="\$title$i" |
| test_expect_success "$title" \ |
| "git blame -M9 --ignore-rev $IGNOREME $i >output && |
| sed -e \"$pick_author\" output >actual && |
| test_cmp expected$i actual" |
| done |
| |
| # This invoked a null pointer dereference when the chunk callback was called |
| # with a zero length parent chunk and there were no more suspects. |
| test_expect_success 'Diff chunks with no suspects' ' |
| test_write_lines xy1 A B C xy1 >file && |
| git add file && |
| test_tick && |
| GIT_AUTHOR_NAME=1 git commit -m 1 && |
| |
| test_write_lines xy2 A B xy2 C xy2 >file && |
| git add file && |
| test_tick && |
| GIT_AUTHOR_NAME=2 git commit -m 2 && |
| REV_2=$(git rev-parse HEAD) && |
| |
| test_write_lines xy3 A >file && |
| git add file && |
| test_tick && |
| GIT_AUTHOR_NAME=3 git commit -m 3 && |
| REV_3=$(git rev-parse HEAD) && |
| |
| test_write_lines 1 1 >expected && |
| |
| git blame --ignore-rev $REV_2 --ignore-rev $REV_3 file >output && |
| sed -e "$pick_author" output >actual && |
| |
| test_cmp expected actual |
| ' |
| |
| test_expect_success 'position matching' ' |
| test_write_lines abc def >file2 && |
| git add file2 && |
| test_tick && |
| GIT_AUTHOR_NAME=1 git commit -m 1 && |
| |
| test_write_lines abc def abc def >file2 && |
| git add file2 && |
| test_tick && |
| GIT_AUTHOR_NAME=2 git commit -m 2 && |
| |
| test_write_lines abcx defx abcx defx >file2 && |
| git add file2 && |
| test_tick && |
| GIT_AUTHOR_NAME=3 git commit -m 3 && |
| REV_3=$(git rev-parse HEAD) && |
| |
| test_write_lines abcy defy abcx defx >file2 && |
| git add file2 && |
| test_tick && |
| GIT_AUTHOR_NAME=4 git commit -m 4 && |
| REV_4=$(git rev-parse HEAD) && |
| |
| test_write_lines 1 1 2 2 >expected && |
| |
| git blame --ignore-rev $REV_3 --ignore-rev $REV_4 file2 >output && |
| sed -e "$pick_author" output >actual && |
| |
| test_cmp expected actual |
| ' |
| |
| # This fails if each blame entry is processed independently instead of |
| # processing each diff change in full. |
| test_expect_success 'preserve order' ' |
| test_write_lines bcde >file3 && |
| git add file3 && |
| test_tick && |
| GIT_AUTHOR_NAME=1 git commit -m 1 && |
| |
| test_write_lines bcde fghij >file3 && |
| git add file3 && |
| test_tick && |
| GIT_AUTHOR_NAME=2 git commit -m 2 && |
| |
| test_write_lines bcde fghij abcd >file3 && |
| git add file3 && |
| test_tick && |
| GIT_AUTHOR_NAME=3 git commit -m 3 && |
| |
| test_write_lines abcdx fghijx bcdex >file3 && |
| git add file3 && |
| test_tick && |
| GIT_AUTHOR_NAME=4 git commit -m 4 && |
| REV_4=$(git rev-parse HEAD) && |
| |
| test_write_lines abcdx fghijy bcdex >file3 && |
| git add file3 && |
| test_tick && |
| GIT_AUTHOR_NAME=5 git commit -m 5 && |
| REV_5=$(git rev-parse HEAD) && |
| |
| test_write_lines 1 2 3 >expected && |
| |
| git blame --ignore-rev $REV_4 --ignore-rev $REV_5 file3 >output && |
| sed -e "$pick_author" output >actual && |
| |
| test_cmp expected actual |
| ' |
| |
| test_done |