github.com/jbendotnet/noms@v0.0.0-20190904222105-c43e4293ea92/go/marshal/encode_test.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package marshal 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "math" 12 "regexp" 13 "strings" 14 "testing" 15 16 "github.com/attic-labs/noms/go/types" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestEncode(tt *testing.T) { 21 vs := newTestValueStore() 22 defer vs.Close() 23 24 t := func(exp types.Value, v interface{}) { 25 actual, err := Marshal(vs, v) 26 assert.NoError(tt, err) 27 assert.True(tt, exp.Equals(actual)) 28 29 // Encode again for fallthrough 30 actual2, err := Marshal(vs, actual) 31 assert.NoError(tt, err) 32 assert.True(tt, exp.Equals(actual2)) 33 } 34 35 for _, n := range []float32{0, 42, 3.14159265359, math.MaxFloat32} { 36 t(types.Number(n), n) 37 t(types.Number(-n), -n) 38 } 39 40 for _, n := range []float64{0, 42, 3.14159265359, 9007199254740991, math.MaxFloat64} { 41 t(types.Number(n), n) 42 t(types.Number(-n), -n) 43 } 44 45 for _, n := range []int8{0, 42, math.MaxInt8} { 46 t(types.Number(n), n) 47 t(types.Number(-n), -n) 48 } 49 50 for _, n := range []int16{0, 42, math.MaxInt16} { 51 t(types.Number(n), n) 52 t(types.Number(-n), -n) 53 } 54 55 for _, n := range []int32{0, 42, math.MaxInt32} { 56 t(types.Number(n), n) 57 t(types.Number(-n), -n) 58 } 59 60 // int is at least int32 61 for _, n := range []int{0, 42, math.MaxInt32} { 62 t(types.Number(n), n) 63 t(types.Number(-n), -n) 64 } 65 66 for _, n := range []int64{0, 42, math.MaxInt64} { 67 t(types.Number(n), n) 68 t(types.Number(-n), -n) 69 } 70 71 for _, n := range []uint8{0, 42, math.MaxUint8} { 72 t(types.Number(n), n) 73 } 74 75 for _, n := range []uint16{0, 42, math.MaxUint16} { 76 t(types.Number(n), n) 77 } 78 79 for _, n := range []uint32{0, 42, math.MaxUint32} { 80 t(types.Number(n), n) 81 } 82 83 // uint is at least uint32 84 for _, n := range []uint{0, 42, math.MaxUint32} { 85 t(types.Number(n), n) 86 } 87 88 for _, n := range []uint64{0, 42, math.MaxUint64} { 89 t(types.Number(n), n) 90 } 91 92 t(types.Bool(true), true) 93 t(types.Bool(false), false) 94 95 for _, s := range []string{"", "s", "hello", "💩"} { 96 t(types.String(s), s) 97 } 98 99 t(types.NewList(vs, types.Number(42)), types.NewList(vs, types.Number(42))) 100 t(types.NewMap(vs, types.Number(42), types.String("hi")), types.NewMap(vs, types.Number(42), types.String("hi"))) 101 t(types.NewSet(vs, types.String("bye")), types.NewSet(vs, types.String("bye"))) 102 t(types.NewBlob(vs, bytes.NewBufferString("hello")), types.NewBlob(vs, bytes.NewBufferString("hello"))) 103 104 type TestStruct struct { 105 Str string 106 Num float64 107 } 108 t(types.NewStruct("TestStruct", types.StructData{ 109 "num": types.Number(42), 110 "str": types.String("Hello"), 111 }), TestStruct{Str: "Hello", Num: 42}) 112 // Same again to test caching 113 t(types.NewStruct("TestStruct", types.StructData{ 114 "num": types.Number(1), 115 "str": types.String("Bye"), 116 }), TestStruct{Str: "Bye", Num: 1}) 117 118 anonStruct := struct { 119 B bool 120 }{ 121 true, 122 } 123 t(types.NewStruct("", types.StructData{ 124 "b": types.Bool(true), 125 }), anonStruct) 126 127 type TestNestedStruct struct { 128 A types.List 129 B TestStruct 130 C float64 131 } 132 t(types.NewStruct("TestNestedStruct", types.StructData{ 133 "a": types.NewList(vs, types.String("hi")), 134 "b": types.NewStruct("TestStruct", types.StructData{ 135 "str": types.String("bye"), 136 "num": types.Number(5678), 137 }), 138 "c": types.Number(1234), 139 }), TestNestedStruct{ 140 A: types.NewList(vs, types.String("hi")), 141 B: TestStruct{ 142 Str: "bye", 143 Num: 5678, 144 }, 145 C: 1234, 146 }) 147 148 type testStruct struct { 149 Str string 150 Num float64 151 } 152 t(types.NewStruct("TestStruct", types.StructData{ 153 "num": types.Number(42), 154 "str": types.String("Hello"), 155 }), testStruct{Str: "Hello", Num: 42}) 156 } 157 158 func assertEncodeErrorMessage(t *testing.T, v interface{}, expectedMessage string) { 159 vs := newTestValueStore() 160 defer vs.Close() 161 162 _, err := Marshal(vs, v) 163 assert.Error(t, err) 164 assert.Equal(t, expectedMessage, err.Error()) 165 } 166 167 func TestInvalidTypes(t *testing.T) { 168 assertEncodeErrorMessage(t, make(chan int), "Type is not supported, type: chan int") 169 x := 42 170 assertEncodeErrorMessage(t, &x, "Type is not supported, type: *int") 171 } 172 173 func TestEncodeEmbeddedStructSkip(t *testing.T) { 174 assert := assert.New(t) 175 176 vs := newTestValueStore() 177 defer vs.Close() 178 179 type EmbeddedStruct struct { 180 X int 181 } 182 type TestStruct struct { 183 EmbeddedStruct `noms:"-"` 184 Y int 185 } 186 s := TestStruct{EmbeddedStruct{1}, 2} 187 v, err := Marshal(vs, s) 188 assert.NoError(err) 189 assert.True(types.NewStruct("TestStruct", types.StructData{ 190 "y": types.Number(2), 191 }).Equals(v)) 192 } 193 194 func TestEncodeEmbeddedStructWithName(t *testing.T) { 195 assert := assert.New(t) 196 197 vs := newTestValueStore() 198 defer vs.Close() 199 200 type EmbeddedStruct struct { 201 X int 202 } 203 type TestStruct struct { 204 EmbeddedStruct `noms:"em"` 205 Y int 206 } 207 s := TestStruct{EmbeddedStruct{1}, 2} 208 v, err := Marshal(vs, s) 209 assert.NoError(err) 210 assert.True(types.NewStruct("TestStruct", types.StructData{ 211 "em": types.NewStruct("EmbeddedStruct", types.StructData{ 212 "x": types.Number(1), 213 }), 214 "y": types.Number(2), 215 }).Equals(v)) 216 } 217 218 func TestEncodeEmbeddedStruct(t *testing.T) { 219 assert := assert.New(t) 220 221 vs := newTestValueStore() 222 defer vs.Close() 223 224 type EmbeddedStruct struct { 225 X int 226 } 227 type TestStruct struct { 228 EmbeddedStruct 229 } 230 s := TestStruct{EmbeddedStruct{1}} 231 v, err := Marshal(vs, s) 232 assert.NoError(err) 233 assert.True(types.NewStruct("TestStruct", types.StructData{ 234 "x": types.Number(1), 235 }).Equals(v)) 236 237 type TestOuter struct { 238 A int 239 TestStruct 240 B int 241 } 242 s2 := TestOuter{0, TestStruct{EmbeddedStruct{1}}, 2} 243 v2, err := Marshal(vs, s2) 244 assert.NoError(err) 245 assert.True(types.NewStruct("TestOuter", types.StructData{ 246 "a": types.Number(0), 247 "b": types.Number(2), 248 "x": types.Number(1), 249 }).Equals(v2)) 250 } 251 252 func TestEncodeEmbeddedStructOriginal(t *testing.T) { 253 assert := assert.New(t) 254 255 vs := newTestValueStore() 256 defer vs.Close() 257 258 type EmbeddedStruct struct { 259 X int 260 O types.Struct `noms:",original"` 261 B bool 262 } 263 type TestStruct struct { 264 EmbeddedStruct 265 } 266 s := TestStruct{ 267 EmbeddedStruct: EmbeddedStruct{ 268 X: 1, 269 B: true, 270 }, 271 } 272 v, err := Marshal(vs, s) 273 assert.NoError(err) 274 assert.True(types.NewStruct("TestStruct", types.StructData{ 275 "b": types.Bool(true), 276 "x": types.Number(1), 277 }).Equals(v)) 278 } 279 280 func TestEncodeNonExportedField(t *testing.T) { 281 type TestStruct struct { 282 x int 283 } 284 assertEncodeErrorMessage(t, TestStruct{1}, "Non exported fields are not supported, type: marshal.TestStruct") 285 } 286 287 func TestEncodeTaggingSkip(t *testing.T) { 288 assert := assert.New(t) 289 290 vs := newTestValueStore() 291 defer vs.Close() 292 293 type S struct { 294 Abc int `noms:"-"` 295 Def bool 296 } 297 s := S{42, true} 298 v, err := Marshal(vs, s) 299 assert.NoError(err) 300 assert.True(types.NewStruct("S", types.StructData{ 301 "def": types.Bool(true), 302 }).Equals(v)) 303 } 304 305 func TestEncodeNamedFields(t *testing.T) { 306 assert := assert.New(t) 307 308 vs := newTestValueStore() 309 defer vs.Close() 310 311 type S struct { 312 Aaa int `noms:"a"` 313 Bbb bool `noms:"B"` 314 Ccc string 315 } 316 s := S{42, true, "Hi"} 317 v, err := Marshal(vs, s) 318 assert.NoError(err) 319 assert.True(types.NewStruct("S", types.StructData{ 320 "a": types.Number(42), 321 "B": types.Bool(true), 322 "ccc": types.String("Hi"), 323 }).Equals(v)) 324 } 325 326 func TestEncodeInvalidNamedFields(t *testing.T) { 327 type S struct { 328 A int `noms:"1a"` 329 } 330 assertEncodeErrorMessage(t, S{42}, "Invalid struct field name: 1a") 331 } 332 333 func TestEncodeOmitEmpty(t *testing.T) { 334 assert := assert.New(t) 335 336 vs := newTestValueStore() 337 defer vs.Close() 338 339 type S struct { 340 String string `noms:",omitempty"` 341 Bool bool `noms:",omitempty"` 342 Int int `noms:",omitempty"` 343 Int8 int8 `noms:",omitempty"` 344 Int16 int16 `noms:",omitempty"` 345 Int32 int32 `noms:",omitempty"` 346 Int64 int64 `noms:",omitempty"` 347 Uint uint `noms:",omitempty"` 348 Uint8 uint8 `noms:",omitempty"` 349 Uint16 uint16 `noms:",omitempty"` 350 Uint32 uint32 `noms:",omitempty"` 351 Uint64 uint64 `noms:",omitempty"` 352 Float32 float32 `noms:",omitempty"` 353 Float64 float64 `noms:",omitempty"` 354 } 355 s := S{ 356 String: "s", 357 Bool: true, 358 Int: 1, 359 Int8: 1, 360 Int16: 1, 361 Int32: 1, 362 Int64: 1, 363 Uint: 1, 364 Uint8: 1, 365 Uint16: 1, 366 Uint32: 1, 367 Uint64: 1, 368 Float32: 1, 369 Float64: 1, 370 } 371 v, err := Marshal(vs, s) 372 assert.NoError(err) 373 assert.True(types.NewStruct("S", types.StructData{ 374 "string": types.String("s"), 375 "bool": types.Bool(true), 376 "int": types.Number(1), 377 "int8": types.Number(1), 378 "int16": types.Number(1), 379 "int32": types.Number(1), 380 "int64": types.Number(1), 381 "uint": types.Number(1), 382 "uint8": types.Number(1), 383 "uint16": types.Number(1), 384 "uint32": types.Number(1), 385 "uint64": types.Number(1), 386 "float32": types.Number(1), 387 "float64": types.Number(1), 388 }).Equals(v)) 389 390 s2 := S{ 391 String: "", 392 Bool: false, 393 Int: 0, 394 Int8: 0, 395 Int16: 0, 396 Int32: 0, 397 Int64: 0, 398 Uint: 0, 399 Uint8: 0, 400 Uint16: 0, 401 Uint32: 0, 402 Uint64: 0, 403 Float32: 0, 404 Float64: 0, 405 } 406 v2, err := Marshal(vs, s2) 407 assert.NoError(err) 408 assert.True(types.NewStruct("S", types.StructData{}).Equals(v2)) 409 410 type S2 struct { 411 Slice []int `noms:",omitempty"` 412 Map map[int]int `noms:",omitempty"` 413 } 414 415 s3 := S2{ 416 Slice: []int{0}, 417 Map: map[int]int{0: 0}, 418 } 419 v3, err := Marshal(vs, s3) 420 assert.NoError(err) 421 assert.True(types.NewStruct("S2", types.StructData{ 422 "slice": types.NewList(vs, types.Number(0)), 423 "map": types.NewMap(vs, types.Number(0), types.Number(0)), 424 }).Equals(v3)) 425 426 s4 := S2{ 427 Slice: []int{}, 428 Map: map[int]int{}, 429 } 430 v4, err := Marshal(vs, s4) 431 assert.NoError(err) 432 assert.True(types.NewStruct("S2", types.StructData{}).Equals(v4)) 433 434 s5 := S2{ 435 Slice: nil, 436 Map: nil, 437 } 438 v5, err := Marshal(vs, s5) 439 assert.NoError(err) 440 assert.True(types.NewStruct("S2", types.StructData{}).Equals(v5)) 441 442 type S3 struct { 443 List types.List `noms:",omitempty"` 444 Value types.Value `noms:",omitempty"` 445 } 446 s6 := S3{ 447 List: types.NewList(vs), 448 Value: types.Number(0), 449 } 450 v6, err := Marshal(vs, s6) 451 assert.NoError(err) 452 assert.True(types.NewStruct("S3", types.StructData{ 453 "list": types.NewList(vs), 454 "value": types.Number(0), 455 }).Equals(v6)) 456 457 s7 := S3{ 458 List: types.List{}, 459 Value: nil, 460 } 461 v7, err := Marshal(vs, s7) 462 assert.NoError(err) 463 assert.True(types.NewStruct("S3", types.StructData{}).Equals(v7)) 464 465 // Both name and omitempty 466 type S4 struct { 467 X int `noms:"y,omitempty"` 468 } 469 s8 := S4{ 470 X: 1, 471 } 472 v8, err := Marshal(vs, s8) 473 assert.NoError(err) 474 assert.True(types.NewStruct("S4", types.StructData{ 475 "y": types.Number(1), 476 }).Equals(v8)) 477 478 s9 := S4{ 479 X: 0, 480 } 481 v9, err := Marshal(vs, s9) 482 assert.NoError(err) 483 assert.True(types.NewStruct("S4", types.StructData{}).Equals(v9)) 484 } 485 486 func ExampleMarshal() { 487 vs := newTestValueStore() 488 defer vs.Close() 489 490 type Person struct { 491 Given string 492 Male bool 493 } 494 arya, err := Marshal(vs, Person{"Arya", false}) 495 if err != nil { 496 fmt.Println(err) 497 return 498 } 499 500 fmt.Printf("Given: %s, Male: %t\n", arya.(types.Struct).Get("given").(types.String), arya.(types.Struct).Get("male").(types.Bool)) 501 // Output: Given: Arya, Male: false 502 } 503 504 func TestEncodeSlice(t *testing.T) { 505 assert := assert.New(t) 506 507 vs := newTestValueStore() 508 defer vs.Close() 509 510 v, err := Marshal(vs, []string{"a", "b", "c"}) 511 assert.NoError(err) 512 assert.True(types.NewList(vs, types.String("a"), types.String("b"), types.String("c")).Equals(v)) 513 } 514 515 func TestEncodeArray(t *testing.T) { 516 assert := assert.New(t) 517 518 vs := newTestValueStore() 519 defer vs.Close() 520 521 v, err := Marshal(vs, [3]int{1, 2, 3}) 522 assert.NoError(err) 523 assert.True(types.NewList(vs, types.Number(1), types.Number(2), types.Number(3)).Equals(v)) 524 } 525 526 func TestEncodeStructWithSlice(t *testing.T) { 527 assert := assert.New(t) 528 529 vs := newTestValueStore() 530 defer vs.Close() 531 532 type S struct { 533 List []int 534 } 535 v, err := Marshal(vs, S{[]int{1, 2, 3}}) 536 assert.NoError(err) 537 assert.True(types.NewStruct("S", types.StructData{ 538 "list": types.NewList(vs, types.Number(1), types.Number(2), types.Number(3)), 539 }).Equals(v)) 540 } 541 542 func TestEncodeStructWithArrayOfNomsValue(t *testing.T) { 543 assert := assert.New(t) 544 545 vs := newTestValueStore() 546 defer vs.Close() 547 548 type S struct { 549 List [1]types.Set 550 } 551 v, err := Marshal(vs, S{[1]types.Set{types.NewSet(vs, types.Bool(true))}}) 552 assert.NoError(err) 553 assert.True(types.NewStruct("S", types.StructData{ 554 "list": types.NewList(vs, types.NewSet(vs, types.Bool(true))), 555 }).Equals(v)) 556 } 557 558 func TestEncodeNomsTypePtr(t *testing.T) { 559 assert := assert.New(t) 560 561 vs := newTestValueStore() 562 defer vs.Close() 563 564 testMarshal := func(g interface{}, expected types.Value) { 565 v, err := Marshal(vs, g) 566 assert.NoError(err) 567 assert.Equal(expected, v) 568 } 569 570 type S struct { 571 Type *types.Type 572 } 573 574 primitive := types.StringType 575 testMarshal(S{primitive}, types.NewStruct("S", types.StructData{"type": primitive})) 576 577 complex := types.MakeStructType("Complex", 578 types.StructField{ 579 Name: "stuff", 580 Type: types.StringType, 581 }, 582 ) 583 testMarshal(S{complex}, types.NewStruct("S", types.StructData{"type": complex})) 584 } 585 586 func TestEncodeRecursive(t *testing.T) { 587 assert := assert.New(t) 588 589 vs := newTestValueStore() 590 defer vs.Close() 591 592 type Node struct { 593 Value int 594 Children []Node 595 } 596 v, err := Marshal(vs, Node{ 597 1, []Node{ 598 {2, []Node{}}, 599 {3, []Node(nil)}, 600 }, 601 }) 602 assert.NoError(err) 603 604 typ := types.MakeStructType("Node", 605 types.StructField{ 606 Name: "children", 607 Type: types.MakeListType(types.MakeCycleType("Node")), 608 }, 609 types.StructField{ 610 Name: "value", 611 Type: types.NumberType, 612 }, 613 ) 614 assert.True(typ.Equals(types.TypeOf(v))) 615 616 assert.True(types.NewStruct("Node", types.StructData{ 617 "children": types.NewList( 618 vs, 619 types.NewStruct("Node", types.StructData{ 620 "children": types.NewList(vs), 621 "value": types.Number(2), 622 }), 623 types.NewStruct("Node", types.StructData{ 624 "children": types.NewList(vs), 625 "value": types.Number(3), 626 }), 627 ), 628 "value": types.Number(1), 629 }).Equals(v)) 630 } 631 632 func TestEncodeMap(t *testing.T) { 633 assert := assert.New(t) 634 635 vs := newTestValueStore() 636 defer vs.Close() 637 638 v, err := Marshal(vs, map[string]int{"a": 1, "b": 2, "c": 3}) 639 assert.NoError(err) 640 assert.True(types.NewMap( 641 vs, 642 types.String("a"), types.Number(1), 643 types.String("b"), types.Number(2), 644 types.String("c"), types.Number(3)).Equals(v)) 645 646 type S struct { 647 N string 648 } 649 v, err = Marshal(vs, map[S]bool{S{"Yes"}: true, S{"No"}: false}) 650 assert.NoError(err) 651 assert.True(types.NewMap( 652 vs, 653 types.NewStruct("S", types.StructData{"n": types.String("Yes")}), types.Bool(true), 654 types.NewStruct("S", types.StructData{"n": types.String("No")}), types.Bool(false)).Equals(v)) 655 656 v, err = Marshal(vs, map[string]int(nil)) 657 assert.NoError(err) 658 assert.True(types.NewMap(vs).Equals(v)) 659 660 v, err = Marshal(vs, map[string]int{}) 661 assert.NoError(err) 662 assert.True(types.NewMap(vs).Equals(v)) 663 } 664 665 func TestEncodeInterface(t *testing.T) { 666 assert := assert.New(t) 667 668 vs := newTestValueStore() 669 defer vs.Close() 670 671 var i interface{} 672 i = []string{"a", "b"} 673 v, err := Marshal(vs, i) 674 assert.NoError(err) 675 assert.True(types.NewList(vs, types.String("a"), types.String("b")).Equals(v)) 676 677 i = map[interface{}]interface{}{"a": true, struct{ Name string }{"b"}: 42} 678 v, err = Marshal(vs, i) 679 assert.NoError(err) 680 assert.True(types.NewMap( 681 vs, 682 types.String("a"), types.Bool(true), 683 types.NewStruct("", types.StructData{"name": types.String("b")}), types.Number(42), 684 ).Equals(v)) 685 } 686 687 func TestEncodeSet(t *testing.T) { 688 assert := assert.New(t) 689 690 vs := newTestValueStore() 691 defer vs.Close() 692 693 v, err := Marshal(vs, struct { 694 A map[int]struct{} `noms:",set"` 695 B map[int]struct{} 696 C map[int]string `noms:",set"` 697 D map[string]struct{} `noms:",set"` 698 E map[string]struct{} 699 F map[string]int `noms:",set"` 700 G []int `noms:",set"` 701 H string `noms:",set"` 702 }{ 703 map[int]struct{}{0: {}, 1: {}, 2: {}}, 704 map[int]struct{}{3: {}, 4: {}, 5: {}}, 705 map[int]string{}, 706 map[string]struct{}{"A": {}, "B": {}, "C": {}}, 707 map[string]struct{}{"D": {}, "E": {}, "F": {}}, 708 map[string]int{}, 709 []int{1, 2, 3}, 710 "", 711 }) 712 assert.NoError(err) 713 s, ok := v.(types.Struct) 714 assert.True(ok) 715 716 expect := map[string]types.NomsKind{ 717 "a": types.SetKind, 718 "b": types.MapKind, 719 "c": types.MapKind, 720 "d": types.SetKind, 721 "e": types.MapKind, 722 "f": types.MapKind, 723 "g": types.SetKind, 724 "h": types.StringKind, 725 } 726 for fieldName, kind := range expect { 727 assert.Equal(kind, s.Get(fieldName).Kind()) 728 } 729 730 // Test both the Set values are correct, and that the equivalent typed Map 731 // are correct in case the Set marshaling interferes with it. 732 733 a := s.Get("a").(types.Set) 734 assert.True(a.Has(types.Number(0))) 735 assert.True(a.Has(types.Number(1))) 736 assert.True(a.Has(types.Number(2))) 737 738 b := s.Get("b").(types.Map) 739 assert.True(b.Has(types.Number(3))) 740 assert.True(b.Has(types.Number(4))) 741 assert.True(b.Has(types.Number(5))) 742 743 d := s.Get("d").(types.Set) 744 assert.True(d.Has(types.String("A"))) 745 assert.True(d.Has(types.String("B"))) 746 assert.True(d.Has(types.String("C"))) 747 748 e := s.Get("e").(types.Map) 749 assert.True(e.Has(types.String("D"))) 750 assert.True(e.Has(types.String("E"))) 751 assert.True(e.Has(types.String("F"))) 752 753 g := s.Get("g").(types.Set) 754 assert.True(g.Has(types.Number(1))) 755 assert.True(g.Has(types.Number(2))) 756 assert.True(g.Has(types.Number(3))) 757 } 758 759 func TestEncodeOpt(t *testing.T) { 760 assert := assert.New(t) 761 762 vs := newTestValueStore() 763 defer vs.Close() 764 765 tc := []struct { 766 in interface{} 767 opt Opt 768 wantValue types.Value 769 }{ 770 { 771 []string{"a", "b"}, 772 Opt{}, 773 types.NewList(vs, types.String("a"), types.String("b")), 774 }, 775 { 776 []string{"a", "b"}, 777 Opt{Set: true}, 778 types.NewSet(vs, types.String("a"), types.String("b")), 779 }, 780 { 781 map[string]struct{}{"a": struct{}{}, "b": struct{}{}}, 782 Opt{}, 783 types.NewMap(vs, types.String("a"), types.NewStruct("", nil), types.String("b"), types.NewStruct("", nil)), 784 }, 785 { 786 map[string]struct{}{"a": struct{}{}, "b": struct{}{}}, 787 Opt{Set: true}, 788 types.NewSet(vs, types.String("a"), types.String("b")), 789 }, 790 } 791 792 for _, t := range tc { 793 r, err := MarshalOpt(vs, t.in, t.opt) 794 assert.True(t.wantValue.Equals(r)) 795 assert.Nil(err) 796 } 797 } 798 799 func TestEncodeSetWithTags(t *testing.T) { 800 assert := assert.New(t) 801 802 vs := newTestValueStore() 803 defer vs.Close() 804 805 v, err := Marshal(vs, struct { 806 A map[int]struct{} `noms:"foo,set"` 807 B map[int]struct{} `noms:",omitempty,set"` 808 C map[int]struct{} `noms:"bar,omitempty,set"` 809 }{ 810 A: map[int]struct{}{0: {}, 1: {}}, 811 C: map[int]struct{}{2: {}, 3: {}}, 812 }) 813 assert.NoError(err) 814 s, ok := v.(types.Struct) 815 assert.True(ok) 816 817 _, ok = s.MaybeGet("a") 818 assert.False(ok) 819 _, ok = s.MaybeGet("b") 820 assert.False(ok) 821 _, ok = s.MaybeGet("c") 822 assert.False(ok) 823 824 foo, ok := s.Get("foo").(types.Set) 825 assert.True(ok) 826 assert.True(types.NewSet(vs, types.Number(0), types.Number(1)).Equals(foo)) 827 828 bar, ok := s.Get("bar").(types.Set) 829 assert.True(ok) 830 assert.True(types.NewSet(vs, types.Number(2), types.Number(3)).Equals(bar)) 831 } 832 833 func TestInvalidTag(t *testing.T) { 834 vs := newTestValueStore() 835 defer vs.Close() 836 837 _, err := Marshal(vs, struct { 838 F string `noms:",omitEmpty"` 839 }{"F"}) 840 assert.Error(t, err) 841 assert.Equal(t, `Unrecognized tag: omitEmpty`, err.Error()) 842 } 843 844 func TestEncodeCanSkipUnexportedField(t *testing.T) { 845 assert := assert.New(t) 846 847 vs := newTestValueStore() 848 defer vs.Close() 849 850 type S struct { 851 Abc int 852 notExported bool `noms:"-"` 853 } 854 s := S{42, true} 855 v, err := Marshal(vs, s) 856 assert.NoError(err) 857 assert.True(types.NewStruct("S", types.StructData{ 858 "abc": types.Number(42), 859 }).Equals(v)) 860 } 861 862 func TestEncodeOriginal(t *testing.T) { 863 assert := assert.New(t) 864 865 vs := newTestValueStore() 866 defer vs.Close() 867 868 type S struct { 869 Foo int `noms:",omitempty"` 870 Bar types.Struct `noms:",original"` 871 } 872 873 var s S 874 var err error 875 var orig types.Struct 876 877 // New field value clobbers old field value 878 orig = types.NewStruct("S", types.StructData{ 879 "foo": types.Number(42), 880 }) 881 err = Unmarshal(orig, &s) 882 assert.NoError(err) 883 s.Foo = 43 884 assert.True(MustMarshal(vs, s).Equals(orig.Set("foo", types.Number(43)))) 885 886 // New field extends old struct 887 orig = types.NewStruct("S", types.StructData{}) 888 err = Unmarshal(orig, &s) 889 assert.NoError(err) 890 s.Foo = 43 891 assert.True(MustMarshal(vs, s).Equals(orig.Set("foo", types.Number(43)))) 892 893 // Old struct name always used 894 orig = types.NewStruct("Q", types.StructData{}) 895 err = Unmarshal(orig, &s) 896 assert.NoError(err) 897 s.Foo = 43 898 assert.True(MustMarshal(vs, s).Equals(orig.Set("foo", types.Number(43)))) 899 900 // Field type of base are preserved 901 orig = types.NewStruct("S", types.StructData{ 902 "foo": types.Number(42), 903 }) 904 err = Unmarshal(orig, &s) 905 assert.NoError(err) 906 s.Foo = 43 907 out := MustMarshal(vs, s) 908 assert.True(out.Equals(orig.Set("foo", types.Number(43)))) 909 910 st2 := types.MakeStructTypeFromFields("S", types.FieldMap{ 911 "foo": types.NumberType, 912 }) 913 assert.True(types.TypeOf(out).Equals(st2)) 914 915 // It's OK to have an empty original field 916 s = S{ 917 Foo: 42, 918 } 919 assert.True(MustMarshal(vs, s).Equals( 920 types.NewStruct("S", types.StructData{"foo": types.Number(float64(42))}))) 921 } 922 923 func TestNomsTypes(t *testing.T) { 924 assert := assert.New(t) 925 926 vs := newTestValueStore() 927 defer vs.Close() 928 929 type S struct { 930 Blob types.Blob 931 Bool types.Bool 932 Number types.Number 933 String types.String 934 Type *types.Type 935 } 936 s := S{ 937 Blob: types.NewBlob(vs), 938 Bool: types.Bool(true), 939 Number: types.Number(42), 940 String: types.String("hi"), 941 Type: types.NumberType, 942 } 943 assert.True(MustMarshal(vs, s).Equals( 944 types.NewStruct("S", types.StructData{ 945 "blob": types.NewBlob(vs), 946 "bool": types.Bool(true), 947 "number": types.Number(42), 948 "string": types.String("hi"), 949 "type": types.NumberType, 950 }), 951 )) 952 } 953 954 type primitiveType int 955 956 func (t primitiveType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 957 return types.Number(int(t) + 1), nil 958 } 959 960 func TestMarshalerPrimitiveType(t *testing.T) { 961 assert := assert.New(t) 962 963 vs := newTestValueStore() 964 defer vs.Close() 965 966 u := primitiveType(42) 967 v := MustMarshal(vs, u) 968 assert.Equal(types.Number(43), v) 969 } 970 971 type primitiveSliceType []string 972 973 func (u primitiveSliceType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 974 return types.String(strings.Join(u, ",")), nil 975 } 976 977 func TestMarshalerPrimitiveSliceType(t *testing.T) { 978 assert := assert.New(t) 979 980 vs := newTestValueStore() 981 defer vs.Close() 982 983 u := primitiveSliceType([]string{"a", "b", "c"}) 984 v := MustMarshal(vs, u) 985 assert.Equal(types.String("a,b,c"), v) 986 } 987 988 type primitiveMapType map[string]string 989 990 func (u primitiveMapType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 991 var vals types.ValueSlice 992 for k, v := range u { 993 vals = append(vals, types.String(k+","+v)) 994 } 995 return types.NewSet(vrw, vals...), nil 996 } 997 998 func TestMarshalerPrimitiveMapType(t *testing.T) { 999 assert := assert.New(t) 1000 1001 vs := newTestValueStore() 1002 defer vs.Close() 1003 1004 u := primitiveMapType(map[string]string{ 1005 "a": "foo", 1006 "b": "bar", 1007 }) 1008 v := MustMarshal(vs, u) 1009 assert.True(types.NewSet(vs, types.String("a,foo"), types.String("b,bar")).Equals(v)) 1010 } 1011 1012 type primitiveStructType struct { 1013 x, y int 1014 } 1015 1016 func (u primitiveStructType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1017 return types.Number(u.x + u.y), nil 1018 } 1019 1020 func TestMarshalerPrimitiveStructType(t *testing.T) { 1021 assert := assert.New(t) 1022 1023 vs := newTestValueStore() 1024 defer vs.Close() 1025 1026 u := primitiveStructType{1, 2} 1027 v := MustMarshal(vs, u) 1028 assert.Equal(types.Number(3), v) 1029 } 1030 1031 type builtinType regexp.Regexp 1032 1033 func (u builtinType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1034 r := regexp.Regexp(u) 1035 return types.String(r.String()), nil 1036 } 1037 1038 func TestMarshalerBuiltinType(t *testing.T) { 1039 assert := assert.New(t) 1040 1041 vs := newTestValueStore() 1042 defer vs.Close() 1043 1044 s := "[a-z]+$" 1045 r := regexp.MustCompile(s) 1046 u := builtinType(*r) 1047 v := MustMarshal(vs, u) 1048 assert.Equal(types.String(s), v) 1049 } 1050 1051 type wrappedMarshalerType primitiveType 1052 1053 func (u wrappedMarshalerType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1054 return types.Number(int(u) + 2), nil 1055 } 1056 1057 func TestMarshalerWrapperMarshalerType(t *testing.T) { 1058 assert := assert.New(t) 1059 1060 vs := newTestValueStore() 1061 defer vs.Close() 1062 1063 u := wrappedMarshalerType(primitiveType(42)) 1064 v := MustMarshal(vs, u) 1065 assert.Equal(types.Number(44), v) 1066 } 1067 1068 type TestComplexStructType struct { 1069 P primitiveType 1070 Ps []primitiveType 1071 Pm map[string]primitiveType 1072 Pslice primitiveSliceType 1073 Pmap primitiveMapType 1074 Pstruct primitiveStructType 1075 B builtinType 1076 } 1077 1078 func TestMarshalerComplexStructType(t *testing.T) { 1079 assert := assert.New(t) 1080 1081 vs := newTestValueStore() 1082 defer vs.Close() 1083 1084 s := "foo|bar" 1085 r := regexp.MustCompile(s) 1086 u := TestComplexStructType{ 1087 P: 42, 1088 Ps: []primitiveType{1, 2}, 1089 Pm: map[string]primitiveType{ 1090 "x": 100, 1091 "y": 101, 1092 }, 1093 Pslice: primitiveSliceType{"a", "b", "c"}, 1094 Pmap: primitiveMapType{ 1095 "c": "123", 1096 "d": "456", 1097 }, 1098 Pstruct: primitiveStructType{10, 20}, 1099 B: builtinType(*r), 1100 } 1101 1102 v := MustMarshal(vs, u) 1103 1104 assert.True(types.NewStruct("TestComplexStructType", types.StructData{ 1105 "p": types.Number(43), 1106 "ps": types.NewList(vs, types.Number(2), types.Number(3)), 1107 "pm": types.NewMap(vs, types.String("x"), types.Number(101), types.String("y"), types.Number(102)), 1108 "pslice": types.String("a,b,c"), 1109 "pmap": types.NewSet(vs, types.String("c,123"), types.String("d,456")), 1110 "pstruct": types.Number(30), 1111 "b": types.String(s), 1112 }).Equals(v)) 1113 } 1114 1115 type returnsMarshalerError struct { 1116 err error 1117 } 1118 1119 func (u returnsMarshalerError) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1120 return nil, u.err 1121 } 1122 1123 type returnsMarshalerNil struct{} 1124 1125 func (u returnsMarshalerNil) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1126 return nil, nil 1127 } 1128 1129 type panicsMarshaler struct{} 1130 1131 func (u panicsMarshaler) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) { 1132 panic("panic") 1133 } 1134 1135 func TestMarshalerErrors(t *testing.T) { 1136 assert := assert.New(t) 1137 1138 vs := newTestValueStore() 1139 defer vs.Close() 1140 1141 expErr := errors.New("expected error") 1142 m1 := returnsMarshalerError{expErr} 1143 _, actErr := Marshal(vs, m1) 1144 assert.Equal(expErr, actErr) 1145 1146 m2 := returnsMarshalerNil{} 1147 assert.Panics(func() { Marshal(vs, m2) }) 1148 1149 m3 := panicsMarshaler{} 1150 assert.Panics(func() { Marshal(vs, m3) }) 1151 } 1152 1153 type TestStructWithNameImpl struct { 1154 X int 1155 } 1156 1157 func (ts TestStructWithNameImpl) MarshalNomsStructName() string { 1158 return "A" 1159 } 1160 func TestMarshalStructName(t *testing.T) { 1161 assert := assert.New(t) 1162 1163 vs := newTestValueStore() 1164 defer vs.Close() 1165 1166 ts := TestStructWithNameImpl{ 1167 X: 1, 1168 } 1169 v := MustMarshal(vs, ts) 1170 assert.True(types.NewStruct("A", types.StructData{ 1171 "x": types.Number(1), 1172 }).Equals(v), types.EncodedValue(v)) 1173 } 1174 1175 type TestStructWithNameImpl2 struct { 1176 X int 1177 } 1178 1179 func (ts TestStructWithNameImpl2) MarshalNomsStructName() string { 1180 return "" 1181 } 1182 func TestMarshalStructName2(t *testing.T) { 1183 assert := assert.New(t) 1184 1185 vs := newTestValueStore() 1186 defer vs.Close() 1187 1188 ts := TestStructWithNameImpl2{ 1189 X: 1, 1190 } 1191 v := MustMarshal(vs, ts) 1192 assert.True(types.NewStruct("", types.StructData{ 1193 "x": types.Number(1), 1194 }).Equals(v), types.EncodedValue(v)) 1195 }