github.com/cosmos/cosmos-sdk@v0.50.10/x/group/internal/orm/iterator_property_test.go (about) 1 package orm 2 3 import ( 4 "testing" 5 6 "github.com/cosmos/gogoproto/proto" 7 "github.com/stretchr/testify/require" 8 "pgregory.net/rapid" 9 10 errorsmod "cosmossdk.io/errors" 11 12 "github.com/cosmos/cosmos-sdk/testutil/testdata" 13 "github.com/cosmos/cosmos-sdk/types/query" 14 "github.com/cosmos/cosmos-sdk/x/group/errors" 15 ) 16 17 func TestPaginationProperty(t *testing.T) { 18 t.Run("TestPagination", rapid.MakeCheck(func(t *rapid.T) { 19 // Create a slice of group members 20 tableModels := rapid.SliceOf(genTableModel).Draw(t, "tableModels") 21 22 // Choose a random limit for paging 23 upperLimit := uint64(len(tableModels)) 24 if upperLimit == 0 { 25 upperLimit = 1 26 } 27 limit := rapid.Uint64Range(1, upperLimit).Draw(t, "limit") 28 29 // Reconstruct the slice from offset pages 30 reconstructedTableModels := make([]*testdata.TableModel, 0, len(tableModels)) 31 for offset := uint64(0); offset < uint64(len(tableModels)); offset += limit { 32 pageRequest := &query.PageRequest{ 33 Key: nil, 34 Offset: offset, 35 Limit: limit, 36 CountTotal: false, 37 Reverse: false, 38 } 39 end := offset + limit 40 if end > uint64(len(tableModels)) { 41 end = uint64(len(tableModels)) 42 } 43 dest := reconstructedTableModels[offset:end] 44 tableModelsIt := testTableModelIterator(tableModels, nil) 45 Paginate(tableModelsIt, pageRequest, &dest) 46 reconstructedTableModels = append(reconstructedTableModels, dest...) 47 } 48 49 // Should be the same slice 50 require.Equal(t, len(tableModels), len(reconstructedTableModels)) 51 for i, gm := range tableModels { 52 require.Equal(t, *gm, *reconstructedTableModels[i]) 53 } 54 55 // Reconstruct the slice from keyed pages 56 reconstructedTableModels = make([]*testdata.TableModel, 0, len(tableModels)) 57 var start uint64 58 key := EncodeSequence(0) 59 for key != nil { 60 pageRequest := &query.PageRequest{ 61 Key: key, 62 Offset: 0, 63 Limit: limit, 64 CountTotal: false, 65 Reverse: false, 66 } 67 68 end := start + limit 69 if end > uint64(len(tableModels)) { 70 end = uint64(len(tableModels)) 71 } 72 73 dest := reconstructedTableModels[start:end] 74 tableModelsIt := testTableModelIterator(tableModels, key) 75 76 resp, err := Paginate(tableModelsIt, pageRequest, &dest) 77 require.NoError(t, err) 78 key = resp.NextKey 79 80 reconstructedTableModels = append(reconstructedTableModels, dest...) 81 82 start += limit 83 } 84 85 // Should be the same slice 86 require.Equal(t, len(tableModels), len(reconstructedTableModels)) 87 for i, gm := range tableModels { 88 require.Equal(t, *gm, *reconstructedTableModels[i]) 89 } 90 })) 91 } 92 93 func testTableModelIterator(tms []*testdata.TableModel, key RowID) Iterator { 94 var closed bool 95 var index int 96 if key != nil { 97 index = int(DecodeSequence(key)) 98 } 99 return IteratorFunc(func(dest proto.Message) (RowID, error) { 100 if dest == nil { 101 return nil, errorsmod.Wrap(errors.ErrORMInvalidArgument, "destination object must not be nil") 102 } 103 104 if index == len(tms) { 105 closed = true 106 } 107 108 if closed { 109 return nil, errors.ErrORMIteratorDone 110 } 111 112 rowID := EncodeSequence(uint64(index)) 113 114 bytes, err := tms[index].Marshal() 115 if err != nil { 116 return nil, err 117 } 118 119 index++ 120 121 return rowID, proto.Unmarshal(bytes, dest) 122 }) 123 }