package field import ( "fmt" "math/rand" "testing" "time" "github.com/tidwall/assert" "github.com/tidwall/btree" ) func TestList(t *testing.T) { var fields List fields = fields.Set(Make("hello", "123")) assert.Assert(fields.Len() == 1) // println(fields.Weight()) // assert.Assert(fields.Weight() == 16) fields = fields.Set(Make("jello", "456")) assert.Assert(fields.Len() == 2) // assert.Assert(fields.Weight() == 32) value := fields.Get("jello") assert.Assert(value.Value().Data() == "456") assert.Assert(value.Value().JSON() == "456") assert.Assert(value.Value().Num() == 456) value = fields.Get("nello") assert.Assert(value.Name() == "") assert.Assert(value.Value().IsZero()) fields = fields.Set(Make("jello", "789")) assert.Assert(fields.Len() == 2) // assert.Assert(fields.Weight() == 32) fields = fields.Set(Make("nello", "0")) assert.Assert(fields.Len() == 2) // assert.Assert(fields.Weight() == 32) fields = fields.Set(Make("jello", "789")) assert.Assert(fields.Len() == 2) // assert.Assert(fields.Weight() == 32) fields = fields.Set(Make("jello", "0")) assert.Assert(fields.Len() == 1) // assert.Assert(fields.Weight() == 16) fields = fields.Set(Make("nello", "012")) fields = fields.Set(Make("hello", "456")) fields = fields.Set(Make("fello", "123")) fields = fields.Set(Make("jello", "789")) var names string var datas string var nums float64 fields.Scan(func(f Field) bool { names += f.Name() datas += f.Value().Data() nums += f.Value().Num() return true }) assert.Assert(names == "fellohellojellonello") assert.Assert(datas == "123456789012") assert.Assert(nums == 1380) names = "" datas = "" nums = 0 fields.Scan(func(f Field) bool { names += f.Name() datas += f.Value().Data() nums += f.Value().Num() return false }) assert.Assert(names == "fello") assert.Assert(datas == "123") assert.Assert(nums == 123) } func randStr(n int) string { b := make([]byte, n) rand.Read(b) for i := 0; i < n; i++ { b[i] = 'a' + b[i]%26 } return string(b) } func randVal(n int) string { switch rand.Intn(10) { case 0: return "null" case 1: return "true" case 2: return "false" case 3: return `{"a":"` + randStr(n) + `"}` case 4: return `["` + randStr(n) + `"]` case 5: return `"` + randStr(n) + `"` case 6: return randStr(n) default: return fmt.Sprintf("%f", rand.Float64()*360) } } func TestRandom(t *testing.T) { seed := time.Now().UnixNano() // seed = 1663607868546669000 rand.Seed(seed) start := time.Now() var total int for time.Since(start) < time.Second*2 { N := rand.Intn(500) var org []Field var tr btree.Map[string, Field] var fields List for i := 0; i < N; i++ { name := randStr(rand.Intn(10)) value := randVal(rand.Intn(10)) field := Make(name, value) org = append(org, field) fields = fields.Set(field) v := fields.Get(name) // println(name, v.Value().Data(), field.Value().Data()) if !v.Value().Equals(field.Value()) { t.Fatalf("seed: %d, expected true", seed) } tr.Set(name, field) if fields.Len() != tr.Len() { t.Fatalf("seed: %d, expected %d, got %d", seed, tr.Len(), fields.Len()) } } comp := func() { var all []Field fields.Scan(func(f Field) bool { all = append(all, f) return true }) if len(all) != fields.Len() { t.Fatalf("seed: %d, expected %d, got %d", seed, fields.Len(), len(all)) } if fields.Len() != tr.Len() { t.Fatalf("seed: %d, expected %d, got %d", seed, tr.Len(), fields.Len()) } var i int tr.Scan(func(name string, f Field) bool { if name != f.Name() || all[i].Name() != f.Name() { t.Fatalf("seed: %d, out of order", seed) } i++ return true }) } comp() rand.Shuffle(len(org), func(i, j int) { org[i], org[j] = org[j], org[i] }) for _, f := range org { comp() tr.Delete(f.Name()) fields = fields.Set(Make(f.Name(), "0")) if fields.Len() != tr.Len() { t.Fatalf("seed: %d, expected %d, got %d", seed, tr.Len(), fields.Len()) } comp() } total++ } }