cosmos-sdk/schema/testing/statesim/object_coll_diff.go
Aaron Craelius e7844e640c
feat(schema): testing utilities (#20705)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-07-31 06:58:30 +00:00

76 lines
2.5 KiB
Go

package statesim
import (
"fmt"
"strings"
"cosmossdk.io/schema"
schematesting "cosmossdk.io/schema/testing"
)
// ObjectCollectionState is the interface for the state of an object collection
// represented by ObjectUpdate's for an ObjectType. ObjectUpdates must not include
// ValueUpdates in the Value field. When ValueUpdates are applied they must be
// converted to individual value or array format depending on the number of fields in
// the value. For collections which retain deletions, ObjectUpdate's with the Delete
// field set to true should be returned with the latest Value still intact.
type ObjectCollectionState interface {
// ObjectType returns the object type for the collection.
ObjectType() schema.ObjectType
// GetObject returns the object update for the given key if it exists.
GetObject(key any) (update schema.ObjectUpdate, found bool)
// AllState iterates over the state of the collection by calling the given function with each item in
// state represented as an object update.
AllState(f func(schema.ObjectUpdate) bool)
// Len returns the number of objects in the collection.
Len() int
}
// DiffObjectCollections compares the object collection state of two objects that implement ObjectCollectionState and returns a string with a diff if they
// are different or the empty string if they are the same.
func DiffObjectCollections(expected, actual ObjectCollectionState) string {
res := ""
if expected.Len() != actual.Len() {
res += fmt.Sprintf("OBJECT COUNT ERROR: expected %d, got %d\n", expected.Len(), actual.Len())
}
expected.AllState(func(expectedUpdate schema.ObjectUpdate) bool {
actualUpdate, found := actual.GetObject(expectedUpdate.Key)
if !found {
res += fmt.Sprintf("Object %s: NOT FOUND\n", fmtObjectKey(expected.ObjectType(), expectedUpdate.Key))
return true
}
if expectedUpdate.Delete != actualUpdate.Delete {
res += fmt.Sprintf("Object %s: Deleted mismatch, expected %v, got %v\n", fmtObjectKey(expected.ObjectType(), expectedUpdate.Key), expectedUpdate.Delete, actualUpdate.Delete)
}
if expectedUpdate.Delete {
return true
}
valueDiff := schematesting.DiffObjectValues(expected.ObjectType().ValueFields, expectedUpdate.Value, actualUpdate.Value)
if valueDiff != "" {
res += "Object "
res += fmtObjectKey(expected.ObjectType(), expectedUpdate.Key)
res += "\n"
res += indentAllLines(valueDiff)
}
return true
})
return res
}
func indentAllLines(s string) string {
lines := strings.Split(s, "\n")
for i, line := range lines {
lines[i] = " " + line
}
return strings.Join(lines, "\n")
}