github.com/go-kivik/kivik/v4@v4.3.2/iterator_test.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 package kivik 14 15 import ( 16 "context" 17 "fmt" 18 "io" 19 "testing" 20 "time" 21 22 "gitlab.com/flimzy/testy" 23 ) 24 25 type TestFeed struct { 26 max int64 27 i int64 28 closeErr error 29 } 30 31 var _ iterator = &TestFeed{} 32 33 func (f *TestFeed) Close() error { return f.closeErr } 34 func (f *TestFeed) Next(ifce interface{}) error { 35 i, ok := ifce.(*int64) 36 if ok { 37 *i = f.i 38 f.i++ 39 if f.i > f.max { 40 return io.EOF 41 } 42 time.Sleep(5 * time.Millisecond) 43 return nil 44 } 45 panic(fmt.Sprintf("unknown type: %T", ifce)) 46 } 47 48 func TestIterator(t *testing.T) { 49 iter := newIterator(context.Background(), nil, &TestFeed{max: 10}, func() interface{} { var i int64; return &i }()) 50 expected := []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 51 result := []int64{} 52 for iter.Next() { 53 val, ok := iter.curVal.(*int64) 54 if !ok { 55 panic("Unexpected type") 56 } 57 result = append(result, *val) 58 } 59 if err := iter.Err(); err != nil { 60 t.Errorf("Unexpected error: %s", err) 61 } 62 if d := testy.DiffAsJSON(expected, result); d != nil { 63 t.Errorf("Unexpected result:\n%s\n", d) 64 } 65 } 66 67 func TestCancelledIterator(t *testing.T) { 68 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) 69 defer cancel() 70 iter := newIterator(ctx, nil, &TestFeed{max: 10000}, func() interface{} { var i int64; return &i }()) 71 for iter.Next() { //nolint:revive // empty block necessary for loop 72 } 73 if err := iter.Err(); err.Error() != "context deadline exceeded" { 74 t.Errorf("Unexpected error: %s", err) 75 } 76 } 77 78 func Test_iter_isReady(t *testing.T) { 79 tests := []struct { 80 name string 81 iter *iter 82 err string 83 }{ 84 { 85 name: "not ready", 86 iter: &iter{}, 87 err: "kivik: Iterator access before calling Next", 88 }, 89 { 90 name: "closed", 91 iter: &iter{state: stateClosed}, 92 err: "kivik: Iterator is closed", 93 }, 94 { 95 name: "success", 96 iter: &iter{state: stateRowReady}, 97 }, 98 } 99 for _, test := range tests { 100 t.Run(test.name, func(t *testing.T) { 101 err := test.iter.isReady() 102 if !testy.ErrorMatches(test.err, err) { 103 t.Errorf("Unexpected error: %s", err) 104 } 105 }) 106 } 107 }