Skip to content

Commit 864f82c

Browse files
committed
Address issue #243
1 parent 2ea1760 commit 864f82c

2 files changed

Lines changed: 172 additions & 130 deletions

File tree

tui/diff_view.go

Lines changed: 75 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,23 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
4040

4141
curr := activeCommit
4242
diffView.Clear()
43+
if change == nil {
44+
left.Clear()
45+
right.Clear()
46+
return
47+
}
48+
49+
var context *whatChanged.ChangeContext
50+
if change.Context != nil {
51+
context = change.Context
52+
}
4353

4454
if change.OriginalObject == nil {
4555
left.Clear()
4656
} else {
4757
left.Clear()
4858

49-
if change.Context.OriginalLine != nil {
59+
if context != nil && context.OriginalLine != nil {
5060

5161
table := tview.NewTable()
5262
table.SetBorders(false)
@@ -58,12 +68,11 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
5868

5969
origLine := 0
6070
origCol := 0
61-
if change.Context.OriginalLine == nil {
62-
origLine = 0
63-
origCol = 0
64-
} else {
65-
origLine = *change.Context.OriginalLine
66-
origCol = *change.Context.OriginalColumn
71+
if context.OriginalLine != nil {
72+
origLine = *context.OriginalLine
73+
}
74+
if context.OriginalColumn != nil {
75+
origCol = *context.OriginalColumn
6776
}
6877

6978
if change.NewObject == nil {
@@ -73,7 +82,7 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
7382
}
7483
}
7584

76-
if change.Context.OriginalLine != nil && change.Context.OriginalColumn != nil {
85+
if context.OriginalLine != nil {
7786
table.SetCell(1, 0, tview.NewTableCell(change.Original))
7887
table.SetCell(1, 1,
7988
tview.NewTableCell(fmt.Sprint(origLine)).SetAlign(tview.AlignCenter))
@@ -96,85 +105,9 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
96105
diffView.AddItem(y, 0, 1, false)
97106

98107
left.SetWrap(false)
99-
data := string(curr.OldData)
100-
parsed := strings.Split(data, "\n")
101-
102-
var clipped []string
103-
104-
var startLine, currentLine, endLine int
105-
106-
if change.Context.OriginalLine != nil && origLine > 5 {
107-
108-
top := origLine + 8
109-
if top >= len(parsed) {
110-
top = len(parsed) - 1
111-
}
112-
113-
clipped = parsed[origLine-5 : top]
114-
115-
startLine = origLine - 4
116-
currentLine = startLine
117-
endLine = origLine + 8
118-
119-
for j := range clipped {
120-
if j != 4 {
121-
clipped[j] = fmt.Sprintf("[grey]%s[-:-]", clipped[j])
122-
}
123-
}
124-
125-
color := getColorForChange(originalView, changeNumber, startLine, currentLine)
126-
127-
if !change.Breaking {
128-
clipped[4] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[4])
129-
} else {
130-
clipped[4] = fmt.Sprintf("[%s]%s[-:-]", "red", clipped[4])
131-
}
132-
133-
} else {
134-
if change.Context.OriginalLine != nil {
135-
startLine = origLine
136-
currentLine = startLine
137-
endLine = origLine + 13
138-
139-
for j := range clipped {
140-
if j != origLine {
141-
clipped[j] = fmt.Sprintf("[%s]%s[-:-]", "grey", clipped[j])
142-
}
143-
}
144-
145-
color := getColorForChange(originalView, changeNumber, startLine, currentLine)
146-
147-
clipped = parsed[0 : origLine+13]
148-
149-
if !change.Breaking {
150-
clipped[origLine] = fmt.Sprintf("[%s]%s[-:-]",
151-
color, clipped[origLine])
152-
} else {
153-
clipped[origLine] = fmt.Sprintf("[%s]%s[-:-]", "red",
154-
clipped[origLine])
155-
}
156-
}
157-
}
158-
159-
if change.Context.OriginalLine != nil {
160-
161-
for x := range clipped {
162-
color := getColorForChange(originalView, lineNumber, currentLine, origLine)
163-
if !change.Breaking {
164-
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
165-
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
166-
} else {
167-
if currentLine != *change.Context.OriginalLine {
168-
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
169-
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
170-
} else {
171-
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
172-
printSpacing(currentLine, endLine), "red", currentLine, clipped[x])
173-
}
174-
}
175-
currentLine++
176-
}
177-
}
108+
clipped, startLine, highlightLine, endLine :=
109+
buildClippedLines(string(curr.OldData), origLine)
110+
clipped = styleClippedLines(clipped, originalView, startLine, highlightLine, endLine, change.Breaking)
178111
_, _ = fmt.Fprintf(left, "%s", strings.Join(clipped, "\n"))
179112
}
180113
}
@@ -200,12 +133,11 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
200133

201134
newLine := 0
202135
newCol := 0
203-
if change.Context.NewLine == nil {
204-
newLine = 0
205-
newCol = 0
206-
} else {
207-
newLine = *change.Context.NewLine
208-
newCol = *change.Context.NewColumn
136+
if context != nil && context.NewLine != nil {
137+
newLine = *context.NewLine
138+
}
139+
if context != nil && context.NewColumn != nil {
140+
newCol = *context.NewColumn
209141
}
210142

211143
table.SetCell(1, 0, tview.NewTableCell(change.New))
@@ -228,55 +160,68 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC
228160
AddItem(right, 0, 1, false)
229161
diffView.AddItem(y, 0, 1, false)
230162

231-
data := string(curr.Data)
232-
parsed := strings.Split(data, "\n")
163+
clipped, startLine, highlightLine, endLine := buildClippedLines(string(curr.Data), newLine)
164+
clipped = styleClippedLines(clipped, newView, startLine, highlightLine, endLine, change.Breaking)
165+
_, _ = fmt.Fprintf(right, "%s", strings.Join(clipped, "\n"))
166+
}
233167

234-
var clipped []string
168+
}
235169

236-
var startLine, currentLine, endLine int
170+
func buildClippedLines(data string, line int) ([]string, int, int, int) {
171+
parsed := strings.Split(data, "\n")
172+
if len(parsed) == 0 {
173+
parsed = []string{""}
174+
}
237175

238-
if newLine > 5 {
239-
clipped = parsed[newLine-5 : newLine+8]
240-
startLine = newLine - 4
241-
currentLine = startLine
242-
endLine = newLine + 8
176+
highlightLine := line
177+
if highlightLine < 1 {
178+
highlightLine = 1
179+
}
180+
if highlightLine > len(parsed) {
181+
highlightLine = len(parsed)
182+
}
243183

244-
for j := range clipped {
245-
if j != 4 {
246-
clipped[j] = fmt.Sprintf("[grey]%s[-:-]", clipped[j])
247-
}
248-
}
184+
startLine := highlightLine - 4
185+
if startLine < 1 {
186+
startLine = 1
187+
}
188+
endLine := startLine + 12
189+
if endLine > len(parsed) {
190+
endLine = len(parsed)
191+
}
192+
if endLine-startLine < 12 {
193+
startLine = endLine - 12
194+
if startLine < 1 {
195+
startLine = 1
196+
}
197+
}
249198

250-
color := getColorForChange(newView, changeNumber, startLine, currentLine)
251-
clipped[4] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[4])
199+
clipped := append([]string(nil), parsed[startLine-1:endLine]...)
200+
return clipped, startLine, highlightLine, endLine
201+
}
252202

203+
func styleClippedLines(clipped []string, view ViewType, startLine, highlightLine, endLine int, breaking bool) []string {
204+
currentLine := startLine
205+
for i := range clipped {
206+
if currentLine != highlightLine {
207+
clipped[i] = fmt.Sprintf("[grey]%s[-:-]", clipped[i])
253208
} else {
254-
startLine = newLine
255-
currentLine = startLine
256-
endLine = newLine + 13
257-
color := getColorForChange(newView, changeNumber, startLine, currentLine)
258-
259-
for j := range clipped {
260-
if j != *change.Context.NewLine {
261-
clipped[j] = fmt.Sprintf("[%s]%s[-:-]", "grey", clipped[j])
262-
}
209+
color := getColorForChange(view, changeNumber, currentLine, highlightLine)
210+
if breaking {
211+
color = "red"
263212
}
264-
265-
clipped = parsed[0 : newLine+13]
266-
clipped[newLine] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[newLine])
267-
213+
clipped[i] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[i])
268214
}
269215

270-
for x := range clipped {
271-
color := getColorForChange(newView, lineNumber, currentLine, newLine)
272-
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
273-
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
274-
currentLine++
216+
color := getColorForChange(view, lineNumber, currentLine, highlightLine)
217+
if breaking && currentLine == highlightLine {
218+
color = "red"
275219
}
276-
277-
_, _ = fmt.Fprintf(right, "%s", strings.Join(clipped, "\n"))
220+
clipped[i] = fmt.Sprintf("%s[%s]%d|[-] %s",
221+
printSpacing(currentLine, endLine), color, currentLine, clipped[i])
222+
currentLine++
278223
}
279-
224+
return clipped
280225
}
281226

282227
func getColorForChange(view ViewType, changeType ColorType, currentLine, changeLine int) string {

tui/diff_view_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package tui
2+
3+
import (
4+
"testing"
5+
6+
whatChangedModel "github.com/pb33f/libopenapi/what-changed/model"
7+
changesModel "github.com/pb33f/openapi-changes/model"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestRenderDiff_DoesNotPanicOnShortNewData(t *testing.T) {
12+
newLine := 1
13+
newColumn := 1
14+
15+
prevCommit := activeCommit
16+
activeCommit = &changesModel.Commit{
17+
Data: []byte("value"),
18+
}
19+
t.Cleanup(func() {
20+
activeCommit = prevCommit
21+
})
22+
23+
left := BuildTextView()
24+
right := BuildTextView()
25+
diffView := BuildDiffView(left, right)
26+
27+
change := &whatChangedModel.Change{
28+
Context: &whatChangedModel.ChangeContext{
29+
NewLine: &newLine,
30+
NewColumn: &newColumn,
31+
},
32+
NewObject: struct{}{},
33+
New: "value",
34+
}
35+
36+
require.NotPanics(t, func() {
37+
RenderDiff(left, right, diffView, change)
38+
})
39+
}
40+
41+
func TestRenderDiff_DoesNotPanicOnShortOriginalData(t *testing.T) {
42+
originalLine := 1
43+
originalColumn := 1
44+
45+
prevCommit := activeCommit
46+
activeCommit = &changesModel.Commit{
47+
OldData: []byte("value"),
48+
}
49+
t.Cleanup(func() {
50+
activeCommit = prevCommit
51+
})
52+
53+
left := BuildTextView()
54+
right := BuildTextView()
55+
diffView := BuildDiffView(left, right)
56+
57+
change := &whatChangedModel.Change{
58+
Context: &whatChangedModel.ChangeContext{
59+
OriginalLine: &originalLine,
60+
OriginalColumn: &originalColumn,
61+
},
62+
OriginalObject: struct{}{},
63+
Original: "value",
64+
}
65+
66+
require.NotPanics(t, func() {
67+
RenderDiff(left, right, diffView, change)
68+
})
69+
}
70+
71+
func TestRenderDiff_DoesNotPanicWhenLineExceedsDocumentLength(t *testing.T) {
72+
newLine := 25
73+
74+
prevCommit := activeCommit
75+
activeCommit = &changesModel.Commit{
76+
Data: []byte("value"),
77+
}
78+
t.Cleanup(func() {
79+
activeCommit = prevCommit
80+
})
81+
82+
left := BuildTextView()
83+
right := BuildTextView()
84+
diffView := BuildDiffView(left, right)
85+
86+
change := &whatChangedModel.Change{
87+
Context: &whatChangedModel.ChangeContext{
88+
NewLine: &newLine,
89+
},
90+
NewObject: struct{}{},
91+
New: "value",
92+
}
93+
94+
require.NotPanics(t, func() {
95+
RenderDiff(left, right, diffView, change)
96+
})
97+
}

0 commit comments

Comments
 (0)