122 lines
3.2 KiB
Go
122 lines
3.2 KiB
Go
package orm
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/types/query"
|
|
"github.com/cosmos/cosmos-sdk/x/group/errors"
|
|
"github.com/stretchr/testify/require"
|
|
"pgregory.net/rapid"
|
|
)
|
|
|
|
func TestPaginationProperty(t *testing.T) {
|
|
t.Run("TestPagination", rapid.MakeCheck(func(t *rapid.T) {
|
|
// Create a slice of group members
|
|
tableModels := rapid.SliceOf(genTableModel).Draw(t, "tableModels").([]*testdata.TableModel)
|
|
|
|
// Choose a random limit for paging
|
|
upperLimit := uint64(len(tableModels))
|
|
if upperLimit == 0 {
|
|
upperLimit = 1
|
|
}
|
|
limit := rapid.Uint64Range(1, upperLimit).Draw(t, "limit").(uint64)
|
|
|
|
// Reconstruct the slice from offset pages
|
|
reconstructedTableModels := make([]*testdata.TableModel, 0, len(tableModels))
|
|
for offset := uint64(0); offset < uint64(len(tableModels)); offset += limit {
|
|
pageRequest := &query.PageRequest{
|
|
Key: nil,
|
|
Offset: offset,
|
|
Limit: limit,
|
|
CountTotal: false,
|
|
Reverse: false,
|
|
}
|
|
end := offset + limit
|
|
if end > uint64(len(tableModels)) {
|
|
end = uint64(len(tableModels))
|
|
}
|
|
dest := reconstructedTableModels[offset:end]
|
|
tableModelsIt := testTableModelIterator(tableModels, nil)
|
|
Paginate(tableModelsIt, pageRequest, &dest)
|
|
reconstructedTableModels = append(reconstructedTableModels, dest...)
|
|
}
|
|
|
|
// Should be the same slice
|
|
require.Equal(t, len(tableModels), len(reconstructedTableModels))
|
|
for i, gm := range tableModels {
|
|
require.Equal(t, *gm, *reconstructedTableModels[i])
|
|
}
|
|
|
|
// Reconstruct the slice from keyed pages
|
|
reconstructedTableModels = make([]*testdata.TableModel, 0, len(tableModels))
|
|
var start uint64 = 0
|
|
key := EncodeSequence(0)
|
|
for key != nil {
|
|
pageRequest := &query.PageRequest{
|
|
Key: key,
|
|
Offset: 0,
|
|
Limit: limit,
|
|
CountTotal: false,
|
|
Reverse: false,
|
|
}
|
|
|
|
end := start + limit
|
|
if end > uint64(len(tableModels)) {
|
|
end = uint64(len(tableModels))
|
|
}
|
|
|
|
dest := reconstructedTableModels[start:end]
|
|
tableModelsIt := testTableModelIterator(tableModels, key)
|
|
|
|
resp, err := Paginate(tableModelsIt, pageRequest, &dest)
|
|
require.NoError(t, err)
|
|
key = resp.NextKey
|
|
|
|
reconstructedTableModels = append(reconstructedTableModels, dest...)
|
|
|
|
start += limit
|
|
}
|
|
|
|
// Should be the same slice
|
|
require.Equal(t, len(tableModels), len(reconstructedTableModels))
|
|
for i, gm := range tableModels {
|
|
require.Equal(t, *gm, *reconstructedTableModels[i])
|
|
}
|
|
}))
|
|
}
|
|
|
|
func testTableModelIterator(tms []*testdata.TableModel, key RowID) Iterator {
|
|
var closed bool
|
|
var index int
|
|
if key != nil {
|
|
index = int(DecodeSequence(key))
|
|
}
|
|
return IteratorFunc(func(dest codec.ProtoMarshaler) (RowID, error) {
|
|
if dest == nil {
|
|
return nil, sdkerrors.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil")
|
|
}
|
|
|
|
if index == len(tms) {
|
|
closed = true
|
|
}
|
|
|
|
if closed {
|
|
return nil, errors.ErrORMIteratorDone
|
|
}
|
|
|
|
rowID := EncodeSequence(uint64(index))
|
|
|
|
bytes, err := tms[index].Marshal()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
index++
|
|
|
|
return rowID, dest.Unmarshal(bytes)
|
|
})
|
|
}
|