github.com/cosmos/cosmos-sdk@v0.50.10/types/query/collections_pagination_test.go (about) 1 package query 2 3 import ( 4 "context" 5 "testing" 6 7 db "github.com/cosmos/cosmos-db" 8 "github.com/stretchr/testify/require" 9 10 "cosmossdk.io/collections" 11 "cosmossdk.io/core/store" 12 ) 13 14 func TestCollectionPagination(t *testing.T) { 15 sk, ctx := deps() 16 sb := collections.NewSchemaBuilder(sk) 17 m := collections.NewMap(sb, collections.NewPrefix(0), "_", collections.Uint64Key, collections.Uint64Value) 18 19 for i := uint64(0); i < 300; i++ { 20 require.NoError(t, m.Set(ctx, i, i)) 21 } 22 23 createResults := func(from, to uint64) []collections.KeyValue[uint64, uint64] { 24 var res []collections.KeyValue[uint64, uint64] 25 if from <= to { 26 for i := from; i <= to; i++ { 27 res = append(res, collections.KeyValue[uint64, uint64]{ 28 Key: i, 29 Value: i, 30 }) 31 } 32 } else { 33 for i := from; i >= to; i-- { 34 res = append(res, collections.KeyValue[uint64, uint64]{ 35 Key: i, 36 Value: i, 37 }) 38 } 39 } 40 return res 41 } 42 43 encodeKey := func(key uint64) []byte { 44 b, err := encodeCollKey[uint64, uint64](m, key) 45 require.NoError(t, err) 46 return b 47 } 48 49 type test struct { 50 req *PageRequest 51 expResp *PageResponse 52 filter func(key, value uint64) (bool, error) 53 expResults []collections.KeyValue[uint64, uint64] 54 wantErr error 55 } 56 57 tcs := map[string]test{ 58 "nil pagination": { 59 req: nil, 60 expResp: &PageResponse{ 61 NextKey: encodeKey(100), 62 Total: 300, 63 }, 64 expResults: createResults(0, 99), 65 }, 66 "with key and limit": { 67 req: &PageRequest{ 68 Key: encodeKey(100), 69 Limit: 149, 70 }, 71 expResp: &PageResponse{ 72 NextKey: encodeKey(249), 73 }, 74 expResults: createResults(100, 248), 75 }, 76 "with reverse": { 77 req: &PageRequest{ 78 Reverse: true, 79 }, 80 expResp: &PageResponse{ 81 NextKey: encodeKey(199), 82 Total: 300, 83 }, 84 expResults: createResults(299, 200), 85 }, 86 "with key and reverse": { 87 req: &PageRequest{ 88 Key: encodeKey(199), 89 Reverse: true, 90 }, 91 expResp: &PageResponse{ 92 NextKey: encodeKey(99), 93 }, 94 expResults: createResults(199, 100), 95 }, 96 "with offset and count total": { 97 req: &PageRequest{ 98 Offset: 50, 99 Limit: 100, 100 CountTotal: true, 101 }, 102 expResp: &PageResponse{ 103 NextKey: encodeKey(150), 104 Total: 300, 105 }, 106 expResults: createResults(50, 149), 107 }, 108 "filtered no key": { 109 req: &PageRequest{ 110 Limit: 3, 111 }, 112 expResp: &PageResponse{ 113 NextKey: encodeKey(5), 114 }, 115 filter: func(key, value uint64) (bool, error) { 116 return key%2 == 0, nil 117 }, 118 expResults: []collections.KeyValue[uint64, uint64]{ 119 {Key: 0, Value: 0}, 120 {Key: 2, Value: 2}, 121 {Key: 4, Value: 4}, 122 }, 123 }, 124 "filtered with key": { 125 req: &PageRequest{ 126 Key: encodeKey(2), 127 Limit: 3, 128 }, 129 expResp: &PageResponse{ 130 NextKey: encodeKey(5), 131 }, 132 filter: func(key, value uint64) (bool, error) { 133 return key%2 == 0, nil 134 }, 135 expResults: []collections.KeyValue[uint64, uint64]{ 136 {Key: 2, Value: 2}, 137 {Key: 4, Value: 4}, 138 }, 139 }, 140 } 141 142 for name, tc := range tcs { 143 tc := tc 144 t.Run(name, func(t *testing.T) { 145 gotResults, gotResponse, err := CollectionFilteredPaginate( 146 ctx, 147 m, 148 tc.req, 149 tc.filter, 150 func(key, value uint64) (collections.KeyValue[uint64, uint64], error) { 151 return collections.KeyValue[uint64, uint64]{Key: key, Value: value}, nil 152 }, 153 ) 154 if tc.wantErr != nil { 155 require.ErrorIs(t, err, tc.wantErr) 156 return 157 } 158 require.NoError(t, err) 159 require.Equal(t, tc.expResults, gotResults) 160 require.Equal(t, tc.expResp, gotResponse) 161 }) 162 } 163 } 164 165 type testStore struct { 166 db db.DB 167 } 168 169 func (t testStore) OpenKVStore(ctx context.Context) store.KVStore { 170 return t 171 } 172 173 func (t testStore) Get(key []byte) ([]byte, error) { 174 return t.db.Get(key) 175 } 176 177 func (t testStore) Has(key []byte) (bool, error) { 178 return t.db.Has(key) 179 } 180 181 func (t testStore) Set(key, value []byte) error { 182 return t.db.Set(key, value) 183 } 184 185 func (t testStore) Delete(key []byte) error { 186 return t.db.Delete(key) 187 } 188 189 func (t testStore) Iterator(start, end []byte) (store.Iterator, error) { 190 return t.db.Iterator(start, end) 191 } 192 193 func (t testStore) ReverseIterator(start, end []byte) (store.Iterator, error) { 194 return t.db.ReverseIterator(start, end) 195 } 196 197 var _ store.KVStore = testStore{} 198 199 func deps() (store.KVStoreService, context.Context) { 200 kv := db.NewMemDB() 201 return &testStore{kv}, context.Background() 202 }