1package toml 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "reflect" 9 "strings" 10 "testing" 11 "time" 12) 13 14type basicMarshalTestStruct struct { 15 String string `toml:"Zstring"` 16 StringList []string `toml:"Ystrlist"` 17 Sub basicMarshalTestSubStruct `toml:"Xsubdoc"` 18 SubList []basicMarshalTestSubStruct `toml:"Wsublist"` 19} 20 21type basicMarshalTestSubStruct struct { 22 String2 string 23} 24 25var basicTestData = basicMarshalTestStruct{ 26 String: "Hello", 27 StringList: []string{"Howdy", "Hey There"}, 28 Sub: basicMarshalTestSubStruct{"One"}, 29 SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}}, 30} 31 32var basicTestToml = []byte(`Ystrlist = ["Howdy","Hey There"] 33Zstring = "Hello" 34 35[[Wsublist]] 36 String2 = "Two" 37 38[[Wsublist]] 39 String2 = "Three" 40 41[Xsubdoc] 42 String2 = "One" 43`) 44 45var basicTestTomlOrdered = []byte(`Zstring = "Hello" 46Ystrlist = ["Howdy","Hey There"] 47 48[Xsubdoc] 49 String2 = "One" 50 51[[Wsublist]] 52 String2 = "Two" 53 54[[Wsublist]] 55 String2 = "Three" 56`) 57 58func TestBasicMarshal(t *testing.T) { 59 result, err := Marshal(basicTestData) 60 if err != nil { 61 t.Fatal(err) 62 } 63 expected := basicTestToml 64 if !bytes.Equal(result, expected) { 65 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 66 } 67} 68 69func TestBasicMarshalOrdered(t *testing.T) { 70 var result bytes.Buffer 71 err := NewEncoder(&result).Order(OrderPreserve).Encode(basicTestData) 72 if err != nil { 73 t.Fatal(err) 74 } 75 expected := basicTestTomlOrdered 76 if !bytes.Equal(result.Bytes(), expected) { 77 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes()) 78 } 79} 80 81func TestBasicMarshalWithPointer(t *testing.T) { 82 result, err := Marshal(&basicTestData) 83 if err != nil { 84 t.Fatal(err) 85 } 86 expected := basicTestToml 87 if !bytes.Equal(result, expected) { 88 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 89 } 90} 91 92func TestBasicMarshalOrderedWithPointer(t *testing.T) { 93 var result bytes.Buffer 94 err := NewEncoder(&result).Order(OrderPreserve).Encode(&basicTestData) 95 if err != nil { 96 t.Fatal(err) 97 } 98 expected := basicTestTomlOrdered 99 if !bytes.Equal(result.Bytes(), expected) { 100 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes()) 101 } 102} 103 104func TestBasicUnmarshal(t *testing.T) { 105 result := basicMarshalTestStruct{} 106 err := Unmarshal(basicTestToml, &result) 107 expected := basicTestData 108 if err != nil { 109 t.Fatal(err) 110 } 111 if !reflect.DeepEqual(result, expected) { 112 t.Errorf("Bad unmarshal: expected %v, got %v", expected, result) 113 } 114} 115 116type testDoc struct { 117 Title string `toml:"title"` 118 BasicLists testDocBasicLists `toml:"basic_lists"` 119 SubDocPtrs []*testSubDoc `toml:"subdocptrs"` 120 BasicMap map[string]string `toml:"basic_map"` 121 Subdocs testDocSubs `toml:"subdoc"` 122 Basics testDocBasics `toml:"basic"` 123 SubDocList []testSubDoc `toml:"subdoclist"` 124 err int `toml:"shouldntBeHere"` 125 unexported int `toml:"shouldntBeHere"` 126 Unexported2 int `toml:"-"` 127} 128 129type testMapDoc struct { 130 Title string `toml:"title"` 131 BasicMap map[string]string `toml:"basic_map"` 132 LongMap map[string]string `toml:"long_map"` 133} 134 135type testDocBasics struct { 136 Uint uint `toml:"uint"` 137 Bool bool `toml:"bool"` 138 Float float32 `toml:"float"` 139 Int int `toml:"int"` 140 String *string `toml:"string"` 141 Date time.Time `toml:"date"` 142 unexported int `toml:"shouldntBeHere"` 143} 144 145type testDocBasicLists struct { 146 Floats []*float32 `toml:"floats"` 147 Bools []bool `toml:"bools"` 148 Dates []time.Time `toml:"dates"` 149 Ints []int `toml:"ints"` 150 UInts []uint `toml:"uints"` 151 Strings []string `toml:"strings"` 152} 153 154type testDocSubs struct { 155 Second *testSubDoc `toml:"second"` 156 First testSubDoc `toml:"first"` 157} 158 159type testSubDoc struct { 160 Name string `toml:"name"` 161 unexported int `toml:"shouldntBeHere"` 162} 163 164var biteMe = "Bite me" 165var float1 float32 = 12.3 166var float2 float32 = 45.6 167var float3 float32 = 78.9 168var subdoc = testSubDoc{"Second", 0} 169 170var docData = testDoc{ 171 Title: "TOML Marshal Testing", 172 unexported: 0, 173 Unexported2: 0, 174 Basics: testDocBasics{ 175 Bool: true, 176 Date: time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC), 177 Float: 123.4, 178 Int: 5000, 179 Uint: 5001, 180 String: &biteMe, 181 unexported: 0, 182 }, 183 BasicLists: testDocBasicLists{ 184 Bools: []bool{true, false, true}, 185 Dates: []time.Time{ 186 time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC), 187 time.Date(1980, 5, 27, 7, 32, 0, 0, time.UTC), 188 }, 189 Floats: []*float32{&float1, &float2, &float3}, 190 Ints: []int{8001, 8001, 8002}, 191 Strings: []string{"One", "Two", "Three"}, 192 UInts: []uint{5002, 5003}, 193 }, 194 BasicMap: map[string]string{ 195 "one": "one", 196 "two": "two", 197 }, 198 Subdocs: testDocSubs{ 199 First: testSubDoc{"First", 0}, 200 Second: &subdoc, 201 }, 202 SubDocList: []testSubDoc{ 203 {"List.First", 0}, 204 {"List.Second", 0}, 205 }, 206 SubDocPtrs: []*testSubDoc{&subdoc}, 207} 208 209var mapTestDoc = testMapDoc{ 210 Title: "TOML Marshal Testing", 211 BasicMap: map[string]string{ 212 "one": "one", 213 "two": "two", 214 }, 215 LongMap: map[string]string{ 216 "h1": "8", 217 "i2": "9", 218 "b3": "2", 219 "d4": "4", 220 "f5": "6", 221 "e6": "5", 222 "a7": "1", 223 "c8": "3", 224 "j9": "10", 225 "g10": "7", 226 }, 227} 228 229func TestDocMarshal(t *testing.T) { 230 result, err := Marshal(docData) 231 if err != nil { 232 t.Fatal(err) 233 } 234 expected, _ := ioutil.ReadFile("marshal_test.toml") 235 if !bytes.Equal(result, expected) { 236 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 237 } 238} 239 240func TestDocMarshalOrdered(t *testing.T) { 241 var result bytes.Buffer 242 err := NewEncoder(&result).Order(OrderPreserve).Encode(docData) 243 if err != nil { 244 t.Fatal(err) 245 } 246 expected, _ := ioutil.ReadFile("marshal_OrderPreserve_test.toml") 247 if !bytes.Equal(result.Bytes(), expected) { 248 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes()) 249 } 250} 251 252func TestDocMarshalMaps(t *testing.T) { 253 result, err := Marshal(mapTestDoc) 254 if err != nil { 255 t.Fatal(err) 256 } 257 expected, _ := ioutil.ReadFile("marshal_OrderPreserve_Map_test.toml") 258 if !bytes.Equal(result, expected) { 259 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 260 } 261} 262 263func TestDocMarshalOrderedMaps(t *testing.T) { 264 var result bytes.Buffer 265 err := NewEncoder(&result).Order(OrderPreserve).Encode(mapTestDoc) 266 if err != nil { 267 t.Fatal(err) 268 } 269 expected, _ := ioutil.ReadFile("marshal_OrderPreserve_Map_test.toml") 270 if !bytes.Equal(result.Bytes(), expected) { 271 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes()) 272 } 273} 274 275func TestDocMarshalPointer(t *testing.T) { 276 result, err := Marshal(&docData) 277 if err != nil { 278 t.Fatal(err) 279 } 280 expected, _ := ioutil.ReadFile("marshal_test.toml") 281 if !bytes.Equal(result, expected) { 282 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 283 } 284} 285 286func TestDocUnmarshal(t *testing.T) { 287 result := testDoc{} 288 tomlData, _ := ioutil.ReadFile("marshal_test.toml") 289 err := Unmarshal(tomlData, &result) 290 expected := docData 291 if err != nil { 292 t.Fatal(err) 293 } 294 if !reflect.DeepEqual(result, expected) { 295 resStr, _ := json.MarshalIndent(result, "", " ") 296 expStr, _ := json.MarshalIndent(expected, "", " ") 297 t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) 298 } 299} 300 301func TestDocPartialUnmarshal(t *testing.T) { 302 result := testDocSubs{} 303 304 tree, _ := LoadFile("marshal_test.toml") 305 subTree := tree.Get("subdoc").(*Tree) 306 err := subTree.Unmarshal(&result) 307 expected := docData.Subdocs 308 if err != nil { 309 t.Fatal(err) 310 } 311 if !reflect.DeepEqual(result, expected) { 312 resStr, _ := json.MarshalIndent(result, "", " ") 313 expStr, _ := json.MarshalIndent(expected, "", " ") 314 t.Errorf("Bad partial unmartial: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) 315 } 316} 317 318type tomlTypeCheckTest struct { 319 name string 320 item interface{} 321 typ int //0=primitive, 1=otherslice, 2=treeslice, 3=tree 322} 323 324func TestTypeChecks(t *testing.T) { 325 tests := []tomlTypeCheckTest{ 326 {"integer", 2, 0}, 327 {"time", time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC), 0}, 328 {"stringlist", []string{"hello", "hi"}, 1}, 329 {"timelist", []time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1}, 330 {"objectlist", []tomlTypeCheckTest{}, 2}, 331 {"object", tomlTypeCheckTest{}, 3}, 332 } 333 334 for _, test := range tests { 335 expected := []bool{false, false, false, false} 336 expected[test.typ] = true 337 result := []bool{ 338 isPrimitive(reflect.TypeOf(test.item)), 339 isOtherSlice(reflect.TypeOf(test.item)), 340 isTreeSlice(reflect.TypeOf(test.item)), 341 isTree(reflect.TypeOf(test.item)), 342 } 343 if !reflect.DeepEqual(expected, result) { 344 t.Errorf("Bad type check on %q: expected %v, got %v", test.name, expected, result) 345 } 346 } 347} 348 349type unexportedMarshalTestStruct struct { 350 String string `toml:"string"` 351 StringList []string `toml:"strlist"` 352 Sub basicMarshalTestSubStruct `toml:"subdoc"` 353 SubList []basicMarshalTestSubStruct `toml:"sublist"` 354 unexported int `toml:"shouldntBeHere"` 355 Unexported2 int `toml:"-"` 356} 357 358var unexportedTestData = unexportedMarshalTestStruct{ 359 String: "Hello", 360 StringList: []string{"Howdy", "Hey There"}, 361 Sub: basicMarshalTestSubStruct{"One"}, 362 SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}}, 363 unexported: 0, 364 Unexported2: 0, 365} 366 367var unexportedTestToml = []byte(`string = "Hello" 368strlist = ["Howdy","Hey There"] 369unexported = 1 370shouldntBeHere = 2 371 372[subdoc] 373 String2 = "One" 374 375[[sublist]] 376 String2 = "Two" 377 378[[sublist]] 379 String2 = "Three" 380`) 381 382func TestUnexportedUnmarshal(t *testing.T) { 383 result := unexportedMarshalTestStruct{} 384 err := Unmarshal(unexportedTestToml, &result) 385 expected := unexportedTestData 386 if err != nil { 387 t.Fatal(err) 388 } 389 if !reflect.DeepEqual(result, expected) { 390 t.Errorf("Bad unexported unmarshal: expected %v, got %v", expected, result) 391 } 392} 393 394type errStruct struct { 395 Bool bool `toml:"bool"` 396 Date time.Time `toml:"date"` 397 Float float64 `toml:"float"` 398 Int int16 `toml:"int"` 399 String *string `toml:"string"` 400} 401 402var errTomls = []string{ 403 "bool = truly\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"", 404 "bool = true\ndate = 1979-05-27T07:3200Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"", 405 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123a4\nint = 5000\nstring = \"Bite me\"", 406 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = j000\nstring = \"Bite me\"", 407 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me", 408 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me", 409 "bool = 1\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"", 410 "bool = true\ndate = 1\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"", 411 "bool = true\ndate = 1979-05-27T07:32:00Z\n\"sorry\"\nint = 5000\nstring = \"Bite me\"", 412 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = \"sorry\"\nstring = \"Bite me\"", 413 "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = 1", 414} 415 416type mapErr struct { 417 Vals map[string]float64 418} 419 420type intErr struct { 421 Int1 int 422 Int2 int8 423 Int3 int16 424 Int4 int32 425 Int5 int64 426 UInt1 uint 427 UInt2 uint8 428 UInt3 uint16 429 UInt4 uint32 430 UInt5 uint64 431 Flt1 float32 432 Flt2 float64 433} 434 435var intErrTomls = []string{ 436 "Int1 = []\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 437 "Int1 = 1\nInt2 = []\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 438 "Int1 = 1\nInt2 = 2\nInt3 = []\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 439 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = []\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 440 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = []\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 441 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = []\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 442 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = []\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 443 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = []\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 444 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = []\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = 2.0", 445 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = []\nFlt1 = 1.0\nFlt2 = 2.0", 446 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = []\nFlt2 = 2.0", 447 "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = []", 448} 449 450func TestErrUnmarshal(t *testing.T) { 451 for ind, toml := range errTomls { 452 result := errStruct{} 453 err := Unmarshal([]byte(toml), &result) 454 if err == nil { 455 t.Errorf("Expected err from case %d\n", ind) 456 } 457 } 458 result2 := mapErr{} 459 err := Unmarshal([]byte("[Vals]\nfred=\"1.2\""), &result2) 460 if err == nil { 461 t.Errorf("Expected err from map") 462 } 463 for ind, toml := range intErrTomls { 464 result3 := intErr{} 465 err := Unmarshal([]byte(toml), &result3) 466 if err == nil { 467 t.Errorf("Expected int err from case %d\n", ind) 468 } 469 } 470} 471 472type emptyMarshalTestStruct struct { 473 Title string `toml:"title"` 474 Bool bool `toml:"bool"` 475 Int int `toml:"int"` 476 String string `toml:"string"` 477 StringList []string `toml:"stringlist"` 478 Ptr *basicMarshalTestStruct `toml:"ptr"` 479 Map map[string]string `toml:"map"` 480} 481 482var emptyTestData = emptyMarshalTestStruct{ 483 Title: "Placeholder", 484 Bool: false, 485 Int: 0, 486 String: "", 487 StringList: []string{}, 488 Ptr: nil, 489 Map: map[string]string{}, 490} 491 492var emptyTestToml = []byte(`bool = false 493int = 0 494string = "" 495stringlist = [] 496title = "Placeholder" 497 498[map] 499`) 500 501type emptyMarshalTestStruct2 struct { 502 Title string `toml:"title"` 503 Bool bool `toml:"bool,omitempty"` 504 Int int `toml:"int, omitempty"` 505 String string `toml:"string,omitempty "` 506 StringList []string `toml:"stringlist,omitempty"` 507 Ptr *basicMarshalTestStruct `toml:"ptr,omitempty"` 508 Map map[string]string `toml:"map,omitempty"` 509} 510 511var emptyTestData2 = emptyMarshalTestStruct2{ 512 Title: "Placeholder", 513 Bool: false, 514 Int: 0, 515 String: "", 516 StringList: []string{}, 517 Ptr: nil, 518 Map: map[string]string{}, 519} 520 521var emptyTestToml2 = []byte(`title = "Placeholder" 522`) 523 524func TestEmptyMarshal(t *testing.T) { 525 result, err := Marshal(emptyTestData) 526 if err != nil { 527 t.Fatal(err) 528 } 529 expected := emptyTestToml 530 if !bytes.Equal(result, expected) { 531 t.Errorf("Bad empty marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 532 } 533} 534 535func TestEmptyMarshalOmit(t *testing.T) { 536 result, err := Marshal(emptyTestData2) 537 if err != nil { 538 t.Fatal(err) 539 } 540 expected := emptyTestToml2 541 if !bytes.Equal(result, expected) { 542 t.Errorf("Bad empty omit marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 543 } 544} 545 546func TestEmptyUnmarshal(t *testing.T) { 547 result := emptyMarshalTestStruct{} 548 err := Unmarshal(emptyTestToml, &result) 549 expected := emptyTestData 550 if err != nil { 551 t.Fatal(err) 552 } 553 if !reflect.DeepEqual(result, expected) { 554 t.Errorf("Bad empty unmarshal: expected %v, got %v", expected, result) 555 } 556} 557 558func TestEmptyUnmarshalOmit(t *testing.T) { 559 result := emptyMarshalTestStruct2{} 560 err := Unmarshal(emptyTestToml, &result) 561 expected := emptyTestData2 562 if err != nil { 563 t.Fatal(err) 564 } 565 if !reflect.DeepEqual(result, expected) { 566 t.Errorf("Bad empty omit unmarshal: expected %v, got %v", expected, result) 567 } 568} 569 570type pointerMarshalTestStruct struct { 571 Str *string 572 List *[]string 573 ListPtr *[]*string 574 Map *map[string]string 575 MapPtr *map[string]*string 576 EmptyStr *string 577 EmptyList *[]string 578 EmptyMap *map[string]string 579 DblPtr *[]*[]*string 580} 581 582var pointerStr = "Hello" 583var pointerList = []string{"Hello back"} 584var pointerListPtr = []*string{&pointerStr} 585var pointerMap = map[string]string{"response": "Goodbye"} 586var pointerMapPtr = map[string]*string{"alternate": &pointerStr} 587var pointerTestData = pointerMarshalTestStruct{ 588 Str: &pointerStr, 589 List: &pointerList, 590 ListPtr: &pointerListPtr, 591 Map: &pointerMap, 592 MapPtr: &pointerMapPtr, 593 EmptyStr: nil, 594 EmptyList: nil, 595 EmptyMap: nil, 596} 597 598var pointerTestToml = []byte(`List = ["Hello back"] 599ListPtr = ["Hello"] 600Str = "Hello" 601 602[Map] 603 response = "Goodbye" 604 605[MapPtr] 606 alternate = "Hello" 607`) 608 609func TestPointerMarshal(t *testing.T) { 610 result, err := Marshal(pointerTestData) 611 if err != nil { 612 t.Fatal(err) 613 } 614 expected := pointerTestToml 615 if !bytes.Equal(result, expected) { 616 t.Errorf("Bad pointer marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 617 } 618} 619 620func TestPointerUnmarshal(t *testing.T) { 621 result := pointerMarshalTestStruct{} 622 err := Unmarshal(pointerTestToml, &result) 623 expected := pointerTestData 624 if err != nil { 625 t.Fatal(err) 626 } 627 if !reflect.DeepEqual(result, expected) { 628 t.Errorf("Bad pointer unmarshal: expected %v, got %v", expected, result) 629 } 630} 631 632func TestUnmarshalTypeMismatch(t *testing.T) { 633 result := pointerMarshalTestStruct{} 634 err := Unmarshal([]byte("List = 123"), &result) 635 if !strings.HasPrefix(err.Error(), "(1, 1): Can't convert 123(int64) to []string(slice)") { 636 t.Errorf("Type mismatch must be reported: got %v", err.Error()) 637 } 638} 639 640type nestedMarshalTestStruct struct { 641 String [][]string 642 //Struct [][]basicMarshalTestSubStruct 643 StringPtr *[]*[]*string 644 // StructPtr *[]*[]*basicMarshalTestSubStruct 645} 646 647var str1 = "Three" 648var str2 = "Four" 649var strPtr = []*string{&str1, &str2} 650var strPtr2 = []*[]*string{&strPtr} 651 652var nestedTestData = nestedMarshalTestStruct{ 653 String: [][]string{{"Five", "Six"}, {"One", "Two"}}, 654 StringPtr: &strPtr2, 655} 656 657var nestedTestToml = []byte(`String = [["Five","Six"],["One","Two"]] 658StringPtr = [["Three","Four"]] 659`) 660 661func TestNestedMarshal(t *testing.T) { 662 result, err := Marshal(nestedTestData) 663 if err != nil { 664 t.Fatal(err) 665 } 666 expected := nestedTestToml 667 if !bytes.Equal(result, expected) { 668 t.Errorf("Bad nested marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 669 } 670} 671 672func TestNestedUnmarshal(t *testing.T) { 673 result := nestedMarshalTestStruct{} 674 err := Unmarshal(nestedTestToml, &result) 675 expected := nestedTestData 676 if err != nil { 677 t.Fatal(err) 678 } 679 if !reflect.DeepEqual(result, expected) { 680 t.Errorf("Bad nested unmarshal: expected %v, got %v", expected, result) 681 } 682} 683 684type customMarshalerParent struct { 685 Self customMarshaler `toml:"me"` 686 Friends []customMarshaler `toml:"friends"` 687} 688 689type customMarshaler struct { 690 FirsName string 691 LastName string 692} 693 694func (c customMarshaler) MarshalTOML() ([]byte, error) { 695 fullName := fmt.Sprintf("%s %s", c.FirsName, c.LastName) 696 return []byte(fullName), nil 697} 698 699var customMarshalerData = customMarshaler{FirsName: "Sally", LastName: "Fields"} 700var customMarshalerToml = []byte(`Sally Fields`) 701var nestedCustomMarshalerData = customMarshalerParent{ 702 Self: customMarshaler{FirsName: "Maiku", LastName: "Suteda"}, 703 Friends: []customMarshaler{customMarshalerData}, 704} 705var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"] 706me = "Maiku Suteda" 707`) 708 709func TestCustomMarshaler(t *testing.T) { 710 result, err := Marshal(customMarshalerData) 711 if err != nil { 712 t.Fatal(err) 713 } 714 expected := customMarshalerToml 715 if !bytes.Equal(result, expected) { 716 t.Errorf("Bad custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 717 } 718} 719 720func TestNestedCustomMarshaler(t *testing.T) { 721 result, err := Marshal(nestedCustomMarshalerData) 722 if err != nil { 723 t.Fatal(err) 724 } 725 expected := nestedCustomMarshalerToml 726 if !bytes.Equal(result, expected) { 727 t.Errorf("Bad nested custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 728 } 729} 730 731var commentTestToml = []byte(` 732# it's a comment on type 733[postgres] 734 # isCommented = "dvalue" 735 noComment = "cvalue" 736 737 # A comment on AttrB with a 738 # break line 739 password = "bvalue" 740 741 # A comment on AttrA 742 user = "avalue" 743 744 [[postgres.My]] 745 746 # a comment on my on typeC 747 My = "Foo" 748 749 [[postgres.My]] 750 751 # a comment on my on typeC 752 My = "Baar" 753`) 754 755func TestMarshalComment(t *testing.T) { 756 type TypeC struct { 757 My string `comment:"a comment on my on typeC"` 758 } 759 type TypeB struct { 760 AttrA string `toml:"user" comment:"A comment on AttrA"` 761 AttrB string `toml:"password" comment:"A comment on AttrB with a\n break line"` 762 AttrC string `toml:"noComment"` 763 AttrD string `toml:"isCommented" commented:"true"` 764 My []TypeC 765 } 766 type TypeA struct { 767 TypeB TypeB `toml:"postgres" comment:"it's a comment on type"` 768 } 769 770 ta := []TypeC{{My: "Foo"}, {My: "Baar"}} 771 config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", AttrC: "cvalue", AttrD: "dvalue", My: ta}} 772 result, err := Marshal(config) 773 if err != nil { 774 t.Fatal(err) 775 } 776 expected := commentTestToml 777 if !bytes.Equal(result, expected) { 778 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 779 } 780} 781 782type mapsTestStruct struct { 783 Simple map[string]string 784 Paths map[string]string 785 Other map[string]float64 786 X struct { 787 Y struct { 788 Z map[string]bool 789 } 790 } 791} 792 793var mapsTestData = mapsTestStruct{ 794 Simple: map[string]string{ 795 "one plus one": "two", 796 "next": "three", 797 }, 798 Paths: map[string]string{ 799 "/this/is/a/path": "/this/is/also/a/path", 800 "/heloo.txt": "/tmp/lololo.txt", 801 }, 802 Other: map[string]float64{ 803 "testing": 3.9999, 804 }, 805 X: struct{ Y struct{ Z map[string]bool } }{ 806 Y: struct{ Z map[string]bool }{ 807 Z: map[string]bool{ 808 "is.Nested": true, 809 }, 810 }, 811 }, 812} 813var mapsTestToml = []byte(` 814[Other] 815 "testing" = 3.9999 816 817[Paths] 818 "/heloo.txt" = "/tmp/lololo.txt" 819 "/this/is/a/path" = "/this/is/also/a/path" 820 821[Simple] 822 "next" = "three" 823 "one plus one" = "two" 824 825[X] 826 827 [X.Y] 828 829 [X.Y.Z] 830 "is.Nested" = true 831`) 832 833func TestEncodeQuotedMapKeys(t *testing.T) { 834 var buf bytes.Buffer 835 if err := NewEncoder(&buf).QuoteMapKeys(true).Encode(mapsTestData); err != nil { 836 t.Fatal(err) 837 } 838 result := buf.Bytes() 839 expected := mapsTestToml 840 if !bytes.Equal(result, expected) { 841 t.Errorf("Bad maps marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 842 } 843} 844 845func TestDecodeQuotedMapKeys(t *testing.T) { 846 result := mapsTestStruct{} 847 err := NewDecoder(bytes.NewBuffer(mapsTestToml)).Decode(&result) 848 expected := mapsTestData 849 if err != nil { 850 t.Fatal(err) 851 } 852 if !reflect.DeepEqual(result, expected) { 853 t.Errorf("Bad maps unmarshal: expected %v, got %v", expected, result) 854 } 855} 856 857type structArrayNoTag struct { 858 A struct { 859 B []int64 860 C []int64 861 } 862} 863 864func TestMarshalArray(t *testing.T) { 865 expected := []byte(` 866[A] 867 B = [1,2,3] 868 C = [1] 869`) 870 871 m := structArrayNoTag{ 872 A: struct { 873 B []int64 874 C []int64 875 }{ 876 B: []int64{1, 2, 3}, 877 C: []int64{1}, 878 }, 879 } 880 881 b, err := Marshal(m) 882 883 if err != nil { 884 t.Fatal(err) 885 } 886 887 if !bytes.Equal(b, expected) { 888 t.Errorf("Bad arrays marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, b) 889 } 890} 891 892func TestMarshalArrayOnePerLine(t *testing.T) { 893 expected := []byte(` 894[A] 895 B = [ 896 1, 897 2, 898 3, 899 ] 900 C = [1] 901`) 902 903 m := structArrayNoTag{ 904 A: struct { 905 B []int64 906 C []int64 907 }{ 908 B: []int64{1, 2, 3}, 909 C: []int64{1}, 910 }, 911 } 912 913 var buf bytes.Buffer 914 encoder := NewEncoder(&buf).ArraysWithOneElementPerLine(true) 915 err := encoder.Encode(m) 916 917 if err != nil { 918 t.Fatal(err) 919 } 920 921 b := buf.Bytes() 922 923 if !bytes.Equal(b, expected) { 924 t.Errorf("Bad arrays marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, b) 925 } 926} 927 928var customTagTestToml = []byte(` 929[postgres] 930 password = "bvalue" 931 user = "avalue" 932 933 [[postgres.My]] 934 My = "Foo" 935 936 [[postgres.My]] 937 My = "Baar" 938`) 939 940func TestMarshalCustomTag(t *testing.T) { 941 type TypeC struct { 942 My string 943 } 944 type TypeB struct { 945 AttrA string `file:"user"` 946 AttrB string `file:"password"` 947 My []TypeC 948 } 949 type TypeA struct { 950 TypeB TypeB `file:"postgres"` 951 } 952 953 ta := []TypeC{{My: "Foo"}, {My: "Baar"}} 954 config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", My: ta}} 955 var buf bytes.Buffer 956 err := NewEncoder(&buf).SetTagName("file").Encode(config) 957 if err != nil { 958 t.Fatal(err) 959 } 960 expected := customTagTestToml 961 result := buf.Bytes() 962 if !bytes.Equal(result, expected) { 963 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 964 } 965} 966 967var customCommentTagTestToml = []byte(` 968# db connection 969[postgres] 970 971 # db pass 972 password = "bvalue" 973 974 # db user 975 user = "avalue" 976`) 977 978func TestMarshalCustomComment(t *testing.T) { 979 type TypeB struct { 980 AttrA string `toml:"user" descr:"db user"` 981 AttrB string `toml:"password" descr:"db pass"` 982 } 983 type TypeA struct { 984 TypeB TypeB `toml:"postgres" descr:"db connection"` 985 } 986 987 config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue"}} 988 var buf bytes.Buffer 989 err := NewEncoder(&buf).SetTagComment("descr").Encode(config) 990 if err != nil { 991 t.Fatal(err) 992 } 993 expected := customCommentTagTestToml 994 result := buf.Bytes() 995 if !bytes.Equal(result, expected) { 996 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 997 } 998} 999 1000var customCommentedTagTestToml = []byte(` 1001[postgres] 1002 # password = "bvalue" 1003 # user = "avalue" 1004`) 1005 1006func TestMarshalCustomCommented(t *testing.T) { 1007 type TypeB struct { 1008 AttrA string `toml:"user" disable:"true"` 1009 AttrB string `toml:"password" disable:"true"` 1010 } 1011 type TypeA struct { 1012 TypeB TypeB `toml:"postgres"` 1013 } 1014 1015 config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue"}} 1016 var buf bytes.Buffer 1017 err := NewEncoder(&buf).SetTagCommented("disable").Encode(config) 1018 if err != nil { 1019 t.Fatal(err) 1020 } 1021 expected := customCommentedTagTestToml 1022 result := buf.Bytes() 1023 if !bytes.Equal(result, expected) { 1024 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 1025 } 1026} 1027 1028var customMultilineTagTestToml = []byte(`int_slice = [ 1029 1, 1030 2, 1031 3, 1032] 1033`) 1034 1035func TestMarshalCustomMultiline(t *testing.T) { 1036 type TypeA struct { 1037 AttrA []int `toml:"int_slice" mltln:"true"` 1038 } 1039 1040 config := TypeA{AttrA: []int{1, 2, 3}} 1041 var buf bytes.Buffer 1042 err := NewEncoder(&buf).ArraysWithOneElementPerLine(true).SetTagMultiline("mltln").Encode(config) 1043 if err != nil { 1044 t.Fatal(err) 1045 } 1046 expected := customMultilineTagTestToml 1047 result := buf.Bytes() 1048 if !bytes.Equal(result, expected) { 1049 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 1050 } 1051} 1052 1053var testDocBasicToml = []byte(` 1054[document] 1055 bool_val = true 1056 date_val = 1979-05-27T07:32:00Z 1057 float_val = 123.4 1058 int_val = 5000 1059 string_val = "Bite me" 1060 uint_val = 5001 1061`) 1062 1063type testDocCustomTag struct { 1064 Doc testDocBasicsCustomTag `file:"document"` 1065} 1066type testDocBasicsCustomTag struct { 1067 Bool bool `file:"bool_val"` 1068 Date time.Time `file:"date_val"` 1069 Float float32 `file:"float_val"` 1070 Int int `file:"int_val"` 1071 Uint uint `file:"uint_val"` 1072 String *string `file:"string_val"` 1073 unexported int `file:"shouldntBeHere"` 1074} 1075 1076var testDocCustomTagData = testDocCustomTag{ 1077 Doc: testDocBasicsCustomTag{ 1078 Bool: true, 1079 Date: time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC), 1080 Float: 123.4, 1081 Int: 5000, 1082 Uint: 5001, 1083 String: &biteMe, 1084 unexported: 0, 1085 }, 1086} 1087 1088func TestUnmarshalCustomTag(t *testing.T) { 1089 buf := bytes.NewBuffer(testDocBasicToml) 1090 1091 result := testDocCustomTag{} 1092 err := NewDecoder(buf).SetTagName("file").Decode(&result) 1093 if err != nil { 1094 t.Fatal(err) 1095 } 1096 expected := testDocCustomTagData 1097 if !reflect.DeepEqual(result, expected) { 1098 resStr, _ := json.MarshalIndent(result, "", " ") 1099 expStr, _ := json.MarshalIndent(expected, "", " ") 1100 t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) 1101 1102 } 1103} 1104 1105func TestUnmarshalMap(t *testing.T) { 1106 testToml := []byte(` 1107 a = 1 1108 b = 2 1109 c = 3 1110 `) 1111 var result map[string]int 1112 err := Unmarshal(testToml, &result) 1113 if err != nil { 1114 t.Errorf("Received unexpected error: %s", err) 1115 return 1116 } 1117 1118 expected := map[string]int{ 1119 "a": 1, 1120 "b": 2, 1121 "c": 3, 1122 } 1123 1124 if !reflect.DeepEqual(result, expected) { 1125 t.Errorf("Bad unmarshal: expected %v, got %v", expected, result) 1126 } 1127} 1128 1129func TestUnmarshalMapWithTypedKey(t *testing.T) { 1130 testToml := []byte(` 1131 a = 1 1132 b = 2 1133 c = 3 1134 `) 1135 1136 type letter string 1137 var result map[letter]int 1138 err := Unmarshal(testToml, &result) 1139 if err != nil { 1140 t.Errorf("Received unexpected error: %s", err) 1141 return 1142 } 1143 1144 expected := map[letter]int{ 1145 "a": 1, 1146 "b": 2, 1147 "c": 3, 1148 } 1149 1150 if !reflect.DeepEqual(result, expected) { 1151 t.Errorf("Bad unmarshal: expected %v, got %v", expected, result) 1152 } 1153} 1154 1155func TestUnmarshalNonPointer(t *testing.T) { 1156 a := 1 1157 err := Unmarshal([]byte{}, a) 1158 if err == nil { 1159 t.Fatal("unmarshal should err when given a non pointer") 1160 } 1161} 1162 1163func TestUnmarshalInvalidPointerKind(t *testing.T) { 1164 a := 1 1165 err := Unmarshal([]byte{}, &a) 1166 if err == nil { 1167 t.Fatal("unmarshal should err when given an invalid pointer type") 1168 } 1169} 1170 1171func TestMarshalSlice(t *testing.T) { 1172 m := make([]int, 1) 1173 m[0] = 1 1174 1175 var buf bytes.Buffer 1176 err := NewEncoder(&buf).Encode(&m) 1177 if err == nil { 1178 t.Error("expected error, got nil") 1179 return 1180 } 1181 if err.Error() != "Only pointer to struct can be marshaled to TOML" { 1182 t.Fail() 1183 } 1184} 1185 1186func TestMarshalSlicePointer(t *testing.T) { 1187 m := make([]int, 1) 1188 m[0] = 1 1189 1190 var buf bytes.Buffer 1191 err := NewEncoder(&buf).Encode(m) 1192 if err == nil { 1193 t.Error("expected error, got nil") 1194 return 1195 } 1196 if err.Error() != "Only a struct or map can be marshaled to TOML" { 1197 t.Fail() 1198 } 1199} 1200 1201type testDuration struct { 1202 Nanosec time.Duration `toml:"nanosec"` 1203 Microsec1 time.Duration `toml:"microsec1"` 1204 Microsec2 *time.Duration `toml:"microsec2"` 1205 Millisec time.Duration `toml:"millisec"` 1206 Sec time.Duration `toml:"sec"` 1207 Min time.Duration `toml:"min"` 1208 Hour time.Duration `toml:"hour"` 1209 Mixed time.Duration `toml:"mixed"` 1210 AString string `toml:"a_string"` 1211} 1212 1213var testDurationToml = []byte(` 1214nanosec = "1ns" 1215microsec1 = "1us" 1216microsec2 = "1µs" 1217millisec = "1ms" 1218sec = "1s" 1219min = "1m" 1220hour = "1h" 1221mixed = "1h1m1s1ms1µs1ns" 1222a_string = "15s" 1223`) 1224 1225func TestUnmarshalDuration(t *testing.T) { 1226 buf := bytes.NewBuffer(testDurationToml) 1227 1228 result := testDuration{} 1229 err := NewDecoder(buf).Decode(&result) 1230 if err != nil { 1231 t.Fatal(err) 1232 } 1233 ms := time.Duration(1) * time.Microsecond 1234 expected := testDuration{ 1235 Nanosec: 1, 1236 Microsec1: time.Microsecond, 1237 Microsec2: &ms, 1238 Millisec: time.Millisecond, 1239 Sec: time.Second, 1240 Min: time.Minute, 1241 Hour: time.Hour, 1242 Mixed: time.Hour + 1243 time.Minute + 1244 time.Second + 1245 time.Millisecond + 1246 time.Microsecond + 1247 time.Nanosecond, 1248 AString: "15s", 1249 } 1250 if !reflect.DeepEqual(result, expected) { 1251 resStr, _ := json.MarshalIndent(result, "", " ") 1252 expStr, _ := json.MarshalIndent(expected, "", " ") 1253 t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr) 1254 1255 } 1256} 1257 1258var testDurationToml2 = []byte(`a_string = "15s" 1259hour = "1h0m0s" 1260microsec1 = "1µs" 1261microsec2 = "1µs" 1262millisec = "1ms" 1263min = "1m0s" 1264mixed = "1h1m1.001001001s" 1265nanosec = "1ns" 1266sec = "1s" 1267`) 1268 1269func TestMarshalDuration(t *testing.T) { 1270 ms := time.Duration(1) * time.Microsecond 1271 data := testDuration{ 1272 Nanosec: 1, 1273 Microsec1: time.Microsecond, 1274 Microsec2: &ms, 1275 Millisec: time.Millisecond, 1276 Sec: time.Second, 1277 Min: time.Minute, 1278 Hour: time.Hour, 1279 Mixed: time.Hour + 1280 time.Minute + 1281 time.Second + 1282 time.Millisecond + 1283 time.Microsecond + 1284 time.Nanosecond, 1285 AString: "15s", 1286 } 1287 1288 var buf bytes.Buffer 1289 err := NewEncoder(&buf).Encode(data) 1290 if err != nil { 1291 t.Fatal(err) 1292 } 1293 expected := testDurationToml2 1294 result := buf.Bytes() 1295 if !bytes.Equal(result, expected) { 1296 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result) 1297 } 1298} 1299 1300type testBadDuration struct { 1301 Val time.Duration `toml:"val"` 1302} 1303 1304var testBadDurationToml = []byte(`val = "1z"`) 1305 1306func TestUnmarshalBadDuration(t *testing.T) { 1307 buf := bytes.NewBuffer(testBadDurationToml) 1308 1309 result := testBadDuration{} 1310 err := NewDecoder(buf).Decode(&result) 1311 if err == nil { 1312 t.Fatal() 1313 } 1314 if err.Error() != "(1, 1): Can't convert 1z(string) to time.Duration. time: unknown unit z in duration 1z" { 1315 t.Fatalf("unexpected error: %s", err) 1316 } 1317} 1318 1319var testCamelCaseKeyToml = []byte(`fooBar = 10`) 1320 1321func TestUnmarshalCamelCaseKey(t *testing.T) { 1322 var x struct { 1323 FooBar int 1324 B int 1325 } 1326 1327 if err := Unmarshal(testCamelCaseKeyToml, &x); err != nil { 1328 t.Fatal(err) 1329 } 1330 1331 if x.FooBar != 10 { 1332 t.Fatal("Did not set camelCase'd key") 1333 } 1334} 1335 1336func TestUnmarshalDefault(t *testing.T) { 1337 var doc struct { 1338 StringField string `default:"a"` 1339 BoolField bool `default:"true"` 1340 IntField int `default:"1"` 1341 Int64Field int64 `default:"2"` 1342 Float64Field float64 `default:"3.1"` 1343 } 1344 1345 err := Unmarshal([]byte(``), &doc) 1346 if err != nil { 1347 t.Fatal(err) 1348 } 1349 if doc.BoolField != true { 1350 t.Errorf("BoolField should be true, not %t", doc.BoolField) 1351 } 1352 if doc.StringField != "a" { 1353 t.Errorf("StringField should be \"a\", not %s", doc.StringField) 1354 } 1355 if doc.IntField != 1 { 1356 t.Errorf("IntField should be 1, not %d", doc.IntField) 1357 } 1358 if doc.Int64Field != 2 { 1359 t.Errorf("Int64Field should be 2, not %d", doc.Int64Field) 1360 } 1361 if doc.Float64Field != 3.1 { 1362 t.Errorf("Float64Field should be 3.1, not %f", doc.Float64Field) 1363 } 1364} 1365 1366func TestUnmarshalDefaultFailureBool(t *testing.T) { 1367 var doc struct { 1368 Field bool `default:"blah"` 1369 } 1370 1371 err := Unmarshal([]byte(``), &doc) 1372 if err == nil { 1373 t.Fatal("should error") 1374 } 1375} 1376 1377func TestUnmarshalDefaultFailureInt(t *testing.T) { 1378 var doc struct { 1379 Field int `default:"blah"` 1380 } 1381 1382 err := Unmarshal([]byte(``), &doc) 1383 if err == nil { 1384 t.Fatal("should error") 1385 } 1386} 1387 1388func TestUnmarshalDefaultFailureInt64(t *testing.T) { 1389 var doc struct { 1390 Field int64 `default:"blah"` 1391 } 1392 1393 err := Unmarshal([]byte(``), &doc) 1394 if err == nil { 1395 t.Fatal("should error") 1396 } 1397} 1398 1399func TestUnmarshalDefaultFailureFloat64(t *testing.T) { 1400 var doc struct { 1401 Field float64 `default:"blah"` 1402 } 1403 1404 err := Unmarshal([]byte(``), &doc) 1405 if err == nil { 1406 t.Fatal("should error") 1407 } 1408} 1409 1410func TestUnmarshalDefaultFailureUnsupported(t *testing.T) { 1411 var doc struct { 1412 Field struct{} `default:"blah"` 1413 } 1414 1415 err := Unmarshal([]byte(``), &doc) 1416 if err == nil { 1417 t.Fatal("should error") 1418 } 1419} 1420