#!/bin/sh
# The diff page, unified or side-by-side under dt=1. The first checks read
# the markup for one added file in the fixture repository. The rest build
# repositories of their own, shaped for the side-by-side renderer's two
# trickiest cases, a hunk covering a single line and a file where every
# line changed.
test_description='Check content on diff page'
. ./setup.sh
test_expect_success 'generate foo/diff' 'cgit_url "foo/diff" >tmp'
test_expect_success 'find diff header' 'grep "a/file-5 b/file-5" tmp'
test_expect_success 'find blob link' 'grep "@@ -0,0 +1 @@" tmp
'
test_expect_success 'find added line' '
grep "+5
" tmp
'
# The unified diff sits in a single cell, which holds the files together
# rather than tabulating them, so a screen reader is told it is layout.
test_expect_success 'the unified diff table is read as layout' '
grep "
" tmp
'
# A revision that names no commit is quoted the way the request wrote it, as
# the commit and patch pages quote it, on either side of the diff.
test_expect_success 'a tree on either side is named as the request gave it' '
tree=$(git -C repos/foo rev-parse --short HEAD^{tree}) &&
cgit_url "foo/diff/&id=$tree" >tmp &&
grep "Not a commit: $tree
" tmp &&
cgit_url "foo/diff/&id2=$tree" >tmp &&
grep "Not a commit: $tree
" tmp
'
# git writes a hunk length only when the hunk spans more than one line, so the
# header for a single line reads "@@ -1 +1 @@" with no comma in it. Requiring
# that comma left those hunks numbered from zero, which dropped the line
# number link altogether.
test_expect_success 'set up a repo with single-line hunks' '
mkrepo repos/hunk1 1 &&
(
cd repos/hunk1 &&
printf "only\n" >one.txt &&
git add one.txt &&
git commit -m "add one.txt" &&
printf "ONLY\n" >one.txt &&
git commit -am "change one.txt"
) &&
cgitrc_repo hunk1rc hunk1 &&
git -C repos/hunk1 diff HEAD~1 HEAD >raw.diff &&
grep "^@@ -1 +1 @@" raw.diff
'
test_expect_success 'ssdiff numbers a comma-less hunk from its real line' '
old=$(git -C repos/hunk1 rev-parse HEAD~1) &&
new=$(git -C repos/hunk1 rev-parse HEAD) &&
cgit_ok hunk1rc "url=hunk1/diff/&dt=1" >tmp &&
grep "1" tmp &&
grep "1" tmp
'
# A line dropped near the top leaves the two sides of the later hunk starting
# at different lines, so each side has to be numbered from its own half of the
# header.
test_expect_success 'set up a repo whose later hunk starts apart on each side' '
mkrepo repos/later 1 &&
(
cd repos/later &&
test_seq 1 20 >twenty.txt &&
git add twenty.txt &&
git commit -m "add twenty.txt" &&
test_seq 1 20 | sed -e 2d -e s/^15$/fifteen/ >twenty.txt &&
git commit -am "change twenty.txt"
) &&
cgitrc_repo laterrc later &&
git -C repos/later diff HEAD~1 HEAD >raw.diff &&
grep "^@@ -12,7 +11,7 @@" raw.diff
'
test_expect_success 'ssdiff numbers each side of a hunk from its own start' '
old=$(git -C repos/later rev-parse HEAD~1) &&
new=$(git -C repos/later rev-parse HEAD) &&
cgit_ok laterrc "url=later/diff/&dt=1" >tmp &&
grep -x "12 | 12 | " tmp &&
grep -x "11 | 12 | " tmp &&
grep "15" tmp &&
grep "14 | " tmp
'
# The character level highlight reuses one table across every changed pair, so
# these lines get shorter as the file goes on and each comparison is smaller
# than the one before it. That is where a cell left over from the previous
# pair shows itself, as a del or an add span sitting over the wrong
# characters.
test_expect_success 'set up a repo with shrinking changed lines' '
mkrepo repos/lcs 1 &&
(
cd repos/lcs &&
awk "BEGIN{for(n=120;n>0;n-=3){s=\"\";
for(i=0;ilines.txt &&
git add lines.txt &&
git commit -m "add lines.txt" &&
awk "BEGIN{for(n=120;n>0;n-=3){s=\"\";
for(i=0;ilines.txt &&
git commit -am "change every line"
) &&
cgitrc_repo lcsrc lcs
'
test_expect_success 'every changed pair gets both a del and an add span' '
cgit_rc lcsrc "url=lcs/diff/&dt=1" >tmp &&
deletions=$(grep -o "" tmp | wc -l) &&
additions=$(grep -o "" tmp | wc -l) &&
test "$deletions" -gt 0 &&
test "$deletions" -eq "$additions"
'
test_expect_success 'stripping the highlight leaves every line intact' '
sed -e "s/<[^>]*>//g" tmp >plain.out &&
git -C repos/lcs show HEAD~1:lines.txt >lines &&
git -C repos/lcs show HEAD:lines.txt >>lines &&
while read -r line
do
grep -qF "$line" plain.out || {
echo "missing line: $line"
return 1
}
done old.txt &&
git add old.txt &&
git commit -m "add old.txt" &&
git mv old.txt new.txt &&
echo changed >file-1 &&
git commit -am "rename old.txt"
) &&
cgitrc_repo movedrc moved
'
test_expect_success 'the diff of a renamed file shows the rename alone' '
cgit_ok movedrc "url=moved/diff/new.txt" >tmp &&
grep "diff --git a/old.txt b/new.txt" tmp &&
grep " (renamed from old.txt) | " tmp &&
grep "1 file changed, 0 insertions, 0 deletions
" tmp &&
! grep "new file mode" tmp &&
! grep "a/file-1 b/file-1" tmp
'
test_expect_success 'so does the commit page limited to the new name' '
cgit_ok movedrc "url=moved/commit/new.txt" >tmp &&
grep "diff --git a/old.txt b/new.txt" tmp &&
grep "1 file changed, 0 insertions, 0 deletions
" tmp &&
! grep "new file mode" tmp &&
! grep "a/file-1 b/file-1" tmp
'
# Following a file diffs the whole commit and keeps the pairs on that path,
# and the header still names the path rather than the empty limit the walk
# runs under.
test_expect_success 'a followed file is diffed as the rename alone' '
cgitrc_repo followrc moved enable-follow-links=1 &&
cgit_ok followrc "url=moved/diff/new.txt&follow=1" >tmp &&
grep "diff --git a/old.txt b/new.txt" tmp &&
grep "Diffstat (limited to .new.txt.)" tmp &&
grep "1 file changed, 0 insertions, 0 deletions
" tmp &&
! grep "a/file-1 b/file-1" tmp &&
cgit_ok followrc "url=moved/commit/new.txt&follow=1" >tmp &&
grep "diff --git a/old.txt b/new.txt" tmp &&
grep "Diffstat (limited to .new.txt.)" tmp &&
! grep "a/file-1 b/file-1" tmp
'
test_expect_success 'following with no path limits nothing' '
cgit_ok followrc "url=moved/commit/&follow=1" >tmp &&
grep "diff --git a/file-1 b/file-1" tmp &&
grep "" tmp
'
test_expect_success 'a file added outright still shows as new' '
added=$(git -C repos/moved rev-parse HEAD~1) &&
cgit_ok movedrc "url=moved/diff/old.txt&id=$added" >tmp &&
grep "new file mode 100644" tmp &&
grep "+10
" tmp
'
test_done