差分包提供了用于生成、比较和可视化预期值与实际值之间差异的工具。该工具专为测试场景设计,但也可在需要差异可视化的任何场景中使用。
差分包借助 go-cmp 实现泛型类型比较,支持字符串基于统一差分格式的对比,还能提供字符级别的详细文本比较功能。它可处理多种 Go 类型,包括结构体、映射和基础类型,通过反射实现复杂类型的比较。
该包按以下模块组织:
diff.go):主要接口和特定类型差异生成udiff.go):统一差分解析与格式化实现enrich.go):用于提升差异输出的颜色与格式convoluted.go):负责 Go 类型和值的格式化比较testing.go):适用于测试场景的功能实现该包设计允许用户通过实现以下接口或添加选项来自定义行为:
diff.Comparator 接口以自定义比较逻辑。diff.WithOptions 方法来配置特定的差异生成参数。TypedDiff。RequireEqual 并结合选项处理未导出字段。// 使用 WithUnexportedType 选项显式比较私有字段
diff.RequireEqual(t, a, b, diff.WithUnexportedType[type](...))
type MyComparator struct{}
func (MyComparator) Compare(a, b interface{}) string {
// 自定义比较实现
}
// 注册自定义比较器
diff.Register(diff.KeyType(reflect.TypeOf(a)), &MyComparator{})
尽管推荐使用新方法,但包仍支持以下旧函数以确保向后兼容:
diff.Show()diff.DiffString()这些旧函数已逐步弃用,建议在新项目中优先采用最新接口。
package main
import (
"fmt"
"github.com/walteh/cloudstack-mcp/pkg/diff"
)
func main() {
expected := "Hello, World!"
actual := "Hello, Universe!"
// 生成两个字符串之间的差异
result := diff.TypedDiff(expected, actual)
// 打印差异结果
fmt.Println(result)
}
package mypackage_test
import (
"testing"
"github.com/walteh/cloudstack-mcp/pkg/diff"
)
func TestSomething(t *testing.T) {
expected := map[string]int{"a": 1, "b": 2}
actual := map[string]int{"a": 1, "b": 3}
// 比较值并根据不匹配的结果进行测试失败
diff.RequireEqual(t, expected, actual)
}
package mypackage_test
import (
"reflect"
"testing"
"github.com/walteh/cloudstack-mcp/pkg/diff"
)
type MyStruct struct {
Name string
Age int
private string
}
func TestStructComparison(t *testing.T) {
s1 := MyStruct{Name: "Alice", Age: 30, private: "secret"}
s2 := MyStruct{Name: "Alice", Age: 31, private: "secret"}
// 比较包含未导出字段的结构体
diff.RequireEqual(t, s1, s2, diff.WithUnexportedType[MyStruct]())
}
package main
import (
"fmt"
"github.com/walteh/cloudstack-mcp/pkg/diff"
)
func main() {
str1 := "Hello"
str2 := "World"
// 对比两个字符串的字符差异
diff.Show(str1, str2)
}