Skip to content

Commit 0fb3be7

Browse files
authored
Fix diff blob excerpt expansion (#35922)
And add comments and tests
1 parent d6dc531 commit 0fb3be7

File tree

3 files changed

+171
-33
lines changed

3 files changed

+171
-33
lines changed

routers/web/repo/compare.go

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"encoding/csv"
1010
"errors"
1111
"fmt"
12-
"html"
1312
"io"
1413
"net/http"
1514
"net/url"
@@ -957,30 +956,26 @@ func ExcerptBlob(ctx *context.Context) {
957956
ctx.HTTPError(http.StatusInternalServerError, "getExcerptLines")
958957
return
959958
}
960-
if idxRight > lastRight {
961-
lineText := " "
962-
if rightHunkSize > 0 || leftHunkSize > 0 {
963-
lineText = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize)
964-
}
965-
lineText = html.EscapeString(lineText)
966-
lineSection := &gitdiff.DiffLine{
967-
Type: gitdiff.DiffLineSection,
968-
Content: lineText,
969-
SectionInfo: &gitdiff.DiffLineSectionInfo{
970-
Path: filePath,
971-
LastLeftIdx: lastLeft,
972-
LastRightIdx: lastRight,
973-
LeftIdx: idxLeft,
974-
RightIdx: idxRight,
975-
LeftHunkSize: leftHunkSize,
976-
RightHunkSize: rightHunkSize,
977-
},
978-
}
959+
960+
newLineSection := &gitdiff.DiffLine{
961+
Type: gitdiff.DiffLineSection,
962+
SectionInfo: &gitdiff.DiffLineSectionInfo{
963+
Path: filePath,
964+
LastLeftIdx: lastLeft,
965+
LastRightIdx: lastRight,
966+
LeftIdx: idxLeft,
967+
RightIdx: idxRight,
968+
LeftHunkSize: leftHunkSize,
969+
RightHunkSize: rightHunkSize,
970+
},
971+
}
972+
if newLineSection.GetExpandDirection() != "" {
973+
newLineSection.Content = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize)
979974
switch direction {
980975
case "up":
981-
section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...)
976+
section.Lines = append([]*gitdiff.DiffLine{newLineSection}, section.Lines...)
982977
case "down":
983-
section.Lines = append(section.Lines, lineSection)
978+
section.Lines = append(section.Lines, newLineSection)
984979
}
985980
}
986981

services/gitdiff/gitdiff.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,34 @@ type DiffLine struct {
8282

8383
// DiffLineSectionInfo represents diff line section meta data
8484
type DiffLineSectionInfo struct {
85-
Path string
86-
LastLeftIdx int
87-
LastRightIdx int
88-
LeftIdx int
89-
RightIdx int
85+
Path string
86+
87+
// These line "idx" are 1-based line numbers
88+
// Left/Right refer to the left/right side of the diff:
89+
//
90+
// LastLeftIdx | LastRightIdx
91+
// [up/down expander] @@ hunk info @@
92+
// LeftIdx | RightIdx
93+
94+
LastLeftIdx int
95+
LastRightIdx int
96+
LeftIdx int
97+
RightIdx int
98+
99+
// Hunk sizes of the hidden lines
90100
LeftHunkSize int
91101
RightHunkSize int
92102

103+
// For example:
104+
// 17 | 31
105+
// [up/down] @@ -40,23 +54,9 @@ ....
106+
// 40 | 54
107+
//
108+
// In this case:
109+
// LastLeftIdx = 17, LastRightIdx = 31
110+
// LeftHunkSize = 23, RightHunkSize = 9
111+
// LeftIdx = 40, RightIdx = 54
112+
93113
HiddenCommentIDs []int64 // IDs of hidden comments in this section
94114
}
95115

@@ -158,13 +178,13 @@ func (d *DiffLine) getBlobExcerptQuery() string {
158178
return query
159179
}
160180

161-
func (d *DiffLine) getExpandDirection() string {
181+
func (d *DiffLine) GetExpandDirection() string {
162182
if d.Type != DiffLineSection || d.SectionInfo == nil || d.SectionInfo.LeftIdx-d.SectionInfo.LastLeftIdx <= 1 || d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx <= 1 {
163183
return ""
164184
}
165185
if d.SectionInfo.LastLeftIdx <= 0 && d.SectionInfo.LastRightIdx <= 0 {
166186
return "up"
167-
} else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx > BlobExcerptChunkSize && d.SectionInfo.RightHunkSize > 0 {
187+
} else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx-1 > BlobExcerptChunkSize && d.SectionInfo.RightHunkSize > 0 {
168188
return "updown"
169189
} else if d.SectionInfo.LeftHunkSize <= 0 && d.SectionInfo.RightHunkSize <= 0 {
170190
return "down"
@@ -202,13 +222,13 @@ func (d *DiffLine) RenderBlobExcerptButtons(fileNameHash string, data *DiffBlobE
202222
content += htmlutil.HTMLFormat(`<span class="code-comment-more" data-tooltip-content="%s">%d</span>`, tooltip, len(d.SectionInfo.HiddenCommentIDs))
203223
}
204224

205-
expandDirection := d.getExpandDirection()
206-
if expandDirection == "up" || expandDirection == "updown" {
207-
content += makeButton("up", "octicon-fold-up")
208-
}
225+
expandDirection := d.GetExpandDirection()
209226
if expandDirection == "updown" || expandDirection == "down" {
210227
content += makeButton("down", "octicon-fold-down")
211228
}
229+
if expandDirection == "up" || expandDirection == "updown" {
230+
content += makeButton("up", "octicon-fold-up")
231+
}
212232
if expandDirection == "single" {
213233
content += makeButton("single", "octicon-fold")
214234
}

services/gitdiff/gitdiff_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,3 +983,126 @@ func TestDiffLine_RenderBlobExcerptButtons(t *testing.T) {
983983
})
984984
}
985985
}
986+
987+
func TestDiffLine_GetExpandDirection(t *testing.T) {
988+
cases := []struct {
989+
name string
990+
diffLine *DiffLine
991+
direction string
992+
}{
993+
{
994+
name: "NotSectionLine",
995+
diffLine: &DiffLine{Type: DiffLineAdd, SectionInfo: &DiffLineSectionInfo{}},
996+
direction: "",
997+
},
998+
{
999+
name: "NilSectionInfo",
1000+
diffLine: &DiffLine{Type: DiffLineSection, SectionInfo: nil},
1001+
direction: "",
1002+
},
1003+
{
1004+
name: "NoHiddenLines",
1005+
// last block stops at line 100, next block starts at line 101, so no hidden lines, no expansion.
1006+
diffLine: &DiffLine{
1007+
Type: DiffLineSection,
1008+
SectionInfo: &DiffLineSectionInfo{
1009+
LastRightIdx: 100,
1010+
LastLeftIdx: 100,
1011+
RightIdx: 101,
1012+
LeftIdx: 101,
1013+
},
1014+
},
1015+
direction: "",
1016+
},
1017+
{
1018+
name: "FileHead",
1019+
diffLine: &DiffLine{
1020+
Type: DiffLineSection,
1021+
SectionInfo: &DiffLineSectionInfo{
1022+
LastRightIdx: 0, // LastXxxIdx = 0 means this is the first section in the file.
1023+
LastLeftIdx: 0,
1024+
RightIdx: 1,
1025+
LeftIdx: 1,
1026+
},
1027+
},
1028+
direction: "",
1029+
},
1030+
{
1031+
name: "FileHeadHiddenLines",
1032+
diffLine: &DiffLine{
1033+
Type: DiffLineSection,
1034+
SectionInfo: &DiffLineSectionInfo{
1035+
LastRightIdx: 0,
1036+
LastLeftIdx: 0,
1037+
RightIdx: 101,
1038+
LeftIdx: 101,
1039+
},
1040+
},
1041+
direction: "up",
1042+
},
1043+
{
1044+
name: "HiddenSingleHunk",
1045+
diffLine: &DiffLine{
1046+
Type: DiffLineSection,
1047+
SectionInfo: &DiffLineSectionInfo{
1048+
LastRightIdx: 100,
1049+
LastLeftIdx: 100,
1050+
RightIdx: 102,
1051+
LeftIdx: 102,
1052+
RightHunkSize: 1234, // non-zero dummy value
1053+
LeftHunkSize: 5678, // non-zero dummy value
1054+
},
1055+
},
1056+
direction: "single",
1057+
},
1058+
{
1059+
name: "HiddenSingleFullHunk",
1060+
// the hidden lines can exactly fit into one hunk
1061+
diffLine: &DiffLine{
1062+
Type: DiffLineSection,
1063+
SectionInfo: &DiffLineSectionInfo{
1064+
LastRightIdx: 100,
1065+
LastLeftIdx: 100,
1066+
RightIdx: 100 + BlobExcerptChunkSize + 1,
1067+
LeftIdx: 100 + BlobExcerptChunkSize + 1,
1068+
RightHunkSize: 1234, // non-zero dummy value
1069+
LeftHunkSize: 5678, // non-zero dummy value
1070+
},
1071+
},
1072+
direction: "single",
1073+
},
1074+
{
1075+
name: "HiddenUpDownHunks",
1076+
diffLine: &DiffLine{
1077+
Type: DiffLineSection,
1078+
SectionInfo: &DiffLineSectionInfo{
1079+
LastRightIdx: 100,
1080+
LastLeftIdx: 100,
1081+
RightIdx: 100 + BlobExcerptChunkSize + 2,
1082+
LeftIdx: 100 + BlobExcerptChunkSize + 2,
1083+
RightHunkSize: 1234, // non-zero dummy value
1084+
LeftHunkSize: 5678, // non-zero dummy value
1085+
},
1086+
},
1087+
direction: "updown",
1088+
},
1089+
{
1090+
name: "FileTail",
1091+
diffLine: &DiffLine{
1092+
Type: DiffLineSection,
1093+
SectionInfo: &DiffLineSectionInfo{
1094+
LastRightIdx: 100,
1095+
LastLeftIdx: 100,
1096+
RightIdx: 102,
1097+
LeftIdx: 102,
1098+
RightHunkSize: 0,
1099+
LeftHunkSize: 0,
1100+
},
1101+
},
1102+
direction: "down",
1103+
},
1104+
}
1105+
for _, c := range cases {
1106+
assert.Equal(t, c.direction, c.diffLine.GetExpandDirection(), "case %s expected direction: %s", c.name, c.direction)
1107+
}
1108+
}

0 commit comments

Comments
 (0)