github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/generic/value_test.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package generic 18 19 import ( 20 "context" 21 "encoding/binary" 22 "fmt" 23 "io/ioutil" 24 "math" 25 "math/rand" 26 "reflect" 27 "testing" 28 29 "github.com/cloudwego/dynamicgo/meta" 30 "github.com/cloudwego/dynamicgo/testdata/kitex_gen/example2" 31 "github.com/cloudwego/dynamicgo/testdata/sample" 32 "github.com/cloudwego/dynamicgo/thrift" 33 "github.com/stretchr/testify/assert" 34 "github.com/stretchr/testify/require" 35 ) 36 37 const ( 38 exampleIDLPath = "../../testdata/idl/example2.thrift" 39 exampleThriftPath = "../../testdata/data/example2.bin" 40 exampleSuperThriftPath = "../../testdata/data/example2super.bin" 41 ) 42 43 func GetSampleTree(v Value) PathNode { 44 return PathNode{ 45 Node: v.Node, 46 Next: []PathNode{ 47 { 48 Path: NewPathFieldId(1), 49 }, 50 { 51 Path: NewPathFieldId(3), 52 Next: []PathNode{ 53 { 54 Path: NewPathFieldId(1), 55 }, 56 { 57 Path: NewPathFieldId(8), 58 }, 59 { 60 Path: NewPathFieldId(9), 61 }, 62 }, 63 }, 64 { 65 Path: NewPathFieldId(255), 66 Next: []PathNode{ 67 { 68 Path: NewPathFieldId(5), 69 }, 70 }, 71 }, 72 }, 73 } 74 } 75 76 func GetSampleTreeById(v Value) PathNode { 77 return PathNode{ 78 Node: v.Node, 79 Next: []PathNode{ 80 { 81 Path: NewPathFieldId(1), 82 }, 83 { 84 Path: NewPathFieldId(3), 85 Next: []PathNode{ 86 { 87 Path: NewPathFieldId(1), 88 }, 89 { 90 Path: NewPathFieldId(8), 91 }, 92 { 93 Path: NewPathFieldId(9), 94 }, 95 }, 96 }, 97 { 98 Path: NewPathFieldId(255), 99 Next: []PathNode{ 100 { 101 Path: NewPathFieldId(4), 102 }, 103 }, 104 }, 105 }, 106 } 107 } 108 109 func TestCount(t *testing.T) { 110 desc := getExampleDesc() 111 data := getExampleData() 112 fmt.Printf("data len: %d\n", len(data)) 113 v := NewValue(desc, data) 114 children := make([]PathNode, 0, 4) 115 opts := Options{} 116 if err := v.Children(&children, true, &opts); err != nil { 117 t.Fatal(err) 118 } 119 count := 1 120 countHelper(&count, children) 121 fmt.Printf("nodes count: %d", count) 122 } 123 124 func countHelper(count *int, ps []PathNode) { 125 *count += len(ps) 126 for _, p := range ps { 127 countHelper(count, p.Next) 128 } 129 } 130 131 func getExampleDesc() *thrift.TypeDescriptor { 132 svc, err := thrift.NewDescritorFromPath(context.Background(), exampleIDLPath) 133 if err != nil { 134 panic(err) 135 } 136 return svc.Functions()["ExampleMethod"].Request().Struct().FieldByKey("req").Type() 137 } 138 139 func getExamplePartialDesc() *thrift.TypeDescriptor { 140 svc, err := thrift.NewDescritorFromPath(context.Background(), exampleIDLPath) 141 if err != nil { 142 panic(err) 143 } 144 return svc.Functions()["ExamplePartialMethod"].Request().Struct().FieldByKey("req").Type() 145 } 146 147 func getExampleData() []byte { 148 out, err := ioutil.ReadFile(exampleThriftPath) 149 if err != nil { 150 panic(err) 151 } 152 return out 153 } 154 155 func getExampleSuperData() []byte { 156 out, err := ioutil.ReadFile(exampleSuperThriftPath) 157 if err != nil { 158 panic(err) 159 } 160 return out 161 } 162 163 func empty(v interface{}) interface{} { 164 et := reflect.TypeOf(v) 165 if et.Kind() == reflect.Ptr { 166 et = et.Elem() 167 } 168 return reflect.New(et).Interface() 169 } 170 171 func checkHelper(t *testing.T, exp interface{}, act Node, api string) { 172 v := reflect.ValueOf(act) 173 f := v.MethodByName(api) 174 if f.Kind() != reflect.Func { 175 t.Fatalf("method %s not found", api) 176 } 177 var args []reflect.Value 178 if api == "List" || api == "StrMap" || api == "IntMap" || api == "Interface" { 179 args = make([]reflect.Value, 1) 180 args[0] = reflect.ValueOf(&Options{}) 181 } else { 182 args = make([]reflect.Value, 0) 183 } 184 rets := f.Call(args) 185 if len(rets) != 2 { 186 t.Fatal("wrong number of return values") 187 } 188 require.Nil(t, rets[1].Interface()) 189 switch api { 190 case "List": 191 vs := rets[0] 192 if vs.Kind() != reflect.Slice { 193 t.Fatal("wrong type") 194 } 195 es := reflect.ValueOf(exp) 196 if es.Kind() != reflect.Slice { 197 t.Fatal("wrong type") 198 } 199 for i := 0; i < vs.Len(); i++ { 200 vv := vs.Index(i) 201 require.Equal(t, cast(es.Index(i).Interface(), vv.Type().Name() == "byte"), vv.Interface()) 202 } 203 case "StrMap": 204 vs := rets[0] 205 if vs.Kind() != reflect.Map { 206 t.Fatal("wrong type") 207 } 208 es := reflect.ValueOf(exp) 209 if es.Kind() != reflect.Map { 210 t.Fatal("wrong type") 211 } 212 ks := vs.MapKeys() 213 for i := 0; i < len(ks); i++ { 214 vv := vs.MapIndex(ks[i]) 215 require.Equal(t, cast(es.MapIndex(ks[i]).Interface(), vv.Type().Name() == "byte"), vv.Interface()) 216 } 217 default: 218 require.Equal(t, exp, rets[0].Interface()) 219 } 220 } 221 222 func cast(ev interface{}, b bool) interface{} { 223 switch ev.(type) { 224 case int8: 225 if b { 226 return byte(ev.(int8)) 227 } 228 return int(ev.(int8)) 229 case int16: 230 return int(ev.(int16)) 231 case int32: 232 return int(ev.(int32)) 233 case int64: 234 return int(ev.(int64)) 235 case float32: 236 return float64(ev.(float32)) 237 default: 238 return ev 239 } 240 } 241 242 func TestGet(t *testing.T) { 243 desc := getExampleDesc() 244 data := getExampleData() 245 246 exp := example2.NewExampleReq() 247 v := NewValue(desc, data) 248 _, err := exp.FastRead(data) 249 require.Nil(t, err) 250 251 t.Run("GetByStr()", func(t *testing.T) { 252 v := v.GetByPath(PathExampleMapStringString...) 253 require.Nil(t, v.Check()) 254 v1, err := v.GetByStr("b").String() 255 require.NoError(t, err) 256 require.Equal(t, sample.Example2Obj.InnerBase.MapStringString["b"], v1) 257 v2, err := v.GetByStr("aa").String() 258 require.Error(t, err) 259 require.Equal(t, meta.ErrNotFound, err.(Node).ErrCode()) 260 require.Equal(t, sample.Example2Obj.InnerBase.MapStringString["aa"], v2) 261 }) 262 263 t.Run("GetByInt()", func(t *testing.T) { 264 v := v.GetByPath(PathExampleMapInt32String...) 265 require.Nil(t, v.Check()) 266 v1, err := v.GetByInt(1).String() 267 require.NoError(t, err) 268 require.Equal(t, sample.Example2Obj.InnerBase.MapInt32String[1], v1) 269 v2, err := v.GetByInt(999).String() 270 require.Error(t, err) 271 require.Equal(t, meta.ErrNotFound, err.(Node).ErrCode()) 272 require.Equal(t, sample.Example2Obj.InnerBase.MapInt32String[999], v2) 273 }) 274 275 t.Run("Index()", func(t *testing.T) { 276 v := v.GetByPath(PathExampleListInt32...) 277 require.Nil(t, v.Check()) 278 v1, err := v.Index(1).Int() 279 require.NoError(t, err) 280 require.Equal(t, int(sample.Example2Obj.InnerBase.ListInt32[1]), v1) 281 v2 := v.Index(999) 282 require.Error(t, v2) 283 require.Equal(t, meta.ErrInvalidParam, v2.ErrCode()) 284 }) 285 286 t.Run("FieldByName()", func(t *testing.T) { 287 _, err := v.FieldByName("Msg2").String() 288 require.NotNil(t, err) 289 s, err := v.FieldByName("Msg").String() 290 require.Equal(t, *exp.Msg, s) 291 }) 292 293 t.Run("Field()", func(t *testing.T) { 294 xx, err := v.Field(222).Int() 295 require.NotNil(t, err) 296 require.Equal(t, int(0), xx) 297 a := v.Field(3) 298 b, err := a.Field(1).Bool() 299 require.Nil(t, err) 300 require.Equal(t, exp.InnerBase.Bool, b) 301 c, err := a.Field(2).Byte() 302 require.Nil(t, err) 303 require.Equal(t, byte(exp.InnerBase.Byte), c) 304 d, err := a.Field(3).Int() 305 require.Nil(t, err) 306 require.Equal(t, exp.InnerBase.Int16, int16(d)) 307 e, err := a.Field(4).Int() 308 require.Nil(t, err) 309 require.Equal(t, exp.InnerBase.Int32, int32(e)) 310 f, err := a.Field(5).Int() 311 require.Nil(t, err) 312 require.Equal(t, exp.InnerBase.Int64, int64(f)) 313 g, err := a.Field(6).Float64() 314 require.Nil(t, err) 315 require.Equal(t, exp.InnerBase.Double, float64(g)) 316 h, err := a.Field(7).String() 317 require.Nil(t, err) 318 require.Equal(t, exp.InnerBase.String_, string(h)) 319 list := a.Field(8) 320 checkHelper(t, exp.InnerBase.ListInt32, list.Node, "List") 321 list1, err := a.Field(8).Index(1).Int() 322 require.Nil(t, err) 323 require.Equal(t, exp.InnerBase.ListInt32[1], int32(list1)) 324 mp := a.Field(9) 325 checkHelper(t, exp.InnerBase.MapStringString, mp.Node, "StrMap") 326 mp1, err := a.Field(9).GetByStr("b").String() 327 require.Nil(t, err) 328 require.Equal(t, exp.InnerBase.MapStringString["b"], (mp1)) 329 sp := a.Field(10) 330 checkHelper(t, exp.InnerBase.SetInt32_, sp.Node, "List") 331 i, err := a.Field(11).Int() 332 require.Nil(t, err) 333 require.Equal(t, int64(exp.InnerBase.Foo), int64(i)) 334 mp2, err := a.Field(12).GetByInt(2).String() 335 require.Nil(t, err) 336 require.Equal(t, exp.InnerBase.MapInt32String[2], (mp2)) 337 }) 338 339 t.Run("GetByPath()", func(t *testing.T) { 340 exp := sample.Example2Obj.InnerBase.ListInt32[1] 341 342 v1 := v.GetByPath(NewPathFieldId(thrift.FieldID(3)), NewPathFieldId(8), NewPathIndex(1)) 343 if v1.Error() != "" { 344 t.Fatal(v1.Error()) 345 } 346 act, err := v1.Int() 347 require.NoError(t, err) 348 require.Equal(t, int(exp), act) 349 350 v2 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(1)) 351 if v2.Error() != "" { 352 t.Fatal(v2.Error()) 353 } 354 require.Equal(t, v1, v2) 355 v3 := v.GetByPath(NewPathFieldId(thrift.FieldID(3)), NewPathFieldName("ListInt32"), NewPathIndex(1)) 356 if v3.Error() != "" { 357 t.Fatal(v3.Error()) 358 } 359 require.Equal(t, v1, v3) 360 v4 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldId(8), NewPathIndex(1)) 361 if v4.Error() != "" { 362 t.Fatal(v4.Error()) 363 } 364 require.Equal(t, v1, v4) 365 366 exp2 := sample.Example2Obj.InnerBase.MapInt32String[2] 367 v5 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldId(12), NewPathIntKey(2)) 368 if v5.Error() != "" { 369 t.Fatal(v5.Error()) 370 } 371 act2, err := v5.String() 372 require.NoError(t, err) 373 require.Equal(t, exp2, act2) 374 375 v6 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String"), NewPathIntKey(2)) 376 if v6.Error() != "" { 377 t.Fatal(v6.Error()) 378 } 379 require.Equal(t, v5, v6) 380 381 exp3 := sample.Example2Obj.InnerBase.MapStringString["b"] 382 v7 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldId(9), NewPathStrKey("b")) 383 if v5.Error() != "" { 384 t.Fatal(v7.Error()) 385 } 386 act3, err := v7.String() 387 require.NoError(t, err) 388 require.Equal(t, exp3, act3) 389 390 v8 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString"), NewPathStrKey("b")) 391 if v6.Error() != "" { 392 t.Fatal(v8.Error()) 393 } 394 require.Equal(t, v8, v7) 395 }) 396 } 397 398 func handlePartialMapStringString2(p map[int]interface{}) { 399 delete(p, 127) 400 if f18 := p[18]; f18 != nil { 401 for i := range f18.([]interface{}) { 402 pv := f18.([]interface{})[i].(map[int]interface{}) 403 handlePartialMapStringString2(pv) 404 } 405 } 406 if f19 := p[19]; f19 != nil { 407 for k := range f19.(map[interface{}]interface{}) { 408 handlePartialMapStringString2(*(k.(*map[int]interface{}))) 409 vv := f19.(map[interface{}]interface{})[k].(map[int]interface{}) 410 handlePartialMapStringString2(vv) 411 } 412 } 413 } 414 415 func TestMarshalTo(t *testing.T) { 416 desc := getExampleDesc() 417 data := getExampleData() 418 partial := getExamplePartialDesc() 419 420 exp := example2.NewExampleReq() 421 v := NewValue(desc, data) 422 _, err := exp.FastRead(data) 423 require.Nil(t, err) 424 425 t.Run("ById", func(t *testing.T) { 426 t.Run("WriteDefault", func(t *testing.T) { 427 opts := &Options{WriteDefault: true} 428 buf, err := v.MarshalTo(partial, opts) 429 require.Nil(t, err) 430 ep := example2.NewExampleReqPartial() 431 _, err = ep.FastRead(buf) 432 require.Nil(t, err) 433 act := toInterface(ep) 434 exp := toInterface(exp) 435 require.False(t, DeepEqual(act, exp)) 436 handlePartialMapStringString2(act.(map[int]interface{})[3].(map[int]interface{})) 437 require.True(t, DeepEqual(act, exp)) 438 require.NotNil(t, ep.InnerBase.MapStringString2) 439 }) 440 t.Run("NotWriteDefault", func(t *testing.T) { 441 opts := &Options{} 442 buf, err := v.MarshalTo(partial, opts) 443 require.Nil(t, err) 444 ep := example2.NewExampleReqPartial() 445 _, err = ep.FastRead(buf) 446 require.Nil(t, err) 447 act := toInterface(ep) 448 exp := toInterface(exp) 449 require.False(t, DeepEqual(act, exp)) 450 handlePartialMapStringString2(act.(map[int]interface{})[3].(map[int]interface{})) 451 require.True(t, DeepEqual(act, exp)) 452 require.Nil(t, ep.InnerBase.MapStringString2) 453 }) 454 }) 455 456 t.Run("unknown", func(t *testing.T) { 457 n := NewNode(thrift.STRUCT, data) 458 exist, err := n.SetByPath(NewNodeString("Insert"), NewPathFieldId(1024)) 459 require.Nil(t, err) 460 require.False(t, exist) 461 data = n.raw() 462 v.Node = NewNode(thrift.STRUCT, data) 463 t.Run("allow unknown", func(t *testing.T) { 464 opts := &Options{DisallowUnknow: false} 465 buf, err := v.MarshalTo(partial, opts) 466 require.NoError(t, err) 467 ep := example2.NewExampleReqPartial() 468 _, err = ep.FastRead(buf) 469 require.Nil(t, err) 470 act := toInterface(ep) 471 exp := toInterface(exp) 472 require.False(t, DeepEqual(act, exp)) 473 handlePartialMapStringString2(act.(map[int]interface{})[3].(map[int]interface{})) 474 require.True(t, DeepEqual(act, exp)) 475 }) 476 t.Run("disallow unknown", func(t *testing.T) { 477 opts := &Options{DisallowUnknow: true} 478 _, err := v.MarshalTo(partial, opts) 479 require.Error(t, err) 480 }) 481 }) 482 483 // t.Run("ByName", func(t *testing.T) { 484 // opts := &Options{WriteDefault: true} 485 // // opts.FieldByName = true 486 // buf, err := v.MarshalTo(partial, opts) 487 // require.Nil(t, err) 488 // ep := example2.NewExampleReqPartial() 489 // _, err = ep.FastRead(buf) 490 // require.Nil(t, err) 491 // checkHelper3(t, exp, ep) 492 // require.NotNil(t, ep.InnerBase.MapStringString2) 493 // }) 494 } 495 496 func checkHelper3(t *testing.T, exp, act interface{}) { 497 ev := reflect.ValueOf(exp) 498 av := reflect.ValueOf(act) 499 if ev.Kind() != av.Kind() { 500 t.Fatalf("%v != %v", ev.Kind(), av.Kind()) 501 } 502 if ev.Kind() == reflect.Ptr || av.Kind() == reflect.Ptr { 503 ev = ev.Elem() 504 av = av.Elem() 505 checkHelper3(t, ev.Interface(), av.Interface()) 506 return 507 } 508 switch av.Kind() { 509 case reflect.Struct: 510 for i := 0; i < ev.NumField(); i++ { 511 ef := ev.Type().Field(i) 512 af := av.FieldByName(ef.Name) 513 if reflect.DeepEqual(af, reflect.Value{}) { 514 continue 515 } 516 checkHelper3(t, ev.Field(i).Interface(), af.Interface()) 517 } 518 default: 519 assert.Equal(t, exp, act) 520 } 521 } 522 523 func TestSetMany(t *testing.T) { 524 desc := getExampleDesc() 525 data := getExampleData() 526 opts := &Options{ 527 UseNativeSkip: true, 528 } 529 530 r := NewValue(desc, data) 531 d1 := desc.Struct().FieldByKey("Msg").Type() 532 d2 := desc.Struct().FieldByKey("Subfix").Type() 533 534 t.Run("insert", func(t *testing.T) { 535 v := r.Fork() 536 exp1 := int32(-1024) 537 n1 := NewNodeInt32(exp1) 538 err := v.SetMany([]PathNode{ 539 { 540 Path: NewPathFieldId(2), 541 Node: n1, 542 }, 543 }, opts) 544 require.Nil(t, err) 545 v1 := v.GetByPath(NewPathFieldName("A")) 546 act1, err := v1.Int() 547 require.NoError(t, err) 548 require.Equal(t, exp1, int32(act1)) 549 550 exp21 := int32(math.MinInt32) 551 exp22 := int32(math.MaxInt32) 552 n21 := NewNodeInt32(exp21) 553 n22 := NewNodeInt32(exp22) 554 vv := v.GetByPath(PathExampleListInt32...) 555 l2, err := vv.Len() 556 require.NoError(t, err) 557 err = vv.SetMany([]PathNode{ 558 { 559 Path: NewPathIndex(1024), 560 Node: n21, 561 }, 562 { 563 Path: NewPathIndex(1024), 564 Node: n22, 565 }, 566 }, opts) 567 require.NoError(t, err) 568 v21 := vv.GetByPath(NewPathIndex(0)) 569 act21, err := v21.Int() 570 require.NoError(t, err) 571 require.Equal(t, exp21, int32(act21)) 572 v22 := vv.GetByPath(NewPathIndex(1)) 573 act22, err := v22.Int() 574 require.NoError(t, err) 575 require.Equal(t, exp22, int32(act22)) 576 ll2, err := vv.Len() 577 require.Nil(t, err) 578 require.Equal(t, l2+2, ll2) 579 }) 580 581 t.Run("replace", func(t *testing.T) { 582 v := r.Fork() 583 exp1 := "exp1" 584 exp2 := float64(-255.0001) 585 p := thrift.NewBinaryProtocolBuffer() 586 p.WriteString(exp1) 587 588 v1 := NewValue(d1, []byte(string(p.Buf))) 589 p.Buf = p.Buf[:0] 590 p.WriteDouble(exp2) 591 v2 := NewValue(d2, []byte(string(p.Buf))) 592 err := v.SetMany([]PathNode{ 593 { 594 Path: NewPathFieldId(1), 595 Node: v1.Node, 596 }, 597 { 598 Path: NewPathFieldId(32767), 599 Node: v2.Node, 600 }, 601 }, opts) 602 require.Nil(t, err) 603 604 exp := example2.NewExampleReq() 605 if _, err := exp.FastRead(v.Raw()); err != nil { 606 t.Fatal(err) 607 } 608 require.Equal(t, *exp.Msg, exp1) 609 require.Equal(t, exp.Subfix, exp2) 610 611 vx := v.GetByPath(NewPathFieldName("Base")) 612 vv := vx 613 err = vv.SetMany([]PathNode{ 614 { 615 Path: NewPathFieldId(1), 616 Node: v.FieldByName("Base").FieldByName("LogID").Node, 617 }, 618 { 619 Path: NewPathFieldId(2), 620 Node: v.FieldByName("Base").FieldByName("Caller").Node, 621 }, 622 { 623 Path: NewPathFieldId(3), 624 Node: v.FieldByName("Base").FieldByName("Addr").Node, 625 }, 626 { 627 Path: NewPathFieldId(4), 628 Node: v.FieldByName("Base").FieldByName("Client").Node, 629 }, 630 { 631 Path: NewPathFieldId(5), 632 Node: v.FieldByName("Base").FieldByName("TrafficEnv").Node, 633 }, 634 { 635 Path: NewPathFieldId(6), 636 Node: v.FieldByName("Base").FieldByName("Extra").Node, 637 }, 638 }, opts) 639 require.Nil(t, err) 640 require.Equal(t, vx.raw(), vv.raw()) 641 642 inner := v.GetByPath(NewPathFieldName("InnerBase")) 643 p = thrift.NewBinaryProtocolBuffer() 644 e1 := false 645 p.WriteBool(e1) 646 v1 = NewValue(d1, []byte(string(p.Buf))) 647 p.Buf = p.Buf[:0] 648 e2 := float64(-255.0001) 649 p.WriteDouble(e2) 650 v2 = NewValue(d1, []byte(string(p.Buf))) 651 p.Buf = p.Buf[:0] 652 err = inner.SetMany([]PathNode{ 653 { 654 Path: NewPathFieldId(1), 655 Node: v1.Node, 656 }, 657 { 658 Path: NewPathFieldId(6), 659 Node: v2.Node, 660 }, 661 { 662 Path: NewPathFieldId(255), 663 Node: vx.Node, 664 }, 665 }, opts) 666 require.Nil(t, err) 667 // spew.Dump(inner.Raw()) 668 expx := example2.NewInnerBase() 669 if _, err := expx.FastRead(inner.Raw()); err != nil { 670 t.Fatal(err) 671 } 672 require.Equal(t, expx.Bool, e1) 673 require.Equal(t, expx.Double, e2) 674 require.Equal(t, expx.Base, exp.Base) 675 }) 676 677 } 678 679 func TestUnsetByPath(t *testing.T) { 680 desc := getExampleDesc() 681 data := getExampleData() 682 r := NewValue(desc, data) 683 684 v := r.Fork() 685 err := v.UnsetByPath() 686 require.Nil(t, err) 687 require.True(t, v.IsEmpty()) 688 689 v = r.Fork() 690 n := v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Caller")) 691 require.False(t, n.IsError()) 692 err = v.UnsetByPath(NewPathFieldName("Base"), NewPathFieldName("Caller")) 693 require.NoError(t, err) 694 n = v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Caller")) 695 require.True(t, n.IsErrNotFound()) 696 697 v = r.Fork() 698 l, err := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32")).Len() 699 require.NoError(t, err) 700 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(l-1)) 701 require.False(t, n.IsError()) 702 err = v.UnsetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(l-1)) 703 require.NoError(t, err) 704 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(l-1)) 705 require.True(t, n.IsErrNotFound()) 706 ll, err := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32")).Len() 707 require.NoError(t, err) 708 require.Equal(t, l-1, ll) 709 710 v = r.Fork() 711 l, err = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString")).Len() 712 require.NoError(t, err) 713 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString"), NewPathStrKey("a")) 714 require.False(t, n.IsError()) 715 err = v.UnsetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString"), NewPathStrKey("a")) 716 require.NoError(t, err) 717 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString"), NewPathStrKey("a")) 718 require.True(t, n.IsErrNotFound()) 719 ll, err = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapStringString")).Len() 720 require.NoError(t, err) 721 require.Equal(t, l-1, ll) 722 723 v = r.Fork() 724 l, err = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String")).Len() 725 require.NoError(t, err) 726 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String"), NewPathIntKey(1)) 727 require.False(t, n.IsError()) 728 err = v.UnsetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String"), NewPathIntKey(1)) 729 require.NoError(t, err) 730 n = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String"), NewPathIntKey(1)) 731 require.True(t, n.IsErrNotFound()) 732 ll, err = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("MapInt32String")).Len() 733 require.NoError(t, err) 734 require.Equal(t, l-1, ll) 735 } 736 737 func TestSetByPath(t *testing.T) { 738 desc := getExampleDesc() 739 data := getExampleData() 740 v := NewValue(desc, data) 741 ds := desc.Struct().FieldByKey("Subfix").Type() 742 d2 := desc.Struct().FieldByKey("Base").Type().Struct().FieldByKey("Extra").Type().Elem() 743 d3 := desc.Struct().FieldByKey("InnerBase").Type().Struct().FieldByKey("ListInt32").Type().Elem() 744 745 e, err := v.SetByPath(v) 746 require.True(t, e) 747 require.Nil(t, err) 748 749 t.Run("replace", func(t *testing.T) { 750 s := v.GetByPath(NewPathFieldName("Subfix")) 751 require.Empty(t, s.Error()) 752 f, _ := s.Float64() 753 require.Equal(t, math.MaxFloat64, f) 754 exp := float64(-0.1) 755 buf := make([]byte, 8) 756 binary.BigEndian.PutUint64(buf, math.Float64bits(exp)) 757 e, err := v.SetByPath(NewValue(ds, buf), NewPathFieldName("Subfix")) 758 require.True(t, e) 759 require.Nil(t, err) 760 s = v.GetByPath(NewPathFieldName("Subfix")) 761 require.Empty(t, s.Error()) 762 f, _ = s.Float64() 763 require.Equal(t, exp, f) 764 765 exp2 := "中文" 766 p := thrift.NewBinaryProtocolBuffer() 767 p.WriteString(exp2) 768 e, err2 := v.SetByPath(NewValue(d2, p.Buf), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")) 769 require.True(t, e) 770 require.Nil(t, err2) 771 s2 := v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")) 772 require.Empty(t, s2.Error()) 773 f2, _ := s2.String() 774 require.Equal(t, exp2, f2) 775 e, err2 = v.SetByPath(NewValue(d2, p.Buf), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")) 776 require.True(t, e) 777 require.Nil(t, err2) 778 s2 = v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")) 779 require.Empty(t, s2.Error()) 780 f2, _ = s2.String() 781 require.Equal(t, exp2, f2) 782 783 exp3 := int32(math.MinInt32) + 1 784 v3 := Value{NewNodeInt32(exp3), d3} 785 ps := []Path{NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(2)} 786 parent := v.GetByPath(ps[:len(ps)-1]...) 787 l3, err := parent.Len() 788 require.Nil(t, err) 789 e, err = v.SetByPath(v3, ps...) 790 require.True(t, e) 791 require.Nil(t, err) 792 s3 := v.GetByPath(ps...) 793 act3, _ := s3.Int() 794 require.Equal(t, exp3, int32(act3)) 795 parent = v.GetByPath(ps[:len(ps)-1]...) 796 l3a, err := parent.Len() 797 require.Nil(t, err) 798 require.Equal(t, l3, l3a) 799 }) 800 801 t.Run("insert", func(t *testing.T) { 802 s := v.GetByPath(NewPathFieldName("A")) 803 require.True(t, s.IsErrNotFound()) 804 exp := int32(-1024) 805 v1 := Value{NewNodeInt32(exp), d3} 806 e, err := v.SetByPath(v1, NewPathFieldName("A")) 807 require.False(t, e) 808 require.Nil(t, err) 809 s = v.GetByPath(NewPathFieldName("A")) 810 require.Empty(t, s.Error()) 811 act, _ := s.Int() 812 require.Equal(t, exp, int32(act)) 813 814 s2 := v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x")) 815 require.True(t, s2.IsErrNotFound()) 816 exp2 := "中文\bb" 817 v2 := Value{NewNodeString(exp2), d3} 818 e, err2 := v.SetByPath(v2, NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x")) 819 require.False(t, e) 820 require.Nil(t, err2) 821 s2 = v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x")) 822 require.Empty(t, s2.Error()) 823 act2, _ := s2.String() 824 require.Equal(t, exp2, act2) 825 826 parent := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32")) 827 l3, err := parent.Len() 828 require.Nil(t, err) 829 s3 := v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(1024)) 830 require.True(t, s3.IsErrNotFound()) 831 exp3 := rand.Int31() 832 v3 := Value{NewNodeInt32(exp3), d3} 833 e, err = v.SetByPath(v3, NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(1024)) 834 require.False(t, e) 835 require.NoError(t, err) 836 s3 = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(0)) 837 act3, _ := s3.Int() 838 require.Equal(t, exp3, int32(act3)) 839 parent = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32")) 840 l3a, err := parent.Len() 841 require.Nil(t, err) 842 require.Equal(t, l3+1, l3a) 843 exp3 = rand.Int31() 844 v3 = Value{NewNodeInt32(exp3), d3} 845 e, err = v.SetByPath(v3, NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(1024)) 846 require.False(t, e) 847 require.NoError(t, err) 848 s3 = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32"), NewPathIndex(0)) 849 act3, _ = s3.Int() 850 require.Equal(t, exp3, int32(act3)) 851 parent = v.GetByPath(NewPathFieldName("InnerBase"), NewPathFieldName("ListInt32")) 852 l3a, err = parent.Len() 853 require.Nil(t, err) 854 require.Equal(t, l3+2, l3a) 855 }) 856 }