Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 75 additions & 130 deletions tui/diff_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,23 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC

curr := activeCommit
diffView.Clear()
if change == nil {
left.Clear()
right.Clear()
return
}

var context *whatChanged.ChangeContext
if change.Context != nil {
context = change.Context
}

if change.OriginalObject == nil {
left.Clear()
} else {
left.Clear()

if change.Context.OriginalLine != nil {
if context != nil && context.OriginalLine != nil {

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

origLine := 0
origCol := 0
if change.Context.OriginalLine == nil {
origLine = 0
origCol = 0
} else {
origLine = *change.Context.OriginalLine
origCol = *change.Context.OriginalColumn
if context.OriginalLine != nil {
origLine = *context.OriginalLine
}
if context.OriginalColumn != nil {
origCol = *context.OriginalColumn
}

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

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

left.SetWrap(false)
data := string(curr.OldData)
parsed := strings.Split(data, "\n")

var clipped []string

var startLine, currentLine, endLine int

if change.Context.OriginalLine != nil && origLine > 5 {

top := origLine + 8
if top >= len(parsed) {
top = len(parsed) - 1
}

clipped = parsed[origLine-5 : top]

startLine = origLine - 4
currentLine = startLine
endLine = origLine + 8

for j := range clipped {
if j != 4 {
clipped[j] = fmt.Sprintf("[grey]%s[-:-]", clipped[j])
}
}

color := getColorForChange(originalView, changeNumber, startLine, currentLine)

if !change.Breaking {
clipped[4] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[4])
} else {
clipped[4] = fmt.Sprintf("[%s]%s[-:-]", "red", clipped[4])
}

} else {
if change.Context.OriginalLine != nil {
startLine = origLine
currentLine = startLine
endLine = origLine + 13

for j := range clipped {
if j != origLine {
clipped[j] = fmt.Sprintf("[%s]%s[-:-]", "grey", clipped[j])
}
}

color := getColorForChange(originalView, changeNumber, startLine, currentLine)

clipped = parsed[0 : origLine+13]

if !change.Breaking {
clipped[origLine] = fmt.Sprintf("[%s]%s[-:-]",
color, clipped[origLine])
} else {
clipped[origLine] = fmt.Sprintf("[%s]%s[-:-]", "red",
clipped[origLine])
}
}
}

if change.Context.OriginalLine != nil {

for x := range clipped {
color := getColorForChange(originalView, lineNumber, currentLine, origLine)
if !change.Breaking {
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
} else {
if currentLine != *change.Context.OriginalLine {
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
} else {
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
printSpacing(currentLine, endLine), "red", currentLine, clipped[x])
}
}
currentLine++
}
}
clipped, startLine, highlightLine, endLine :=
buildClippedLines(string(curr.OldData), origLine)
clipped = styleClippedLines(clipped, originalView, startLine, highlightLine, endLine, change.Breaking)
_, _ = fmt.Fprintf(left, "%s", strings.Join(clipped, "\n"))
}
}
Expand All @@ -200,12 +133,11 @@ func RenderDiff(left, right *tview.TextView, diffView *tview.Flex, change *whatC

newLine := 0
newCol := 0
if change.Context.NewLine == nil {
newLine = 0
newCol = 0
} else {
newLine = *change.Context.NewLine
newCol = *change.Context.NewColumn
if context != nil && context.NewLine != nil {
newLine = *context.NewLine
}
if context != nil && context.NewColumn != nil {
newCol = *context.NewColumn
}

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

data := string(curr.Data)
parsed := strings.Split(data, "\n")
clipped, startLine, highlightLine, endLine := buildClippedLines(string(curr.Data), newLine)
clipped = styleClippedLines(clipped, newView, startLine, highlightLine, endLine, change.Breaking)
_, _ = fmt.Fprintf(right, "%s", strings.Join(clipped, "\n"))
}

var clipped []string
}

var startLine, currentLine, endLine int
func buildClippedLines(data string, line int) ([]string, int, int, int) {
parsed := strings.Split(data, "\n")
if len(parsed) == 0 {
parsed = []string{""}
}

if newLine > 5 {
clipped = parsed[newLine-5 : newLine+8]
startLine = newLine - 4
currentLine = startLine
endLine = newLine + 8
highlightLine := line
if highlightLine < 1 {
highlightLine = 1
}
if highlightLine > len(parsed) {
highlightLine = len(parsed)
}

for j := range clipped {
if j != 4 {
clipped[j] = fmt.Sprintf("[grey]%s[-:-]", clipped[j])
}
}
startLine := highlightLine - 4
if startLine < 1 {
startLine = 1
}
endLine := startLine + 12
if endLine > len(parsed) {
endLine = len(parsed)
}
if endLine-startLine < 12 {
startLine = endLine - 12
if startLine < 1 {
startLine = 1
}
}

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

func styleClippedLines(clipped []string, view ViewType, startLine, highlightLine, endLine int, breaking bool) []string {
currentLine := startLine
for i := range clipped {
if currentLine != highlightLine {
clipped[i] = fmt.Sprintf("[grey]%s[-:-]", clipped[i])
} else {
startLine = newLine
currentLine = startLine
endLine = newLine + 13
color := getColorForChange(newView, changeNumber, startLine, currentLine)

for j := range clipped {
if j != *change.Context.NewLine {
clipped[j] = fmt.Sprintf("[%s]%s[-:-]", "grey", clipped[j])
}
color := getColorForChange(view, changeNumber, currentLine, highlightLine)
if breaking {
color = "red"
}

clipped = parsed[0 : newLine+13]
clipped[newLine] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[newLine])

clipped[i] = fmt.Sprintf("[%s]%s[-:-]", color, clipped[i])
}

for x := range clipped {
color := getColorForChange(newView, lineNumber, currentLine, newLine)
clipped[x] = fmt.Sprintf("%s[%s]%d|[-] %s",
printSpacing(currentLine, endLine), color, currentLine, clipped[x])
currentLine++
color := getColorForChange(view, lineNumber, currentLine, highlightLine)
if breaking && currentLine == highlightLine {
color = "red"
}

_, _ = fmt.Fprintf(right, "%s", strings.Join(clipped, "\n"))
clipped[i] = fmt.Sprintf("%s[%s]%d|[-] %s",
printSpacing(currentLine, endLine), color, currentLine, clipped[i])
currentLine++
}

return clipped
}

func getColorForChange(view ViewType, changeType ColorType, currentLine, changeLine int) string {
Expand Down
97 changes: 97 additions & 0 deletions tui/diff_view_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package tui

import (
"testing"

whatChangedModel "github.com/pb33f/libopenapi/what-changed/model"
changesModel "github.com/pb33f/openapi-changes/model"
"github.com/stretchr/testify/require"
)

func TestRenderDiff_DoesNotPanicOnShortNewData(t *testing.T) {
newLine := 1
newColumn := 1

prevCommit := activeCommit
activeCommit = &changesModel.Commit{
Data: []byte("value"),
}
t.Cleanup(func() {
activeCommit = prevCommit
})

left := BuildTextView()
right := BuildTextView()
diffView := BuildDiffView(left, right)

change := &whatChangedModel.Change{
Context: &whatChangedModel.ChangeContext{
NewLine: &newLine,
NewColumn: &newColumn,
},
NewObject: struct{}{},
New: "value",
}

require.NotPanics(t, func() {
RenderDiff(left, right, diffView, change)
})
}

func TestRenderDiff_DoesNotPanicOnShortOriginalData(t *testing.T) {
originalLine := 1
originalColumn := 1

prevCommit := activeCommit
activeCommit = &changesModel.Commit{
OldData: []byte("value"),
}
t.Cleanup(func() {
activeCommit = prevCommit
})

left := BuildTextView()
right := BuildTextView()
diffView := BuildDiffView(left, right)

change := &whatChangedModel.Change{
Context: &whatChangedModel.ChangeContext{
OriginalLine: &originalLine,
OriginalColumn: &originalColumn,
},
OriginalObject: struct{}{},
Original: "value",
}

require.NotPanics(t, func() {
RenderDiff(left, right, diffView, change)
})
}

func TestRenderDiff_DoesNotPanicWhenLineExceedsDocumentLength(t *testing.T) {
newLine := 25

prevCommit := activeCommit
activeCommit = &changesModel.Commit{
Data: []byte("value"),
}
t.Cleanup(func() {
activeCommit = prevCommit
})

left := BuildTextView()
right := BuildTextView()
diffView := BuildDiffView(left, right)

change := &whatChangedModel.Change{
Context: &whatChangedModel.ChangeContext{
NewLine: &newLine,
},
NewObject: struct{}{},
New: "value",
}

require.NotPanics(t, func() {
RenderDiff(left, right, diffView, change)
})
}
Loading