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  }