Skip to content

Commit

Permalink
fix(schema/testing): proper integer and decimal comparison (#21241)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc authored Aug 14, 2024
1 parent 7f1dd97 commit cacea0f
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
35 changes: 35 additions & 0 deletions schema/testing/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package schematesting
import (
"bytes"
"fmt"
"math/big"

"github.com/cockroachdb/apd/v3"

"cosmossdk.io/schema"
)
Expand Down Expand Up @@ -77,6 +80,8 @@ func DiffFieldValues(field schema.Field, expected, actual any) string {

// CompareKindValues compares the expected and actual values for the provided kind and returns true if they are equal,
// false if they are not, and an error if the types are not valid for the kind.
// For IntegerStringKind and DecimalStringKind values, comparisons are made based on equality of the underlying numeric
// values rather than their string encoding.
func CompareKindValues(kind schema.Kind, expected, actual any) (bool, error) {
if kind.ValidateValueType(expected) != nil {
return false, fmt.Errorf("unexpected type %T for kind %s", expected, kind)
Expand All @@ -91,6 +96,36 @@ func CompareKindValues(kind schema.Kind, expected, actual any) (bool, error) {
if !bytes.Equal(expected.([]byte), actual.([]byte)) {
return false, nil
}
case schema.IntegerStringKind:
expectedInt := big.NewInt(0)
expectedInt, ok := expectedInt.SetString(expected.(string), 10)
if !ok {
return false, fmt.Errorf("could not convert %v to big.Int", expected)
}

actualInt := big.NewInt(0)
actualInt, ok = actualInt.SetString(actual.(string), 10)
if !ok {
return false, fmt.Errorf("could not convert %v to big.Int", actual)
}

if expectedInt.Cmp(actualInt) != 0 {
return false, nil
}
case schema.DecimalStringKind:
expectedDec, _, err := apd.NewFromString(expected.(string))
if err != nil {
return false, fmt.Errorf("could not decode %v as a decimal: %w", expected, err)
}

actualDec, _, err := apd.NewFromString(actual.(string))
if err != nil {
return false, fmt.Errorf("could not decode %v as a decimal: %w", actual, err)
}

if expectedDec.Cmp(actualDec) != 0 {
return false, nil
}
default:
if expected != actual {
return false, nil
Expand Down
111 changes: 111 additions & 0 deletions schema/testing/diff_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package schematesting

import (
"testing"

"cosmossdk.io/schema"
)

func TestCompareKindValues(t *testing.T) {
tt := []struct {
kind schema.Kind
expected any
actual any
equal bool
expectError bool
}{
{
kind: schema.BoolKind,
expected: "true",
actual: false,
expectError: true,
},
{
kind: schema.BoolKind,
expected: true,
actual: "false",
expectError: true,
},
{
kind: schema.BoolKind,
expected: true,
actual: false,
equal: false,
},
{
kind: schema.BoolKind,
expected: true,
actual: true,
equal: true,
},
{
kind: schema.BytesKind,
expected: []byte("hello"),
actual: []byte("world"),
equal: false,
},
{
kind: schema.IntegerStringKind,
expected: "a123",
actual: "123",
expectError: true,
},
{
kind: schema.IntegerStringKind,
expected: "123",
actual: "123b",
expectError: true,
},
{
kind: schema.IntegerStringKind,
expected: "123",
actual: "1234",
equal: false,
},
{
kind: schema.IntegerStringKind,
expected: "000123",
actual: "123",
equal: true,
},
{
kind: schema.DecimalStringKind,
expected: "abc",
actual: "100.001",
expectError: true,
},
{
kind: schema.DecimalStringKind,
expected: "1",
actual: "b",
expectError: true,
},
{
kind: schema.DecimalStringKind,
expected: "1.00001",
actual: "100.001",
equal: false,
},
{
kind: schema.DecimalStringKind,
expected: "1.00001e2",
actual: "100.001",
equal: true,
},
{
kind: schema.DecimalStringKind,
expected: "00000100.00100000",
actual: "100.001",
equal: true,
},
}
for _, tc := range tt {
eq, err := CompareKindValues(tc.kind, tc.expected, tc.actual)
if eq != tc.equal {
t.Errorf("expected %v, got %v", tc.equal, eq)
}
if (err != nil) != tc.expectError {
t.Errorf("expected error: %v, got %v", tc.expectError, err)
}
}
}
1 change: 1 addition & 0 deletions schema/testing/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module cosmossdk.io/schema/testing

require (
cosmossdk.io/schema v0.0.0
github.com/cockroachdb/apd/v3 v3.2.1
github.com/stretchr/testify v1.9.0
github.com/tidwall/btree v1.7.0
gotest.tools/v3 v3.5.1
Expand Down
4 changes: 4 additions & 0 deletions schema/testing/go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
Expand Down

0 comments on commit cacea0f

Please sign in to comment.