test(parser/diff): add myers diff test
All checks were successful
submodules sync / sync (push) Successful in 43s
build / build (push) Successful in 1m32s
build / trigger-build-image (push) Successful in 8s

This commit is contained in:
张泊明518370910136 2024-11-16 03:07:12 -05:00
parent 60d9e1b215
commit b8c233b1bb
GPG Key ID: D47306D7062CDA9D
2 changed files with 82 additions and 10 deletions

View 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)
}
})
}
}

View File

@ -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
} }