cosmos-sdk/collections/indexes/multi_test.go

113 lines
3.5 KiB
Go

package indexes
import (
"testing"
"github.com/stretchr/testify/require"
"cosmossdk.io/collections"
)
func TestMultiIndex(t *testing.T) {
sk, ctx := deps()
schema := collections.NewSchemaBuilder(sk)
mi := NewMulti(schema, collections.NewPrefix(1), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
return value.City, nil
})
// we create two reference keys for primary key 1 and 2 associated with "milan"
require.NoError(t, mi.Reference(ctx, 1, company{City: "milan"}, func() (company, error) { return company{}, collections.ErrNotFound }))
require.NoError(t, mi.Reference(ctx, 2, company{City: "milan"}, func() (company, error) { return company{}, collections.ErrNotFound }))
iter, err := mi.MatchExact(ctx, "milan")
require.NoError(t, err)
pks, err := iter.PrimaryKeys()
require.NoError(t, err)
require.Equal(t, []uint64{1, 2}, pks)
// replace
require.NoError(t, mi.Reference(ctx, 1, company{City: "new york"}, func() (company, error) { return company{City: "milan"}, nil }))
// assert after replace only company with id 2 is referenced by milan
iter, err = mi.MatchExact(ctx, "milan")
require.NoError(t, err)
pks, err = iter.PrimaryKeys()
require.NoError(t, err)
require.Equal(t, []uint64{2}, pks)
// assert after replace company with id 1 is referenced by new york
iter, err = mi.MatchExact(ctx, "new york")
require.NoError(t, err)
pks, err = iter.PrimaryKeys()
require.NoError(t, err)
require.Equal(t, []uint64{1}, pks)
// test iter methods
iter, err = mi.Iterate(ctx, nil)
require.NoError(t, err)
fullKey, err := iter.FullKey()
require.NoError(t, err)
require.Equal(t, collections.Join("milan", uint64(2)), fullKey)
pk, err := iter.PrimaryKey()
require.NoError(t, err)
require.Equal(t, uint64(2), pk)
iter.Next()
require.True(t, iter.Valid())
iter.Next()
require.False(t, iter.Valid())
require.NoError(t, iter.Close())
}
func TestMultiUnchecked(t *testing.T) {
sk, ctx := deps()
schema := collections.NewSchemaBuilder(sk)
uncheckedMi := NewMulti(schema, collections.NewPrefix("prefix"), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
return value.City, nil
}, WithMultiUncheckedValue())
mi := NewMulti(schema, collections.NewPrefix("prefix"), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) {
return value.City, nil
})
rawKey, err := collections.EncodeKeyWithPrefix(
collections.NewPrefix("prefix"),
uncheckedMi.KeyCodec(),
collections.Join("milan", uint64(2)))
require.NoError(t, err)
// set value to be something different from []byte{}
require.NoError(t, sk.OpenKVStore(ctx).Set(rawKey, []byte("something")))
// normal multi index will fail.
err = mi.Walk(ctx, nil, func(indexingKey string, indexedKey uint64) (stop bool, err error) {
return true, err
})
require.ErrorIs(t, err, collections.ErrEncoding)
// unchecked multi index will not fail.
err = uncheckedMi.Walk(ctx, nil, func(indexingKey string, indexedKey uint64) (stop bool, err error) {
require.Equal(t, "milan", indexingKey)
require.Equal(t, uint64(2), indexedKey)
return true, err
})
require.NoError(t, err)
// unchecked multi will also reset the value
err = mi.Reference(ctx, 2, company{City: "milan"}, func() (company, error) {
return company{
City: "milan",
}, nil
})
require.NoError(t, err)
// value reset to []byte{}
rawValue, err := sk.OpenKVStore(ctx).Get(rawKey)
require.NoError(t, err)
require.Equal(t, []byte{}, rawValue)
}