github.com/SaurabhDubey-Groww/go-cloud@v0.0.0-20221124105541-b26c29285fd8/docstore/driver/codec_test.go (about) 1 // Copyright 2019 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package driver 16 17 import ( 18 "errors" 19 "fmt" 20 "reflect" 21 "testing" 22 "time" 23 24 "github.com/google/go-cmp/cmp" 25 "gocloud.dev/gcerrors" 26 "gocloud.dev/internal/gcerr" 27 "google.golang.org/protobuf/proto" 28 tspb "google.golang.org/protobuf/types/known/timestamppb" 29 ) 30 31 type myString string 32 33 type te struct{ X byte } 34 35 func (e te) MarshalText() ([]byte, error) { 36 return []byte{e.X}, nil 37 } 38 39 func (e *te) UnmarshalText(b []byte) error { 40 if len(b) != 1 { 41 return errors.New("te.UnmarshalText: need exactly 1 byte") 42 } 43 e.X = b[0] 44 return nil 45 } 46 47 type special int 48 49 func (special) MarshalBinary() ([]byte, error) { panic("should never be called") } 50 func (*special) UnmarshalBinary([]byte) error { panic("should never be called") } 51 52 type badSpecial int 53 54 type Embed1 struct { 55 E1 string 56 } 57 type Embed2 struct { 58 E2 string 59 } 60 61 type embed3 struct { 62 E3 string 63 } 64 65 type embed4 struct { 66 E4 string 67 } 68 69 type MyStruct struct { 70 A int 71 B *bool 72 C []*te 73 D []time.Time 74 T *tspb.Timestamp 75 Embed1 76 *Embed2 77 embed3 78 *embed4 79 Omit int `docstore:"-"` 80 OmitEmpty int `docstore:",omitempty"` 81 Rename int `docstore:"rename"` 82 } 83 84 func TestEncode(t *testing.T) { 85 var seven int32 = 7 86 var nullptr *int 87 tm := time.Now() 88 tmb, err := tm.MarshalBinary() 89 if err != nil { 90 t.Fatal(err) 91 } 92 tru := true 93 ts := &tspb.Timestamp{Seconds: 25, Nanos: 300} 94 tsb, err := proto.Marshal(ts) 95 if err != nil { 96 t.Fatal(err) 97 } 98 for _, test := range []struct { 99 in, want interface{} 100 }{ 101 {nil, nil}, 102 {0, int64(0)}, 103 {uint64(999), uint64(999)}, 104 {float32(3.5), float64(3.5)}, 105 {"", ""}, 106 {"x", "x"}, 107 {true, true}, 108 {nullptr, nil}, 109 {seven, int64(seven)}, 110 {&seven, int64(seven)}, 111 {[]byte{1, 2}, []byte{1, 2}}, 112 {[2]byte{3, 4}, []interface{}{uint64(3), uint64(4)}}, 113 {[]int(nil), nil}, 114 {[]int{}, []interface{}{}}, 115 {[]int{1, 2}, []interface{}{int64(1), int64(2)}}, 116 { 117 [][]string{{"a", "b"}, {"c", "d"}}, 118 []interface{}{ 119 []interface{}{"a", "b"}, 120 []interface{}{"c", "d"}, 121 }, 122 }, 123 {[...]int{1, 2}, []interface{}{int64(1), int64(2)}}, 124 {[]interface{}{nil, false}, []interface{}{nil, false}}, 125 {map[string]int(nil), nil}, 126 {map[string]int{}, map[string]interface{}{}}, 127 { 128 map[string]int{"a": 1, "b": 2}, 129 map[string]interface{}{"a": int64(1), "b": int64(2)}, 130 }, 131 {tm, tmb}, 132 {ts, tsb}, 133 {te{'A'}, "A"}, 134 {special(17), 17}, 135 {myString("x"), "x"}, 136 {[]myString{"x"}, []interface{}{"x"}}, 137 {map[myString]myString{"a": "x"}, map[string]interface{}{"a": "x"}}, 138 { 139 map[int]bool{17: true}, 140 map[string]interface{}{"17": true}, 141 }, 142 { 143 map[uint]bool{18: true}, 144 map[string]interface{}{"18": true}, 145 }, 146 { 147 map[te]bool{{'B'}: true}, 148 map[string]interface{}{"B": true}, 149 }, 150 { 151 MyStruct{ 152 A: 1, 153 B: &tru, 154 C: []*te{{'T'}}, 155 D: []time.Time{tm}, 156 T: ts, 157 Embed1: Embed1{E1: "E1"}, 158 Embed2: &Embed2{E2: "E2"}, 159 embed3: embed3{E3: "E3"}, 160 embed4: &embed4{E4: "E4"}, 161 Omit: 3, 162 OmitEmpty: 4, 163 Rename: 5, 164 }, 165 map[string]interface{}{ 166 "A": int64(1), 167 "B": true, 168 "C": []interface{}{"T"}, 169 "D": []interface{}{tmb}, 170 "T": tsb, 171 "E1": "E1", 172 "E2": "E2", 173 "E3": "E3", 174 "E4": "E4", 175 "OmitEmpty": int64(4), 176 "rename": int64(5), 177 }, 178 }, 179 { 180 MyStruct{}, 181 map[string]interface{}{ 182 "A": int64(0), 183 "B": nil, 184 "C": nil, 185 "D": nil, 186 "T": nil, 187 "E1": "", 188 "E3": "", 189 "rename": int64(0), 190 }, 191 }, 192 } { 193 enc := &testEncoder{} 194 if err := Encode(reflect.ValueOf(test.in), enc); err != nil { 195 t.Fatal(err) 196 } 197 got := enc.val 198 if diff := cmp.Diff(got, test.want); diff != "" { 199 t.Errorf("%#v (got=-, want=+):\n%s", test.in, diff) 200 } 201 } 202 } 203 204 type badBinaryMarshaler struct{} 205 206 func (badBinaryMarshaler) MarshalBinary() ([]byte, error) { return nil, errors.New("bad") } 207 func (*badBinaryMarshaler) UnmarshalBinary([]byte) error { return errors.New("bad") } 208 209 type badTextMarshaler struct{} 210 211 func (badTextMarshaler) MarshalText() ([]byte, error) { return nil, errors.New("bad") } 212 func (*badTextMarshaler) UnmarshalText([]byte) error { return errors.New("bad") } 213 214 func TestEncodeErrors(t *testing.T) { 215 for _, test := range []struct { 216 desc string 217 val interface{} 218 }{ 219 {"MarshalBinary fails", badBinaryMarshaler{}}, 220 {"MarshalText fails", badTextMarshaler{}}, 221 {"bad type", make(chan int)}, 222 {"bad type in list", []interface{}{func() {}}}, 223 {"bad type in map", map[string]interface{}{"a": func() {}}}, 224 {"bad type in struct", &struct{ C chan int }{}}, 225 {"bad map key type", map[float32]int{1: 1}}, 226 {"MarshalText for map key fails", map[badTextMarshaler]int{{}: 1}}, 227 } { 228 enc := &testEncoder{} 229 if err := Encode(reflect.ValueOf(test.val), enc); err == nil { 230 t.Errorf("%s: got nil, want error", test.desc) 231 } else if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { 232 t.Errorf("%s: got code %s, want InvalidArgument", test.desc, c) 233 } 234 } 235 } 236 237 type testEncoder struct { 238 val interface{} 239 } 240 241 func (e *testEncoder) EncodeNil() { e.val = nil } 242 func (e *testEncoder) EncodeBool(x bool) { e.val = x } 243 func (e *testEncoder) EncodeString(x string) { e.val = x } 244 func (e *testEncoder) EncodeInt(x int64) { e.val = x } 245 func (e *testEncoder) EncodeUint(x uint64) { e.val = x } 246 func (e *testEncoder) EncodeFloat(x float64) { e.val = x } 247 func (e *testEncoder) EncodeBytes(x []byte) { e.val = x } 248 249 var ( 250 typeOfSpecial = reflect.TypeOf(special(0)) 251 typeOfBadSpecial = reflect.TypeOf(badSpecial(0)) 252 ) 253 254 func (e *testEncoder) EncodeSpecial(v reflect.Value) (bool, error) { 255 // special would normally encode as a []byte, because it implements BinaryMarshaler. 256 // Encode it as an int instead. 257 if v.Type() == typeOfSpecial { 258 e.val = int(v.Interface().(special)) 259 return true, nil 260 } 261 return false, nil 262 } 263 264 func (e *testEncoder) ListIndex(int) { panic("impossible") } 265 func (e *testEncoder) MapKey(string) { panic("impossible") } 266 267 func (e *testEncoder) EncodeList(n int) Encoder { 268 s := make([]interface{}, n) 269 e.val = s 270 return &listEncoder{s: s} 271 } 272 273 func (e *testEncoder) EncodeMap(n int) Encoder { 274 m := make(map[string]interface{}, n) 275 e.val = m 276 return &mapEncoder{m: m} 277 } 278 279 type listEncoder struct { 280 s []interface{} 281 testEncoder 282 } 283 284 func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val } 285 286 type mapEncoder struct { 287 m map[string]interface{} 288 testEncoder 289 } 290 291 func (e *mapEncoder) MapKey(k string) { e.m[k] = e.val } 292 293 func TestDecode(t *testing.T) { 294 two := 2 295 tru := true 296 fa := false 297 ptru := &tru 298 pfa := &fa 299 tm := time.Now() 300 tmb, err := tm.MarshalBinary() 301 if err != nil { 302 t.Fatal(err) 303 } 304 ts := &tspb.Timestamp{Seconds: 25, Nanos: 300} 305 tsb, err := proto.Marshal(ts) 306 if err != nil { 307 t.Fatal(err) 308 } 309 310 for _, test := range []struct { 311 in interface{} // pointer that will be set 312 val interface{} // value to set it to 313 want interface{} 314 exactMatch bool 315 }{ 316 {new(interface{}), nil, nil, true}, 317 {new(int), int64(7), int(7), true}, 318 {new(uint8), uint64(250), uint8(250), true}, 319 {new(bool), true, true, true}, 320 {new(string), "x", "x", true}, 321 {new(float32), 4.25, float32(4.25), true}, 322 {new(*int), int64(2), &two, true}, 323 {new(*int), nil, (*int)(nil), true}, 324 {new([]byte), []byte("foo"), []byte("foo"), true}, 325 {new([]string), []interface{}{"a", "b"}, []string{"a", "b"}, true}, 326 {new([]**bool), []interface{}{true, false}, []**bool{&ptru, &pfa}, true}, 327 {&[1]int{1}, []interface{}{2}, [1]int{2}, true}, 328 {&[2]int{1, 2}, []interface{}{3}, [2]int{3, 0}, true}, // zero extra elements 329 {&[]int{1, 2}, []interface{}{3}, []int{3}, true}, // truncate slice 330 { 331 // extend slice 332 func() *[]int { s := make([]int, 1, 2); return &s }(), 333 []interface{}{5, 6}, 334 []int{5, 6}, 335 true, 336 }, 337 { 338 new(map[string]string), 339 map[string]interface{}{"a": "b"}, 340 map[string]string{"a": "b"}, 341 true, 342 }, 343 { 344 new(map[int]bool), 345 map[string]interface{}{"17": true}, 346 map[int]bool{17: true}, 347 true, 348 }, 349 { 350 new(map[te]bool), 351 map[string]interface{}{"B": true}, 352 map[te]bool{{'B'}: true}, 353 true, 354 }, 355 { 356 new(map[interface{}]bool), 357 map[string]interface{}{"B": true}, 358 map[interface{}]bool{"B": true}, 359 true, 360 }, 361 { 362 new(map[string][]bool), 363 map[string]interface{}{ 364 "a": []interface{}{true, false}, 365 "b": []interface{}{false, true}, 366 }, 367 map[string][]bool{ 368 "a": {true, false}, 369 "b": {false, true}, 370 }, 371 true, 372 }, 373 {new(special), 17, special(17), true}, 374 {new(myString), "x", myString("x"), true}, 375 {new([]myString), []interface{}{"x"}, []myString{"x"}, true}, 376 {new(time.Time), tmb, tm, true}, 377 {new(*time.Time), tmb, &tm, true}, 378 {new(*tspb.Timestamp), tsb, ts, true}, 379 {new([]time.Time), []interface{}{tmb}, []time.Time{tm}, true}, 380 {new([]*time.Time), []interface{}{tmb}, []*time.Time{&tm}, true}, 381 { 382 new(map[myString]myString), 383 map[string]interface{}{"a": "x"}, 384 map[myString]myString{"a": "x"}, 385 true, 386 }, 387 { 388 new(map[string]time.Time), 389 map[string]interface{}{"t": tmb}, 390 map[string]time.Time{"t": tm}, 391 true, 392 }, 393 { 394 new(map[string]*time.Time), 395 map[string]interface{}{"t": tmb}, 396 map[string]*time.Time{"t": &tm}, 397 true, 398 }, 399 {new(te), "A", te{'A'}, true}, 400 {new(**te), "B", func() **te { x := &te{'B'}; return &x }(), true}, 401 402 { 403 &MyStruct{embed4: &embed4{}}, 404 map[string]interface{}{ 405 "A": int64(1), 406 "B": true, 407 "C": []interface{}{"T"}, 408 "D": []interface{}{tmb}, 409 "T": tsb, 410 "E1": "E1", 411 "E2": "E2", 412 "E3": "E3", 413 "E4": "E4", 414 }, 415 MyStruct{A: 1, B: &tru, C: []*te{{'T'}}, D: []time.Time{tm}, T: ts, 416 Embed1: Embed1{E1: "E1"}, 417 Embed2: &Embed2{E2: "E2"}, 418 embed3: embed3{E3: "E3"}, 419 embed4: &embed4{E4: "E4"}, 420 }, 421 true, 422 }, 423 { 424 &MyStruct{embed4: &embed4{}}, 425 map[string]interface{}{ 426 "a": int64(1), 427 "b": true, 428 "c": []interface{}{"T"}, 429 "d": []interface{}{tmb}, 430 "t": tsb, 431 "e1": "E1", 432 "e2": "E2", 433 "e3": "E3", 434 "e4": "E4", 435 }, 436 MyStruct{A: 1, B: &tru, C: []*te{{'T'}}, D: []time.Time{tm}, T: ts, 437 Embed1: Embed1{E1: "E1"}, 438 Embed2: &Embed2{E2: "E2"}, 439 embed3: embed3{E3: "E3"}, 440 embed4: &embed4{E4: "E4"}, 441 }, 442 false, 443 }, 444 } { 445 dec := &testDecoder{test.val, test.exactMatch} 446 if err := Decode(reflect.ValueOf(test.in).Elem(), dec); err != nil { 447 t.Fatalf("%T: %v", test.in, err) 448 } 449 got := reflect.ValueOf(test.in).Elem().Interface() 450 diff := cmp.Diff(got, test.want, cmp.Comparer(proto.Equal), cmp.AllowUnexported(MyStruct{})) 451 if diff != "" { 452 t.Errorf("%T (got=-, want=+): %s", test.in, diff) 453 } 454 } 455 } 456 457 func TestDecodeErrors(t *testing.T) { 458 for _, test := range []struct { 459 desc string 460 in, val interface{} 461 }{ 462 { 463 "bad type", 464 new(int), 465 "foo", 466 }, 467 { 468 "bad type in list", 469 new([]int), 470 []interface{}{1, "foo"}, 471 }, 472 { 473 "array too short", 474 new([1]bool), 475 []interface{}{true, false}, 476 }, 477 { 478 "bad map key type", 479 new(map[float64]interface{}), 480 map[string]interface{}{"a": 1}, 481 }, 482 { 483 "unknown struct field", 484 new(MyStruct), 485 map[string]interface{}{"bad": 1}, 486 }, 487 { 488 "nil embedded, unexported pointer to struct", 489 new(MyStruct), 490 map[string]interface{}{"E4": "E4"}, 491 }, 492 { 493 "int overflow", 494 new(int8), 495 257, 496 }, 497 { 498 "uint overflow", 499 new(uint8), 500 uint(257), 501 }, 502 { 503 "non-integral float (int)", 504 new(int), 505 1.5, 506 }, 507 { 508 "non-integral float (uint)", 509 new(uint), 510 1.5, 511 }, 512 { 513 "bad special", 514 new(badSpecial), 515 badSpecial(0), 516 }, 517 { 518 "bad binary unmarshal", 519 new(badBinaryMarshaler), 520 []byte{1}, 521 }, 522 { 523 "binary unmarshal with non-byte slice", 524 new(time.Time), 525 1, 526 }, 527 { 528 "bad text unmarshal", 529 new(badTextMarshaler), 530 "foo", 531 }, 532 { 533 "text unmarshal with non-string", 534 new(badTextMarshaler), 535 1, 536 }, 537 { 538 "bad text unmarshal in map key", 539 new(map[badTextMarshaler]int), 540 map[string]interface{}{"a": 1}, 541 }, 542 { 543 "bad int map key", 544 new(map[int]int), 545 map[string]interface{}{"a": 1}, 546 }, 547 { 548 "overflow in int map key", 549 new(map[int8]int), 550 map[string]interface{}{"256": 1}, 551 }, 552 { 553 "bad uint map key", 554 new(map[uint]int), 555 map[string]interface{}{"a": 1}, 556 }, 557 { 558 "overflow in uint map key", 559 new(map[uint8]int), 560 map[string]interface{}{"256": 1}, 561 }, 562 { 563 "case mismatch when decoding with exact match", 564 &MyStruct{embed4: &embed4{}}, 565 map[string]interface{}{ 566 "a": int64(1), 567 "b": true, 568 "e1": "E1", 569 "e2": "E2", 570 }, 571 }, 572 } { 573 dec := &testDecoder{test.val, true} 574 err := Decode(reflect.ValueOf(test.in).Elem(), dec) 575 if e, ok := err.(*gcerr.Error); !ok || err == nil || e.Code != gcerr.InvalidArgument { 576 t.Errorf("%s: got %v, want InvalidArgument Error", test.desc, err) 577 } 578 } 579 } 580 581 func TestDecodeFail(t *testing.T) { 582 // Verify that failure to decode a value results in an error. 583 for _, in := range []interface{}{ 584 new(interface{}), new(bool), new(string), new(int), new(uint), new(float32), 585 new([]byte), new([]int), new(map[string]interface{}), 586 } { 587 dec := &failDecoder{} 588 err := Decode(reflect.ValueOf(in).Elem(), dec) 589 if e, ok := err.(*gcerr.Error); !ok || err == nil || e.Code != gcerr.InvalidArgument { 590 t.Errorf("%T: got %v, want InvalidArgument Error", in, err) 591 } 592 } 593 } 594 595 type testDecoder struct { 596 val interface{} // assume encoded by testEncoder. 597 exactMatch bool 598 } 599 600 func (d testDecoder) String() string { 601 return fmt.Sprintf("%+v of type %T", d.val, d.val) 602 } 603 604 func (d testDecoder) AsNull() bool { 605 return d.val == nil 606 } 607 608 func (d testDecoder) AsBool() (bool, bool) { x, ok := d.val.(bool); return x, ok } 609 func (d testDecoder) AsString() (string, bool) { x, ok := d.val.(string); return x, ok } 610 611 func (d testDecoder) AsInt() (int64, bool) { 612 switch v := d.val.(type) { 613 case int64: 614 return v, true 615 case int: 616 return int64(v), true 617 default: 618 return 0, false 619 } 620 } 621 622 func (d testDecoder) AsUint() (uint64, bool) { 623 switch v := d.val.(type) { 624 case uint64: 625 return v, true 626 case uint: 627 return uint64(v), true 628 default: 629 return 0, false 630 } 631 } 632 633 func (d testDecoder) AsFloat() (float64, bool) { x, ok := d.val.(float64); return x, ok } 634 func (d testDecoder) AsBytes() ([]byte, bool) { x, ok := d.val.([]byte); return x, ok } 635 636 func (d testDecoder) ListLen() (int, bool) { 637 l, ok := d.val.([]interface{}) 638 if !ok { 639 return 0, false 640 } 641 return len(l), true 642 } 643 644 func (d testDecoder) DecodeList(f func(i int, vd Decoder) bool) { 645 for i, v := range d.val.([]interface{}) { 646 if !f(i, testDecoder{v, d.exactMatch}) { 647 break 648 } 649 } 650 } 651 func (d testDecoder) MapLen() (int, bool) { 652 if m, ok := d.val.(map[string]interface{}); ok { 653 return len(m), true 654 } 655 return 0, false 656 } 657 658 func (d testDecoder) DecodeMap(f func(key string, vd Decoder, exactMatch bool) bool) { 659 for k, v := range d.val.(map[string]interface{}) { 660 if !f(k, testDecoder{v, d.exactMatch}, d.exactMatch) { 661 break 662 } 663 } 664 } 665 func (d testDecoder) AsInterface() (interface{}, error) { 666 return d.val, nil 667 } 668 669 func (d testDecoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { 670 switch v.Type() { 671 case typeOfSpecial: 672 return true, special(d.val.(int)), nil 673 case typeOfBadSpecial: 674 return true, nil, errors.New("bad special") 675 default: 676 return false, nil, nil 677 } 678 } 679 680 // All of failDecoder's methods return failure. 681 type failDecoder struct{} 682 683 func (failDecoder) String() string { return "failDecoder" } 684 func (failDecoder) AsNull() bool { return false } 685 func (failDecoder) AsBool() (bool, bool) { return false, false } 686 func (failDecoder) AsString() (string, bool) { return "", false } 687 func (failDecoder) AsInt() (int64, bool) { return 0, false } 688 func (failDecoder) AsUint() (uint64, bool) { return 0, false } 689 func (failDecoder) AsFloat() (float64, bool) { return 0, false } 690 func (failDecoder) AsBytes() ([]byte, bool) { return nil, false } 691 func (failDecoder) ListLen() (int, bool) { return 0, false } 692 func (failDecoder) DecodeList(func(i int, vd Decoder) bool) { panic("impossible") } 693 func (failDecoder) MapLen() (int, bool) { return 0, false } 694 func (failDecoder) DecodeMap(func(string, Decoder, bool) bool) { panic("impossible") } 695 func (failDecoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { return false, nil, nil } 696 func (failDecoder) AsInterface() (interface{}, error) { return nil, errors.New("fail") }