github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/marshal/decode_test.go (about) 1 // Copyright 2019 Dolthub, Inc. 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 // http://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 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package marshal 23 24 import ( 25 "bytes" 26 "context" 27 "errors" 28 "fmt" 29 "math" 30 "reflect" 31 "regexp" 32 "strings" 33 "testing" 34 35 "github.com/stretchr/testify/assert" 36 "github.com/stretchr/testify/require" 37 38 "github.com/dolthub/dolt/go/store/chunks" 39 "github.com/dolthub/dolt/go/store/d" 40 "github.com/dolthub/dolt/go/store/types" 41 ) 42 43 func mustGetValue(val types.Value, found bool, err error) types.Value { 44 d.PanicIfError(err) 45 d.PanicIfFalse(found) 46 return val 47 } 48 49 func mustValue(val types.Value, err error) types.Value { 50 d.PanicIfError(err) 51 return val 52 } 53 54 func mustList(l types.List, err error) types.List { 55 d.PanicIfError(err) 56 return l 57 } 58 59 func mustStruct(st types.Struct, err error) types.Struct { 60 d.PanicIfError(err) 61 return st 62 } 63 64 func mustSet(s types.Set, err error) types.Set { 65 d.PanicIfError(err) 66 return s 67 } 68 69 func mustType(t *types.Type, err error) *types.Type { 70 d.PanicIfError(err) 71 return t 72 } 73 74 func mustBlob(b types.Blob, err error) types.Blob { 75 d.PanicIfError(err) 76 return b 77 } 78 79 func mustString(str string, err error) string { 80 d.PanicIfError(err) 81 return str 82 } 83 84 func mustMarshalType(nbf *types.NomsBinFormat, v interface{}) *types.Type { 85 t, err := MarshalType(nbf, v) 86 d.PanicIfError(err) 87 88 return t 89 } 90 91 func TestDecode(tt *testing.T) { 92 assert := assert.New(tt) 93 vs := newTestValueStore() 94 defer vs.Close() 95 96 t := func(v types.Value, ptr interface{}, expected interface{}) { 97 p := reflect.ValueOf(ptr) 98 assert.Equal(reflect.Ptr, p.Type().Kind()) 99 err := Unmarshal(context.Background(), types.Format_7_18, v, p.Interface()) 100 require.NoError(tt, err) 101 if expectedValue, ok := expected.(types.Value); ok { 102 assert.True(expectedValue.Equals(p.Elem().Interface().(types.Value))) 103 } else { 104 assert.Equal(expected, p.Elem().Interface()) 105 } 106 107 // Also test that types.Value is passed through 108 var v2 types.Value 109 err = Unmarshal(context.Background(), types.Format_7_18, v, &v2) 110 require.NoError(tt, err) 111 assert.True(v.Equals(v2)) 112 } 113 114 for _, n := range []float32{0, 42, 3.14159265359, math.MaxFloat32} { 115 var f32 float32 116 t(types.Float(n), &f32, float32(n)) 117 } 118 119 for _, n := range []float64{0, 42, 3.14159265359, math.MaxFloat64} { 120 var f64 float64 121 t(types.Float(n), &f64, float64(n)) 122 } 123 124 for _, n := range []int8{0, 42, math.MaxInt8} { 125 var i8 int8 126 t(types.Float(n), &i8, int8(n)) 127 } 128 129 for _, n := range []int16{0, 42, math.MaxInt16} { 130 var i16 int16 131 t(types.Float(n), &i16, int16(n)) 132 } 133 134 for _, n := range []int32{0, 42, math.MaxInt32} { 135 var i32 int32 136 t(types.Float(n), &i32, int32(n)) 137 } 138 139 // int is at least int32 140 for _, n := range []int{0, 42, math.MaxInt32} { 141 var i int 142 t(types.Float(n), &i, int(n)) 143 } 144 145 // There is precision loss for values above Math.pow(2, 53) - 1 146 for _, n := range []int64{0, 42, int64(math.Pow(2, 53) - 1)} { 147 var i64 int64 148 t(types.Float(n), &i64, int64(n)) 149 } 150 151 for _, n := range []uint8{0, 42, math.MaxUint8} { 152 var ui8 uint8 153 t(types.Float(n), &ui8, uint8(n)) 154 } 155 156 for _, n := range []uint16{0, 42, math.MaxUint16} { 157 var ui16 uint16 158 t(types.Float(n), &ui16, uint16(n)) 159 } 160 161 for _, n := range []uint32{0, 42, math.MaxInt32} { 162 var ui32 uint32 163 t(types.Float(n), &ui32, uint32(n)) 164 } 165 166 // uint is at least uint32 167 for _, n := range []uint{0, 42, math.MaxInt32} { 168 var ui uint 169 t(types.Float(n), &ui, uint(n)) 170 } 171 172 // There is precision loss for values above Math.pow(2, 53) - 1 173 for _, n := range []uint64{0, 42, uint64(math.Pow(2, 53) - 1)} { 174 var ui64 uint64 175 t(types.Float(n), &ui64, uint64(n)) 176 } 177 178 var b bool 179 t(types.Bool(true), &b, true) 180 t(types.Bool(false), &b, false) 181 182 for _, s := range []string{"", "s", "hello", "💩"} { 183 var s2 string 184 t(types.String(s), &s2, s) 185 } 186 187 var list types.List 188 list2, err := types.NewList(context.Background(), vs, types.Float(42)) 189 require.NoError(tt, err) 190 t(list2, &list, list2) 191 192 var m types.Map 193 map2, err := types.NewMap(context.Background(), vs, types.Float(42), types.String("Hi")) 194 require.NoError(tt, err) 195 t(map2, &m, map2) 196 197 var set types.Set 198 set2, err := types.NewSet(context.Background(), vs, types.String("Bye")) 199 require.NoError(tt, err) 200 t(set2, &set, set2) 201 202 var blob types.Blob 203 blob2, err := types.NewBlob(context.Background(), vs, bytes.NewBufferString("hello")) 204 require.NoError(tt, err) 205 t(blob2, &blob, blob2) 206 207 type TestStruct struct { 208 B bool 209 A float64 210 C string 211 } 212 var ts TestStruct 213 214 t(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{ 215 "b": types.Bool(true), 216 "a": types.Float(42), 217 "c": types.String("hi"), 218 })), &ts, TestStruct{true, 42, "hi"}) 219 // again to test the caching 220 t(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{ 221 "b": types.Bool(false), 222 "a": types.Float(555), 223 "c": types.String("hello"), 224 })), &ts, TestStruct{false, 555, "hello"}) 225 226 var as struct { 227 X int32 228 Y bool 229 } 230 t(mustValue(types.NewStruct(types.Format_7_18, "", types.StructData{ 231 "y": types.Bool(true), 232 "x": types.Float(42), 233 })), &as, struct { 234 X int32 235 Y bool 236 }{ 237 42, 238 true, 239 }) 240 241 // extra fields 242 type T3 struct { 243 B string 244 } 245 var t3 T3 246 t(mustValue(types.NewStruct(types.Format_7_18, "T3", types.StructData{ 247 "b": types.String("abc"), 248 "a": types.Float(42), 249 })), &t3, T3{"abc"}) 250 251 // Case of struct name is not relevant when unmarshalling. 252 type aBc struct { 253 E bool 254 } 255 var t4 aBc 256 t(mustValue(types.NewStruct(types.Format_7_18, "abc", types.StructData{ 257 "e": types.Bool(true), 258 })), &t4, aBc{true}) 259 t(mustValue(types.NewStruct(types.Format_7_18, "Abc", types.StructData{ 260 "e": types.Bool(false), 261 })), &t4, aBc{false}) 262 263 // Name of struct is irrelevant to unmarshalling structs. 264 type SomeOtherName struct { 265 A int 266 } 267 var t5 SomeOtherName 268 t(mustValue(types.NewStruct(types.Format_7_18, "aeiou", types.StructData{ 269 "a": types.Float(42), 270 })), &t5, SomeOtherName{42}) 271 272 var t6 SomeOtherName 273 t(mustValue(types.NewStruct(types.Format_7_18, "SomeOtherName", types.StructData{ 274 "a": types.Float(42), 275 })), &t6, SomeOtherName{42}) 276 277 var t7 struct { 278 A int 279 } 280 t(mustValue(types.NewStruct(types.Format_7_18, "SomeOtherName", types.StructData{ 281 "a": types.Float(42), 282 })), &t7, struct{ A int }{42}) 283 } 284 285 func TestDecodeStructWithNomsValue(t *testing.T) { 286 // This is split out of TestDecode because we cannot use testify Equal 287 // on a go struct with a field that is a Noms value. 288 vs := newTestValueStore() 289 defer vs.Close() 290 291 type TestStruct struct { 292 B bool 293 A float64 294 C string 295 } 296 type T2 struct { 297 Abc TestStruct 298 Def types.List 299 } 300 301 v := mustValue(types.NewStruct(types.Format_7_18, "T2", types.StructData{ 302 "abc": mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{ 303 "a": types.Float(1), 304 "b": types.Bool(false), 305 "c": types.String("bye"), 306 })), 307 "def": mustValue(types.NewList(context.Background(), vs, types.Float(42))), 308 })) 309 var t2 T2 310 err := Unmarshal(context.Background(), types.Format_7_18, v, &t2) 311 assert.NoError(t, err) 312 assert.IsType(t, T2{}, t2) 313 assert.Equal(t, TestStruct{false, 1, "bye"}, t2.Abc) 314 assert.True(t, t2.Def.Equals(mustValue(types.NewList(context.Background(), vs, types.Float(42))))) 315 } 316 317 func TestDecodeNilPointer(t *testing.T) { 318 var x *bool 319 assertDecodeErrorMessage(t, types.Bool(true), x, "Cannot unmarshal into Go nil pointer of type *bool") 320 } 321 322 func TestDecodeNonPointer(t *testing.T) { 323 b := true 324 assertDecodeErrorMessage(t, types.Bool(true), b, "Cannot unmarshal into Go non pointer of type bool") 325 } 326 327 func TestDecodeNil(t *testing.T) { 328 err := Unmarshal(context.Background(), types.Format_7_18, types.Bool(true), nil) 329 assert.Error(t, err) 330 assert.Equal(t, "Cannot unmarshal into Go nil value", err.Error()) 331 } 332 333 func newTestValueStore() *types.ValueStore { 334 st := &chunks.TestStorage{} 335 return types.NewValueStore(st.NewView()) 336 } 337 338 func TestDecodeTypeMismatch(t *testing.T) { 339 vs := newTestValueStore() 340 defer vs.Close() 341 342 var b bool 343 assertDecodeErrorMessage(t, types.Float(42), &b, "Cannot unmarshal from: Float to: bool details: ") 344 345 var blob types.Blob 346 assertDecodeErrorMessage(t, mustValue(types.NewList(context.Background(), vs)), &blob, "Cannot unmarshal from: List<> to: types.Blob details: ") 347 348 type S struct { 349 X int 350 } 351 var s S 352 assertDecodeErrorMessage(t, types.String("hi!"), &s, "Cannot unmarshal from: String to: marshal.S details: expected struct") 353 assertDecodeErrorMessage(t, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 354 "x": types.String("hi"), 355 })), &s, "Cannot unmarshal from: String to: int details: ") 356 } 357 358 func assertDecodeErrorMessage(t *testing.T, v types.Value, ptr interface{}, msg string) { 359 p := reflect.ValueOf(ptr) 360 err := Unmarshal(context.Background(), types.Format_7_18, v, p.Interface()) 361 assert.Error(t, err) 362 assert.Equal(t, msg, err.Error()) 363 } 364 365 func TestDecodeInvalidTypes(tt *testing.T) { 366 t := func(p interface{}, ts string) { 367 assertDecodeErrorMessage(tt, types.Float(42), p, "Type is not supported, type: "+ts) 368 } 369 370 var ptr *bool 371 t(&ptr, "*bool") 372 373 var c chan bool 374 t(&c, "chan bool") 375 376 type Nested struct { 377 X *bool 378 } 379 var n Nested 380 t(&n, "*bool") 381 } 382 383 func TestDecodeOverflows(tt *testing.T) { 384 t := func(p interface{}, n float64, ts string) { 385 assertDecodeErrorMessage(tt, types.Float(n), p, fmt.Sprintf("Cannot unmarshal from: Float to: %s details: (%g does not fit in %s)", ts, n, ts)) 386 } 387 388 var ui8 uint8 389 t(&ui8, 256, "uint8") 390 t(&ui8, -1, "uint8") 391 392 var ui16 uint16 393 t(&ui16, math.Pow(2, 16), "uint16") 394 t(&ui16, -1, "uint16") 395 396 var ui32 uint32 397 t(&ui32, math.Pow(2, 32), "uint32") 398 t(&ui32, -1, "uint32") 399 400 var i8 int8 401 t(&i8, 128, "int8") 402 t(&i8, -128-1, "int8") 403 404 var i16 int16 405 t(&i16, math.Pow(2, 15), "int16") 406 t(&i16, -math.Pow(2, 15)-1, "int16") 407 408 var i32 int32 409 t(&i32, math.Pow(2, 31), "int32") 410 t(&i32, -math.Pow(2, 31)-1, "int32") 411 } 412 413 func TestDecodeMissingField(t *testing.T) { 414 type S struct { 415 A int32 416 B bool 417 } 418 var s S 419 assertDecodeErrorMessage(t, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 420 "a": types.Float(42), 421 })), &s, "Cannot unmarshal from: Struct S {\n a: Float,\n} to: marshal.S details: missing field \"b\"") 422 } 423 424 func TestDecodeEmbeddedStruct(tt *testing.T) { 425 assert := assert.New(tt) 426 427 type EmbeddedStruct struct { 428 X int 429 } 430 type TestStruct struct { 431 EmbeddedStruct 432 } 433 var ts TestStruct 434 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 435 "x": types.Float(1), 436 })), &ts) 437 require.NoError(tt, err) 438 assert.Equal(TestStruct{EmbeddedStruct{1}}, ts) 439 440 type OuterTest struct { 441 Y bool 442 TestStruct 443 } 444 var ts2 OuterTest 445 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 446 "x": types.Float(2), 447 "y": types.Bool(true), 448 })), &ts2) 449 require.NoError(tt, err) 450 assert.Equal(OuterTest{true, TestStruct{EmbeddedStruct{2}}}, ts2) 451 } 452 453 func TestDecodeEmbeddedStructSkip(tt *testing.T) { 454 assert := assert.New(tt) 455 456 type EmbeddedStruct struct { 457 X int 458 } 459 type TestStruct struct { 460 EmbeddedStruct `noms:"-"` 461 Y int 462 } 463 ts := TestStruct{EmbeddedStruct: EmbeddedStruct{42}} 464 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 465 "y": types.Float(2), 466 })), &ts) 467 require.NoError(tt, err) 468 assert.Equal(TestStruct{EmbeddedStruct{42}, 2}, ts) 469 } 470 471 func TestDecodeEmbeddedStructNamed(tt *testing.T) { 472 assert := assert.New(tt) 473 474 type EmbeddedStruct struct { 475 X int 476 } 477 type TestStruct struct { 478 EmbeddedStruct `noms:"em"` 479 Y int 480 } 481 ts := TestStruct{EmbeddedStruct: EmbeddedStruct{42}} 482 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 483 "em": mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 484 "x": types.Float(1), 485 })), 486 "y": types.Float(2), 487 })), &ts) 488 require.NoError(tt, err) 489 assert.Equal(TestStruct{EmbeddedStruct{1}, 2}, ts) 490 } 491 492 func TestDecodeEmbeddedStructOriginal(tt *testing.T) { 493 assert := assert.New(tt) 494 495 type EmbeddedStruct struct { 496 X int 497 O types.Struct `noms:",original"` 498 } 499 type TestStruct struct { 500 EmbeddedStruct 501 } 502 var ts TestStruct 503 nomsStruct := mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 504 "x": types.Float(1), 505 })) 506 err := Unmarshal(context.Background(), types.Format_7_18, nomsStruct, &ts) 507 require.NoError(tt, err) 508 expected := TestStruct{ 509 EmbeddedStruct: EmbeddedStruct{ 510 X: 1, 511 O: nomsStruct, 512 }, 513 } 514 assert.Equal(expected, ts) 515 } 516 517 func TestDecodeNonExportedField(tt *testing.T) { 518 type TestStruct struct { 519 x int 520 } 521 var ts TestStruct 522 assert.Zero(tt, ts.x) // here to remove compiler warning about x not being used. 523 assertDecodeErrorMessage(tt, types.String("hi"), &ts, "Non exported fields are not supported, type: marshal.TestStruct") 524 } 525 526 func TestDecodeTaggingSkip(t *testing.T) { 527 assert := assert.New(t) 528 529 type S struct { 530 A int32 `noms:"-"` 531 B bool 532 } 533 var s S 534 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 535 "b": types.Bool(true), 536 })), &s) 537 require.NoError(t, err) 538 assert.Equal(S{0, true}, s) 539 540 var s2 S 541 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 542 "a": types.Float(42), 543 "b": types.Bool(true), 544 })), &s2) 545 require.NoError(t, err) 546 assert.Equal(S{0, true}, s2) 547 548 s3 := S{555, true} 549 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 550 "a": types.Float(42), 551 "b": types.Bool(false), 552 })), &s3) 553 require.NoError(t, err) 554 assert.Equal(S{555, false}, s3) 555 } 556 557 func TestDecodeNamedFields(t *testing.T) { 558 assert := assert.New(t) 559 560 type S struct { 561 Aaa int `noms:"a"` 562 Bbb bool `noms:"B"` 563 Ccc string 564 } 565 var s S 566 err := Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 567 "a": types.Float(42), 568 "B": types.Bool(true), 569 "ccc": types.String("Hi"), 570 })), &s) 571 require.NoError(t, err) 572 assert.Equal(S{42, true, "Hi"}, s) 573 } 574 575 func TestDecodeInvalidNamedFields(t *testing.T) { 576 type S struct { 577 A int `noms:"1a"` 578 } 579 var s S 580 assertDecodeErrorMessage(t, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 581 "a": types.Float(42), 582 })), &s, "Invalid struct field name: 1a") 583 } 584 585 func TestDecodeInvalidNomsType(t *testing.T) { 586 vs := newTestValueStore() 587 defer vs.Close() 588 589 type S struct { 590 A types.List 591 } 592 var s S 593 assertDecodeErrorMessage(t, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 594 "a": mustValue(types.NewMap(context.Background(), vs, types.String("A"), types.Float(1))), 595 })), &s, "Cannot unmarshal from: Map<String, Float> to: types.List details: ") 596 } 597 598 func TestDecodeNomsTypePtr(t *testing.T) { 599 assert := assert.New(t) 600 601 testUnmarshal := func(v types.Value, dest interface{}, expected interface{}) { 602 err := Unmarshal(context.Background(), types.Format_7_18, v, dest) 603 require.NoError(t, err) 604 assert.Equal(expected, dest) 605 } 606 607 type S struct{ Type *types.Type } 608 var s S 609 610 primitive := types.PrimitiveTypeMap[types.StringKind] 611 testUnmarshal(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"type": primitive})), &s, &S{primitive}) 612 613 complex := mustType(types.MakeStructType("Complex", 614 types.StructField{ 615 Name: "stuff", 616 Type: types.PrimitiveTypeMap[types.StringKind], 617 }, 618 )) 619 testUnmarshal(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"type": complex})), &s, &S{complex}) 620 } 621 622 func ExampleUnmarshal() { 623 type Person struct { 624 Given string 625 Male bool 626 } 627 var rickon Person 628 err := Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "Person", types.StructData{ 629 "given": types.String("Rickon"), 630 "male": types.Bool(true), 631 })), &rickon) 632 if err != nil { 633 fmt.Println(err) 634 return 635 } 636 637 fmt.Printf("Given: %s, Male: %t\n", rickon.Given, rickon.Male) 638 // Output: Given: Rickon, Male: true 639 } 640 641 func TestDecodeSlice(t *testing.T) { 642 assert := assert.New(t) 643 644 vs := newTestValueStore() 645 defer vs.Close() 646 647 var s []string 648 649 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs, types.String("a"), types.String("b"), types.String("c"))), &s) 650 require.NoError(t, err) 651 assert.Equal([]string{"a", "b", "c"}, s) 652 653 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"), types.String("c"))), &s) 654 require.NoError(t, err) 655 assert.Equal([]string{"a", "b", "c"}, s) 656 } 657 658 func TestDecodeSliceEmpty(t *testing.T) { 659 assert := assert.New(t) 660 661 vs := newTestValueStore() 662 defer vs.Close() 663 664 var s []string 665 666 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs)), &s) 667 require.NoError(t, err) 668 assert.Equal([]string(nil), s) 669 670 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs)), &s) 671 require.NoError(t, err) 672 assert.Equal([]string(nil), s) 673 674 s2 := []string{} 675 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs)), &s2) 676 require.NoError(t, err) 677 assert.Equal([]string{}, s2) 678 679 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs)), &s2) 680 require.NoError(t, err) 681 assert.Equal([]string{}, s2) 682 } 683 684 func TestDecodeSliceReuse(t *testing.T) { 685 assert := assert.New(t) 686 687 vs := newTestValueStore() 688 defer vs.Close() 689 690 s := []string{"A", "B", "C", "D"} 691 s2 := s[1:3] 692 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs, types.String("a"), types.String("b"))), &s) 693 require.NoError(t, err) 694 assert.Equal([]string{"a", "b"}, s) 695 assert.Equal([]string{"b", "C"}, s2) 696 697 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))), &s) 698 require.NoError(t, err) 699 assert.Equal([]string{"a", "b"}, s) 700 assert.Equal([]string{"b", "C"}, s2) 701 } 702 703 func TestDecodeArray(t *testing.T) { 704 assert := assert.New(t) 705 706 vs := newTestValueStore() 707 defer vs.Close() 708 709 s := [3]string{"", "", ""} 710 711 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs, types.String("a"), types.String("b"), types.String("c"))), &s) 712 require.NoError(t, err) 713 assert.Equal([3]string{"a", "b", "c"}, s) 714 715 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"), types.String("c"))), &s) 716 require.NoError(t, err) 717 assert.Equal([3]string{"a", "b", "c"}, s) 718 } 719 720 func TestDecodeArrayEmpty(t *testing.T) { 721 assert := assert.New(t) 722 723 vs := newTestValueStore() 724 defer vs.Close() 725 726 var s [0]string 727 728 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs)), &s) 729 require.NoError(t, err) 730 assert.Equal([0]string{}, s) 731 732 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewSet(context.Background(), vs)), &s) 733 require.NoError(t, err) 734 assert.Equal([0]string{}, s) 735 } 736 737 func TestDecodeStructWithSlice(t *testing.T) { 738 assert := assert.New(t) 739 740 vs := newTestValueStore() 741 defer vs.Close() 742 743 type S struct { 744 List []int 745 } 746 var s S 747 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 748 "list": mustValue(types.NewList(context.Background(), vs, types.Float(1), types.Float(2), types.Float(3))), 749 })), &s) 750 require.NoError(t, err) 751 assert.Equal(S{[]int{1, 2, 3}}, s) 752 753 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 754 "list": mustValue(types.NewSet(context.Background(), vs, types.Float(1), types.Float(2), types.Float(3))), 755 })), &s) 756 require.NoError(t, err) 757 assert.Equal(S{[]int{1, 2, 3}}, s) 758 } 759 760 func TestDecodeStructWithArrayOfNomsValue(t *testing.T) { 761 assert := assert.New(t) 762 763 vs := newTestValueStore() 764 defer vs.Close() 765 766 type S struct { 767 List [1]types.Set 768 } 769 var s S 770 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewStruct(types.Format_7_18, "S", types.StructData{ 771 "list": mustValue(types.NewList(context.Background(), vs, mustValue(types.NewSet(context.Background(), vs, types.Bool(true))))), 772 })), &s) 773 require.NoError(t, err) 774 assert.Equal(S{[1]types.Set{mustSet(types.NewSet(context.Background(), vs, types.Bool(true)))}}, s) 775 } 776 777 func TestDecodeWrongArrayLength(t *testing.T) { 778 vs := newTestValueStore() 779 defer vs.Close() 780 781 var l [2]string 782 assertDecodeErrorMessage(t, mustValue(types.NewList(context.Background(), vs, types.String("hi"))), &l, "Cannot unmarshal from: List<String> to: [2]string details: length does not match") 783 } 784 785 func TestDecodeWrongArrayType(t *testing.T) { 786 vs := newTestValueStore() 787 defer vs.Close() 788 789 var l [1]string 790 assertDecodeErrorMessage(t, mustValue(types.NewList(context.Background(), vs, types.Float(1))), &l, "Cannot unmarshal from: Float to: string details: ") 791 } 792 793 func TestDecodeWrongSliceType(t *testing.T) { 794 vs := newTestValueStore() 795 defer vs.Close() 796 797 var l []string 798 assertDecodeErrorMessage(t, mustValue(types.NewList(context.Background(), vs, types.Float(1))), &l, "Cannot unmarshal from: Float to: string details: ") 799 } 800 801 func TestDecodeSliceWrongNomsType(t *testing.T) { 802 vs := newTestValueStore() 803 defer vs.Close() 804 805 var l []string 806 assertDecodeErrorMessage(t, mustValue(types.NewMap(context.Background(), vs, types.String("a"), types.Float(1))), &l, "Cannot unmarshal from: Map<String, Float> to: []string details: ") 807 } 808 809 func TestDecodeArrayWrongNomsType(t *testing.T) { 810 vs := newTestValueStore() 811 defer vs.Close() 812 813 var l [1]string 814 assertDecodeErrorMessage(t, mustValue(types.NewMap(context.Background(), vs, types.String("a"), types.Float(1))), &l, "Cannot unmarshal from: Map<String, Float> to: [1]string details: ") 815 } 816 817 func TestDecodeRecursive(t *testing.T) { 818 assert := assert.New(t) 819 820 vs := newTestValueStore() 821 defer vs.Close() 822 823 type Node struct { 824 Value int 825 Children []Node 826 } 827 828 v := mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{ 829 "children": mustValue(types.NewList(context.Background(), 830 vs, 831 mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{ 832 "children": mustValue(types.NewList(context.Background(), vs)), 833 "value": types.Float(2), 834 })), 835 mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{ 836 "children": mustValue(types.NewList(context.Background(), vs)), 837 "value": types.Float(3), 838 })), 839 )), 840 "value": types.Float(1), 841 })) 842 843 var n Node 844 err := Unmarshal(context.Background(), types.Format_7_18, v, &n) 845 require.NoError(t, err) 846 847 assert.Equal(Node{ 848 1, []Node{ 849 {2, nil}, 850 {3, nil}, 851 }, 852 }, n) 853 } 854 855 func TestDecodeMap(t *testing.T) { 856 assert := assert.New(t) 857 858 vs := newTestValueStore() 859 defer vs.Close() 860 861 var m map[string]int 862 863 testMap, err := types.NewMap(context.Background(), 864 vs, 865 types.String("a"), types.Float(1), 866 types.String("b"), types.Float(2), 867 types.String("c"), types.Float(3)) 868 require.NoError(t, err) 869 expectedMap := map[string]int{"a": 1, "b": 2, "c": 3} 870 err = Unmarshal(context.Background(), types.Format_7_18, testMap, &m) 871 require.NoError(t, err) 872 assert.Equal(expectedMap, m) 873 874 m = map[string]int{"b": 2, "c": 333} 875 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), 876 vs, 877 types.String("a"), types.Float(1), 878 types.String("c"), types.Float(3))), &m) 879 require.NoError(t, err) 880 assert.Equal(expectedMap, m) 881 882 type S struct { 883 N string 884 } 885 886 var m2 map[S]bool 887 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), 888 vs, 889 mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"n": types.String("Yes")})), types.Bool(true), 890 mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"n": types.String("No")})), types.Bool(false))), &m2) 891 require.NoError(t, err) 892 assert.Equal(map[S]bool{S{"Yes"}: true, S{"No"}: false}, m2) 893 } 894 895 func TestDecodeMapEmpty(t *testing.T) { 896 assert := assert.New(t) 897 898 vs := newTestValueStore() 899 defer vs.Close() 900 901 var m map[string]int 902 err := Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), vs)), &m) 903 require.NoError(t, err) 904 assert.Equal(map[string]int(nil), m) 905 906 m2 := map[string]int{} 907 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), vs)), &m2) 908 require.NoError(t, err) 909 assert.Equal(map[string]int{}, m2) 910 } 911 912 func TestDecodeMapWrongNomsType(t *testing.T) { 913 vs := newTestValueStore() 914 defer vs.Close() 915 916 var m map[string]int 917 assertDecodeErrorMessage(t, mustValue(types.NewList(context.Background(), vs, types.String("a"), types.Float(1))), &m, "Cannot unmarshal from: List<Float | String> to: map[string]int details: ") 918 } 919 920 func TestDecodeOntoInterface(t *testing.T) { 921 assert := assert.New(t) 922 923 vs := newTestValueStore() 924 defer vs.Close() 925 926 var i interface{} 927 err := Unmarshal(context.Background(), types.Format_7_18, types.Float(1), &i) 928 require.NoError(t, err) 929 assert.Equal(float64(1), i) 930 931 err = Unmarshal(context.Background(), types.Format_7_18, types.String("abc"), &i) 932 require.NoError(t, err) 933 assert.Equal("abc", i) 934 935 err = Unmarshal(context.Background(), types.Format_7_18, types.Bool(true), &i) 936 require.NoError(t, err) 937 assert.Equal(true, i) 938 939 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs, types.String("abc"))), &i) 940 require.NoError(t, err) 941 assert.Equal([]string{"abc"}, i) 942 943 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), vs, types.String("abc"), types.Float(1))), &i) 944 require.NoError(t, err) 945 assert.Equal(map[string]float64{"abc": float64(1)}, i) 946 947 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewList(context.Background(), vs, types.String("a"), types.Bool(true), types.Float(42))), &i) 948 require.NoError(t, err) 949 assert.Equal([]interface{}{"a", true, float64(42)}, i) 950 951 err = Unmarshal(context.Background(), types.Format_7_18, mustValue(types.NewMap(context.Background(), vs, types.String("a"), types.Bool(true), types.Float(42), mustValue(types.NewList(context.Background(), vs)))), &i) 952 require.NoError(t, err) 953 assert.Equal(map[interface{}]interface{}{"a": true, float64(42): []interface{}(nil)}, i) 954 } 955 956 func TestDecodeOntoNonSupportedInterface(t *testing.T) { 957 type I interface { 958 M() int 959 } 960 var i I 961 assertDecodeErrorMessage(t, types.Float(1), &i, "Type is not supported, type: marshal.I") 962 } 963 964 func TestDecodeOntoInterfaceStruct(t *testing.T) { 965 // Not implemented because it requires Go 1.7. 966 var i interface{} 967 assertDecodeErrorMessage(t, mustStruct(types.NewStruct(types.Format_7_18, "", types.StructData{})), &i, "Cannot unmarshal from: Struct {} to: interface {} details: ") 968 } 969 970 func TestDecodeSet(t *testing.T) { 971 assert := assert.New(t) 972 973 vs := newTestValueStore() 974 defer vs.Close() 975 976 type T struct { 977 A map[int]struct{} `noms:",set"` 978 B map[int]struct{} 979 C map[string]struct{} `noms:",set"` 980 D map[string]struct{} 981 E []int 982 F []int `noms:",set"` 983 G []int 984 } 985 986 ns := mustStruct(types.NewStruct(types.Format_7_18, "T", types.StructData{ 987 "a": mustValue(types.NewSet(context.Background(), vs, types.Float(0), types.Float(1), types.Float(2))), 988 "b": mustValue(types.NewMap(context.Background(), vs, types.Float(3), types.EmptyStruct(types.Format_7_18), types.Float(4), types.EmptyStruct(types.Format_7_18), types.Float(5), types.EmptyStruct(types.Format_7_18))), 989 "c": mustValue(types.NewSet(context.Background(), vs, types.String("0"), types.String("1"), types.String("2"))), 990 "d": mustValue(types.NewMap(context.Background(), vs, types.String("3"), types.EmptyStruct(types.Format_7_18), types.String("4"), types.EmptyStruct(types.Format_7_18), types.String("5"), types.EmptyStruct(types.Format_7_18))), 991 "e": mustValue(types.NewSet(context.Background(), vs, types.Float(6), types.Float(7), types.Float(8))), 992 "f": mustValue(types.NewSet(context.Background(), vs, types.Float(9), types.Float(10), types.Float(11))), 993 "g": mustValue(types.NewList(context.Background(), vs, types.Float(12), types.Float(13), types.Float(14))), 994 })) 995 996 gs := T{} 997 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, ns, &gs)) 998 assert.Equal(T{ 999 A: map[int]struct{}{0: {}, 1: {}, 2: {}}, 1000 B: map[int]struct{}{3: {}, 4: {}, 5: {}}, 1001 C: map[string]struct{}{"0": {}, "1": {}, "2": {}}, 1002 D: map[string]struct{}{"3": {}, "4": {}, "5": {}}, 1003 E: []int{6, 7, 8}, 1004 F: []int{9, 10, 11}, 1005 G: []int{12, 13, 14}, 1006 }, gs) 1007 1008 ns2 := mustStruct(types.NewStruct(types.Format_7_18, "T", types.StructData{ 1009 "a": mustSet(types.NewSet(context.Background(), vs)), 1010 "b": mustValue(types.NewMap(context.Background(), vs)), 1011 "c": mustValue(types.NewSet(context.Background(), vs)), 1012 "d": mustValue(types.NewMap(context.Background(), vs)), 1013 "e": mustValue(types.NewSet(context.Background(), vs)), 1014 "f": mustValue(types.NewSet(context.Background(), vs)), 1015 "g": mustValue(types.NewList(context.Background(), vs)), 1016 })) 1017 1018 gs2 := T{ 1019 A: map[int]struct{}{}, 1020 } 1021 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, ns2, &gs2)) 1022 assert.Equal(T{ 1023 A: map[int]struct{}{}, 1024 }, gs2) 1025 } 1026 1027 func TestDecodeOpt(t *testing.T) { 1028 assert := assert.New(t) 1029 1030 vs := newTestValueStore() 1031 defer vs.Close() 1032 1033 tc := []struct { 1034 in types.Value 1035 opt Opt 1036 onto interface{} 1037 wantValue interface{} 1038 wantError string 1039 }{ 1040 { 1041 mustSet(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))), 1042 Opt{}, 1043 &[]string{}, 1044 &[]string{"a", "b"}, 1045 "", 1046 }, 1047 { 1048 mustSet(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))), 1049 Opt{Set: true}, 1050 &[]string{}, 1051 &[]string{"a", "b"}, 1052 "", 1053 }, 1054 { 1055 mustSet(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))), 1056 Opt{Set: true}, 1057 &map[string]struct{}{}, 1058 &map[string]struct{}{"a": struct{}{}, "b": struct{}{}}, 1059 "", 1060 }, 1061 { 1062 mustSet(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))), 1063 Opt{}, 1064 &map[string]struct{}{}, 1065 &map[string]struct{}{}, 1066 "Cannot unmarshal from: Set<String> to: map[string]struct {} details: field missing \"set\" tag", 1067 }, 1068 } 1069 1070 for _, t := range tc { 1071 err := UnmarshalOpt(context.Background(), types.Format_7_18, t.in, t.opt, t.onto) 1072 assert.Equal(t.wantValue, t.onto) 1073 if t.wantError == "" { 1074 assert.Nil(err) 1075 } else { 1076 assert.Equal(t.wantError, err.Error()) 1077 } 1078 } 1079 } 1080 1081 func TestDecodeNamedSet(t *testing.T) { 1082 assert := assert.New(t) 1083 1084 vs := newTestValueStore() 1085 defer vs.Close() 1086 1087 type T struct { 1088 A map[int]struct{} `noms:"foo,set"` 1089 } 1090 1091 ns := mustStruct(types.NewStruct(types.Format_7_18, "T", types.StructData{ 1092 "a": mustSet(types.NewSet(context.Background(), vs, types.Float(0))), 1093 "foo": mustSet(types.NewSet(context.Background(), vs, types.Float(1))), 1094 })) 1095 1096 gs := T{} 1097 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, ns, &gs)) 1098 assert.Equal(T{ 1099 map[int]struct{}{1: {}}, 1100 }, gs) 1101 } 1102 1103 func TestDecodeSetWrongMapType(t *testing.T) { 1104 assert := assert.New(t) 1105 1106 vs := newTestValueStore() 1107 defer vs.Close() 1108 1109 type T1 struct { 1110 A map[int]int `noms:",set"` 1111 } 1112 1113 err := Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "T1", types.StructData{ 1114 "a": mustSet(types.NewSet(context.Background(), vs, types.Float(0))), 1115 })), &T1{}) 1116 assert.Error(err) 1117 assert.Equal("Cannot unmarshal from: Set<Float> to: map[int]int details: ", err.Error()) 1118 1119 type T2 struct { 1120 A map[int]struct{} 1121 } 1122 1123 err = Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "T2", types.StructData{ 1124 "a": mustSet(types.NewSet(context.Background(), vs, types.Float(0))), 1125 })), &T2{}) 1126 assert.Error(err) 1127 assert.Equal(`Cannot unmarshal from: Set<Float> to: map[int]struct {} details: field missing "set" tag`, err.Error()) 1128 1129 type T3 struct { 1130 A map[int]struct{} `noms:",set"` 1131 } 1132 1133 err = Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "T3", types.StructData{ 1134 "a": mustValue(types.NewMap(context.Background(), vs, types.Float(0), types.EmptyStruct(types.Format_7_18))), 1135 })), &T3{}) 1136 assert.Error(err) 1137 assert.Equal(`Cannot unmarshal from: Map<Float, Struct {}> to: map[int]struct {} details: field has "set" tag`, err.Error()) 1138 } 1139 1140 func TestDecodeOmitEmpty(t *testing.T) { 1141 assert := assert.New(t) 1142 1143 type S struct { 1144 Foo int `noms:",omitempty"` 1145 Bar struct { 1146 Baz int 1147 Hotdog int `noms:",omitempty"` 1148 } 1149 } 1150 expected := S{ 1151 Bar: struct { 1152 Baz int 1153 Hotdog int `noms:",omitempty"` 1154 }{ 1155 Baz: 42, 1156 }, 1157 } 1158 var actual S 1159 err := Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 1160 "bar": mustStruct(types.NewStruct(types.Format_7_18, "", types.StructData{ 1161 "baz": types.Float(42), 1162 })), 1163 })), &actual) 1164 require.NoError(t, err) 1165 assert.Equal(expected, actual) 1166 } 1167 1168 func TestDecodeOriginal(t *testing.T) { 1169 assert := assert.New(t) 1170 1171 type S struct { 1172 Foo int `noms:",omitempty"` 1173 Bar types.Struct `noms:",original"` 1174 Baz types.Struct `noms:",original"` 1175 } 1176 input := mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 1177 "foo": types.Float(42), 1178 })) 1179 expected := S{ 1180 Foo: 42, 1181 Bar: input, 1182 Baz: input, 1183 } 1184 var actual S 1185 err := Unmarshal(context.Background(), types.Format_7_18, input, &actual) 1186 require.NoError(t, err) 1187 assert.True(expected.Bar.Equals(actual.Bar)) 1188 } 1189 1190 func TestDecodeOriginalReceiveTypeError(t *testing.T) { 1191 assert := assert.New(t) 1192 1193 type S struct { 1194 Foo types.Value `noms:",original"` 1195 } 1196 input := mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{})) 1197 var actual S 1198 err := Unmarshal(context.Background(), types.Format_7_18, input, &actual) 1199 assert.Error(err) 1200 assert.Equal(`Cannot unmarshal from: Struct S {} to: marshal.S details: field with tag "original" must have type Struct`, err.Error()) 1201 } 1202 1203 func TestDecodeCanSkipUnexportedField(t *testing.T) { 1204 assert := assert.New(t) 1205 1206 type S struct { 1207 Abc int 1208 notExported bool `noms:"-"` 1209 } 1210 var s S 1211 err := Unmarshal(context.Background(), types.Format_7_18, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{ 1212 "abc": types.Float(42), 1213 })), &s) 1214 require.NoError(t, err) 1215 assert.Equal(S{42, false}, s) 1216 } 1217 1218 func (u *primitiveType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1219 *u = primitiveType(v.(types.Float) - 1) 1220 return nil 1221 } 1222 1223 func TestUnmarshalerPrimitiveType(t *testing.T) { 1224 assert := assert.New(t) 1225 1226 v := types.Float(43) 1227 u := primitiveType(0) 1228 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1229 assert.Equal(primitiveType(42), u) 1230 } 1231 1232 func (u *primitiveSliceType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1233 sv := string(v.(types.String)) 1234 spl := strings.Split(sv, ",") 1235 *u = make(primitiveSliceType, len(spl)) 1236 for i, s := range spl { 1237 (*u)[i] = s 1238 } 1239 return nil 1240 } 1241 1242 func TestUnmarshalerPrimitiveSliceType(t *testing.T) { 1243 assert := assert.New(t) 1244 1245 v := types.String("a,b,c") 1246 u := primitiveSliceType{} 1247 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1248 assert.Equal(primitiveSliceType{"a", "b", "c"}, u) 1249 } 1250 1251 func (u *primitiveMapType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1252 *u = primitiveMapType{} 1253 err := v.(types.Set).IterAll(context.Background(), func(v types.Value) error { 1254 sv := v.(types.String) 1255 spl := strings.Split(string(sv), ",") 1256 d.PanicIfFalse(len(spl) == 2) 1257 (*u)[spl[0]] = spl[1] 1258 return nil 1259 }) 1260 return err 1261 } 1262 1263 func TestUnmarshalerPrimitiveMapType(t *testing.T) { 1264 assert := assert.New(t) 1265 1266 vs := newTestValueStore() 1267 defer vs.Close() 1268 1269 v, err := types.NewSet(context.Background(), vs, types.String("a,foo"), types.String("b,bar")) 1270 require.NoError(t, err) 1271 u := primitiveMapType{} 1272 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1273 assert.Equal(primitiveMapType(map[string]string{ 1274 "a": "foo", 1275 "b": "bar", 1276 }), u) 1277 } 1278 1279 func (u *primitiveStructType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1280 n := int(v.(types.Float)) 1281 u.x = n / 3 1282 u.y = n % 3 1283 return nil 1284 } 1285 1286 func TestUnmarshalerPrimitiveStructType(t *testing.T) { 1287 assert := assert.New(t) 1288 1289 v := types.Float(10) 1290 u := primitiveStructType{} 1291 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1292 assert.Equal(primitiveStructType{3, 1}, u) 1293 } 1294 1295 func (u *builtinType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1296 sv := v.(types.String) 1297 *u = builtinType(*regexp.MustCompile(string(sv))) 1298 return nil 1299 } 1300 1301 func TestUnmarshalerBuiltinType(t *testing.T) { 1302 assert := assert.New(t) 1303 1304 s := "[a-z]+$" 1305 v := types.String(s) 1306 u := builtinType{} 1307 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1308 r := regexp.Regexp(u) 1309 assert.Equal(s, r.String()) 1310 } 1311 1312 func (u *wrappedMarshalerType) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1313 n := v.(types.Float) 1314 *u = wrappedMarshalerType(int(n) - 2) 1315 return nil 1316 } 1317 1318 func TestUnmarshalerWrappedMarshalerType(t *testing.T) { 1319 assert := assert.New(t) 1320 1321 v := types.Float(44) 1322 u := wrappedMarshalerType(0) 1323 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1324 assert.Equal(wrappedMarshalerType(42), u) 1325 } 1326 1327 func TestUnmarshalerComplexStructType(t *testing.T) { 1328 assert := assert.New(t) 1329 1330 vs := newTestValueStore() 1331 defer vs.Close() 1332 1333 s := "foo|bar" 1334 r := regexp.MustCompile(s) 1335 v := mustStruct(types.NewStruct(types.Format_7_18, "TestComplexStructType", types.StructData{ 1336 "p": types.Float(43), 1337 "ps": mustValue(types.NewList(context.Background(), vs, types.Float(2), types.Float(3))), 1338 "pm": mustValue(types.NewMap(context.Background(), vs, types.String("x"), types.Float(101), types.String("y"), types.Float(102))), 1339 "pslice": types.String("a,b,c"), 1340 "pmap": mustValue(types.NewSet(context.Background(), vs, types.String("c,123"), types.String("d,456"))), 1341 "pstruct": types.Float(5), 1342 "b": types.String(s), 1343 })) 1344 u := TestComplexStructType{} 1345 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, v, &u)) 1346 assert.Equal(TestComplexStructType{ 1347 P: 42, 1348 Ps: []primitiveType{1, 2}, 1349 Pm: map[string]primitiveType{ 1350 "x": 100, 1351 "y": 101, 1352 }, 1353 Pslice: primitiveSliceType{"a", "b", "c"}, 1354 Pmap: primitiveMapType{ 1355 "c": "123", 1356 "d": "456", 1357 }, 1358 Pstruct: primitiveStructType{1, 2}, 1359 B: builtinType(*r), 1360 }, u) 1361 } 1362 1363 func (u *returnsMarshalerError) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1364 // Can't use u.err because an empty returnsMarshalerError is created for each 1365 // call to UnmarshalNoms. 1366 return errors.New("foo bar baz") 1367 } 1368 1369 func TestUnmarshalerError(t *testing.T) { 1370 assert := assert.New(t) 1371 1372 m1 := returnsMarshalerError{} 1373 err := Unmarshal(context.Background(), types.Format_7_18, types.EmptyStruct(types.Format_7_18), &m1) 1374 assert.Equal(errors.New("foo bar baz"), err) 1375 } 1376 1377 type notPointer struct { 1378 x int 1379 } 1380 1381 func (u notPointer) UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error { 1382 u.x++ 1383 return nil 1384 } 1385 1386 func TestUnmarshalNomsNotPointerDoesNotShareState(t *testing.T) { 1387 assert := assert.New(t) 1388 1389 u := notPointer{0} 1390 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, types.EmptyStruct(types.Format_7_18), &u)) 1391 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, types.EmptyStruct(types.Format_7_18), &u)) 1392 assert.NoError(Unmarshal(context.Background(), types.Format_7_18, types.EmptyStruct(types.Format_7_18), &u)) 1393 assert.Equal(notPointer{0}, u) 1394 } 1395 1396 func TestUnmarshalMustUnmarshal(t *testing.T) { 1397 a := assert.New(t) 1398 1399 vs := newTestValueStore() 1400 defer vs.Close() 1401 1402 type TestStruct struct{ F1 int } 1403 1404 v, err := Marshal(context.Background(), vs, types.Float(1)) 1405 a.NoError(err) 1406 1407 var out TestStruct 1408 err = Unmarshal(context.Background(), types.Format_7_18, v, &out) 1409 a.Error(err) 1410 1411 v, err = Marshal(context.Background(), vs, TestStruct{2}) 1412 a.NoError(err) 1413 err = Unmarshal(context.Background(), types.Format_7_18, v, &out) 1414 a.NoError(err) 1415 }