github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/keyspan/bounded_test.go (about) 1 // Copyright 2022 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package keyspan 6 7 import ( 8 "bytes" 9 "fmt" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 "github.com/zuoyebang/bitalostable/internal/datadriven" 15 "github.com/zuoyebang/bitalostable/internal/testkeys" 16 ) 17 18 func TestBoundedIter(t *testing.T) { 19 getBounds := func(td *datadriven.TestData) (lower, upper []byte) { 20 for _, cmdArg := range td.CmdArgs { 21 switch cmdArg.Key { 22 case "lower": 23 if len(cmdArg.Vals[0]) > 0 { 24 lower = []byte(cmdArg.Vals[0]) 25 } 26 case "upper": 27 if len(cmdArg.Vals[0]) > 0 { 28 upper = []byte(cmdArg.Vals[0]) 29 } 30 } 31 } 32 return lower, upper 33 } 34 35 cmp := testkeys.Comparer.Compare 36 split := testkeys.Comparer.Split 37 var buf bytes.Buffer 38 var iter BoundedIter 39 var hasPrefix bool 40 var prefix []byte 41 datadriven.RunTest(t, "testdata/bounded_iter", func(td *datadriven.TestData) string { 42 switch td.Cmd { 43 case "define": 44 var spans []Span 45 lines := strings.Split(strings.TrimSpace(td.Input), "\n") 46 for _, line := range lines { 47 spans = append(spans, ParseSpan(line)) 48 } 49 inner := &invalidatingIter{iter: NewIter(cmp, spans)} 50 lower, upper := getBounds(td) 51 iter.Init(cmp, split, inner, lower, upper, &hasPrefix, &prefix) 52 return "" 53 case "set-prefix": 54 hasPrefix = len(td.CmdArgs) > 0 55 if hasPrefix { 56 prefix = []byte(td.CmdArgs[0].String()) 57 return fmt.Sprintf("set prefix to %q\n", prefix) 58 } 59 return "cleared prefix" 60 case "iter": 61 buf.Reset() 62 lower, upper := getBounds(td) 63 iter.SetBounds(lower, upper) 64 65 lines := strings.Split(strings.TrimSpace(td.Input), "\n") 66 for _, line := range lines { 67 line = strings.TrimSpace(line) 68 i := strings.IndexByte(line, ' ') 69 iterCmd := line 70 if i > 0 { 71 iterCmd = string(line[:i]) 72 } 73 switch iterCmd { 74 case "first": 75 fmt.Fprintln(&buf, iter.First()) 76 case "last": 77 fmt.Fprintln(&buf, iter.Last()) 78 case "next": 79 fmt.Fprintln(&buf, iter.Next()) 80 case "prev": 81 fmt.Fprintln(&buf, iter.Prev()) 82 case "seek-ge": 83 fmt.Fprintln(&buf, iter.SeekGE([]byte(strings.TrimSpace(line[i:])))) 84 case "seek-lt": 85 fmt.Fprintln(&buf, iter.SeekLT([]byte(strings.TrimSpace(line[i:])))) 86 default: 87 return fmt.Sprintf("unrecognized iter command %q", iterCmd) 88 } 89 require.NoError(t, iter.Error()) 90 } 91 return strings.TrimSpace(buf.String()) 92 default: 93 return fmt.Sprintf("unrecognized command %q", td.Cmd) 94 } 95 }) 96 }