test(parser/diff): add myers diff test
This commit is contained in:
parent
60d9e1b215
commit
b8c233b1bb
69
internal/parser/diff/diff_test.go
Normal file
69
internal/parser/diff/diff_test.go
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMyersDiff(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
src []string
|
||||||
|
dst []string
|
||||||
|
compareSpace bool
|
||||||
|
expected []operation
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Insert operation",
|
||||||
|
src: []string{"a", "b"},
|
||||||
|
dst: []string{"a", "b", "c"},
|
||||||
|
compareSpace: true,
|
||||||
|
expected: []operation{MOVE, MOVE, INSERT},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Delete operation",
|
||||||
|
src: []string{"a", "b", "c"},
|
||||||
|
dst: []string{"a", "b"},
|
||||||
|
compareSpace: true,
|
||||||
|
expected: []operation{MOVE, MOVE, DELETE},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "No changes",
|
||||||
|
src: []string{"a", "b", "c"},
|
||||||
|
dst: []string{"a", "b", "c"},
|
||||||
|
compareSpace: true,
|
||||||
|
expected: []operation{MOVE, MOVE, MOVE},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Move operation",
|
||||||
|
src: []string{"a", "b", "c"},
|
||||||
|
dst: []string{"c", "a", "b"},
|
||||||
|
compareSpace: true,
|
||||||
|
expected: []operation{INSERT, MOVE, MOVE, DELETE},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ignore whitespace differences",
|
||||||
|
src: []string{"a ", "b"},
|
||||||
|
dst: []string{"a", "b"},
|
||||||
|
compareSpace: false,
|
||||||
|
expected: []operation{MOVE, MOVE},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Consider whitespace differences",
|
||||||
|
src: []string{"a ", "b"},
|
||||||
|
dst: []string{"a", "b"},
|
||||||
|
compareSpace: true,
|
||||||
|
expected: []operation{DELETE, INSERT, MOVE},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
result := myersDiff(test.src, test.dst, test.compareSpace)
|
||||||
|
if !reflect.DeepEqual(result, test.expected) {
|
||||||
|
t.Errorf("myersDiff(%v, %v, %v) = %v; want %v",
|
||||||
|
test.src, test.dst, test.compareSpace, result, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
|
||||||
"actual length", len(result.Files[output.FileName]),
|
"actual length", len(result.Files[output.FileName]),
|
||||||
"answer length", len(string(answer)))
|
"answer length", len(string(answer)))
|
||||||
// If no difference, assign score
|
// If no difference, assign score
|
||||||
if compareChars(string(answer), result.Files[output.FileName],
|
if compareStrings(string(answer), result.Files[output.FileName],
|
||||||
output.CompareSpace) {
|
output.CompareSpace) {
|
||||||
score += output.Score
|
score += output.Score
|
||||||
comment += conf.PassComment
|
comment += conf.PassComment
|
||||||
|
@ -82,7 +82,8 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
|
||||||
result.Files[output.FileName], "\n")
|
result.Files[output.FileName], "\n")
|
||||||
|
|
||||||
// Generate Myers diff
|
// Generate Myers diff
|
||||||
diffOps := myersDiff(stdoutLines, resultLines)
|
diffOps := myersDiff(stdoutLines, resultLines,
|
||||||
|
output.CompareSpace)
|
||||||
if output.MaxDiffLength == 0 { // real default value
|
if output.MaxDiffLength == 0 { // real default value
|
||||||
output.MaxDiffLength = 2048
|
output.MaxDiffLength = 2048
|
||||||
}
|
}
|
||||||
|
@ -108,13 +109,13 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
|
||||||
return res, forceQuit, nil
|
return res, forceQuit, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// compareChars compares two strings character by character, optionally ignoring whitespace.
|
// compareStrings compares two strings character by character, optionally ignoring whitespace.
|
||||||
func compareChars(stdout, result string, compareSpace bool) bool {
|
func compareStrings(str1, str2 string, compareSpace bool) bool {
|
||||||
if !compareSpace {
|
if !compareSpace {
|
||||||
stdout = removeSpace(stdout)
|
str1 = removeSpace(str1)
|
||||||
result = removeSpace(result)
|
str2 = removeSpace(str2)
|
||||||
}
|
}
|
||||||
return stdout == result
|
return str1 == str2
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeSpace removes all whitespace characters from the string.
|
// removeSpace removes all whitespace characters from the string.
|
||||||
|
@ -130,7 +131,7 @@ func removeSpace(s string) string {
|
||||||
|
|
||||||
// myersDiff computes the Myers' diff between two slices of strings.
|
// myersDiff computes the Myers' diff between two slices of strings.
|
||||||
// src: https://github.com/cj1128/myers-diff/blob/master/main.go
|
// src: https://github.com/cj1128/myers-diff/blob/master/main.go
|
||||||
func myersDiff(src, dst []string) []operation {
|
func myersDiff(src, dst []string, compareSpace bool) []operation {
|
||||||
n := len(src)
|
n := len(src)
|
||||||
m := len(dst)
|
m := len(dst)
|
||||||
max := n + m
|
max := n + m
|
||||||
|
@ -144,7 +145,9 @@ loop:
|
||||||
|
|
||||||
if d == 0 {
|
if d == 0 {
|
||||||
t := 0
|
t := 0
|
||||||
for len(src) > t && len(dst) > t && src[t] == dst[t] {
|
for len(src) > t &&
|
||||||
|
len(dst) > t &&
|
||||||
|
compareStrings(src[t], dst[t], compareSpace) {
|
||||||
t += 1
|
t += 1
|
||||||
}
|
}
|
||||||
v[0] = t
|
v[0] = t
|
||||||
|
@ -165,7 +168,7 @@ loop:
|
||||||
|
|
||||||
y = x - k
|
y = x - k
|
||||||
|
|
||||||
for x < n && y < m && src[x] == dst[y] {
|
for x < n && y < m && compareStrings(src[x], dst[y], compareSpace) {
|
||||||
x, y = x+1, y+1
|
x, y = x+1, y+1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user