github.com/square/finch@v0.0.0-20240412205204-6530c03e2b96/data/integer_test.go (about) 1 // Copyright 2024 Block, Inc. 2 3 package data_test 4 5 import ( 6 "sort" 7 "testing" 8 9 "github.com/go-test/deep" 10 11 "github.com/square/finch" 12 "github.com/square/finch/data" 13 ) 14 15 func TestInteger_Int(t *testing.T) { 16 finch.Debugging = true 17 g, _ := data.NewInt(map[string]string{ 18 "max": "1000", 19 }) 20 r := data.RunCount{} 21 22 got := []int{} 23 for i := 0; i < 1000; i++ { 24 v1 := g.Values(r) 25 if len(v1) != 1 { 26 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 27 } 28 got = append(got, int(v1[0].(int64))) 29 } 30 sort.Ints(got) 31 n := got[0] 32 if n < 1 { 33 t.Errorf("lower bound < 1: %v", n) 34 } 35 n = got[len(got)-1] // amx 36 if n > 1000 { 37 t.Errorf("upper bound > max 1000: %v", n) 38 } 39 40 // Copy should be identical except Id 41 deep.CompareUnexportedFields = true 42 c := g.Copy() 43 if diff := deep.Equal(g, c); diff != nil { 44 t.Error(diff) 45 } 46 deep.CompareUnexportedFields = false 47 } 48 49 func TestInteger_AutoInc(t *testing.T) { 50 g, _ := data.NewAutoInc(nil) 51 r := data.RunCount{} 52 53 for i := 1; i <= 3; i++ { // 1, 2, 3 54 v1 := g.Values(r) 55 if len(v1) != 1 { 56 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 57 } 58 s1 := v1[0].(uint64) 59 if s1 != uint64(i) { 60 t.Errorf("got %v, expected %d", v1[0], i) 61 } 62 } 63 64 // start=5: first value is 5+1 (6), then 6+1 (7) 65 g, _ = data.NewAutoInc(map[string]string{"start": "5"}) 66 for i := 6; i <= 7; i++ { // 6, 7 67 v1 := g.Values(r) 68 if len(v1) != 1 { 69 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 70 } 71 s1 := v1[0].(uint64) 72 if s1 != uint64(i) { 73 t.Errorf("got %v, expected %d", v1[0], i) 74 } 75 } 76 77 // step=2 78 g, _ = data.NewAutoInc(map[string]string{"step": "2"}) 79 for i := 1; i <= 2; i++ { // 2, 4 80 v1 := g.Values(r) 81 if len(v1) != 1 { 82 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 83 } 84 s1 := v1[0].(uint64) 85 if s1 != (uint64(i) * 2) { 86 t.Errorf("got %v, expected %d", v1[0], i*2) 87 } 88 } 89 90 // start=10 step=2 91 g, _ = data.NewAutoInc(map[string]string{"start": "10", "step": "2"}) 92 for _, i := range []uint64{12, 14} { 93 v1 := g.Values(r) 94 if len(v1) != 1 { 95 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 96 } 97 s1 := v1[0].(uint64) 98 if s1 != i { 99 t.Errorf("got %v, expected %d", v1[0], i) 100 } 101 } 102 } 103 104 func TestInteger_IntRange(t *testing.T) { 105 // Default is [1, 100000] with size 100 106 g, _ := data.NewIntRange(map[string]string{}) 107 r := data.RunCount{} 108 109 got := [][]int64{} 110 for i := 0; i < 1000; i++ { 111 v1 := g.Values(r) 112 if len(v1) != 2 { 113 t.Fatalf("got %d values, expected 2: %v", len(v1), v1) 114 } 115 got = append(got, []int64{v1[0].(int64), v1[1].(int64)}) 116 } 117 for _, pair := range got { 118 if pair[1] <= pair[0] { 119 t.Errorf("pair not ordered: %v", pair) 120 } 121 if pair[0] < 1 { 122 t.Errorf("lower bound < 1: %v", pair) 123 } 124 if pair[1] > finch.ROWS { 125 t.Errorf("upper bound > %d: %v", finch.ROWS, pair) 126 } 127 if n := pair[1] - pair[0] + 1; n < 1 || n > 100 { 128 t.Errorf("range %d, expected 100 or less: %v", n, pair) 129 } 130 } 131 } 132 133 func TestInteger_IntRangeSeq(t *testing.T) { 134 g, _ := data.NewIntRangeSeq(map[string]string{ 135 "begin": "1", 136 "end": "9", 137 "size": "3", 138 }) 139 r := data.RunCount{} 140 141 got := [][]int64{} 142 for i := 0; i < 4; i++ { 143 v1 := g.Values(r) 144 if len(v1) != 2 { 145 t.Fatalf("got %d values, expected 2: %v", len(v1), v1) 146 } 147 got = append(got, []int64{v1[0].(int64), v1[1].(int64)}) 148 } 149 expect := [][]int64{ 150 {1, 3}, 151 {4, 6}, 152 {7, 9}, 153 {1, 3}, 154 } 155 if diff := deep.Equal(got, expect); diff != nil { 156 t.Error(diff) 157 t.Errorf("%+v", got) 158 } 159 160 // Short chunk at end 161 g, _ = data.NewIntRangeSeq(map[string]string{ 162 "begin": "1", 163 "end": "9", 164 "size": "4", 165 }) 166 got = [][]int64{} 167 for i := 0; i < 4; i++ { 168 v1 := g.Values(r) 169 if len(v1) != 2 { 170 t.Fatalf("got %d values, expected 2: %v", len(v1), v1) 171 } 172 got = append(got, []int64{v1[0].(int64), v1[1].(int64)}) 173 } 174 expect = [][]int64{ 175 {1, 4}, 176 {5, 8}, 177 {9, 9}, // short chunk 178 {1, 4}, 179 } 180 if diff := deep.Equal(got, expect); diff != nil { 181 t.Error(diff) 182 t.Errorf("%+v", got) 183 } 184 } 185 186 func TestInteger_IntGaps(t *testing.T) { 187 g, err := data.NewIntGaps(map[string]string{ 188 "min": "1", 189 "max": "100", 190 "p": "20", // percent 191 }) 192 if err != nil { 193 t.Fatal(err) 194 } 195 r := data.RunCount{} 196 v := map[int64]bool{} 197 for i := 0; i < 1000; i++ { 198 v1 := g.Values(r) 199 if len(v1) != 1 { 200 t.Fatalf("got %d values, expected 1: %v", len(v1), v1) 201 } 202 v[v1[0].(int64)] = true 203 } 204 got := make([]int, 0, len(v)) 205 for k := range v { 206 got = append(got, int(k)) 207 } 208 sort.Ints(got) 209 expect := []int{1, 6, 11, 16, 21, 27, 32, 37, 42, 47, 53, 58, 63, 68, 73, 79, 84, 89, 94, 100} 210 if diff := deep.Equal(got, expect); diff != nil { 211 t.Errorf("%v: %v", diff, got) 212 } 213 if len(v) < 19 || len(v) > 21 { 214 t.Errorf("got %d unique values, expected 19, 20, or 21 (20%% of 100)", len(v)) 215 } 216 }