OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / pelletier / go-toml / marshal_test.go
1 package toml
2
3 import (
4         "bytes"
5         "encoding/json"
6         "fmt"
7         "io/ioutil"
8         "reflect"
9         "strings"
10         "testing"
11         "time"
12 )
13
14 type basicMarshalTestStruct struct {
15         String     string                      `toml:"string"`
16         StringList []string                    `toml:"strlist"`
17         Sub        basicMarshalTestSubStruct   `toml:"subdoc"`
18         SubList    []basicMarshalTestSubStruct `toml:"sublist"`
19 }
20
21 type basicMarshalTestSubStruct struct {
22         String2 string
23 }
24
25 var basicTestData = basicMarshalTestStruct{
26         String:     "Hello",
27         StringList: []string{"Howdy", "Hey There"},
28         Sub:        basicMarshalTestSubStruct{"One"},
29         SubList:    []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
30 }
31
32 var basicTestToml = []byte(`string = "Hello"
33 strlist = ["Howdy","Hey There"]
34
35 [subdoc]
36   String2 = "One"
37
38 [[sublist]]
39   String2 = "Two"
40
41 [[sublist]]
42   String2 = "Three"
43 `)
44
45 func TestBasicMarshal(t *testing.T) {
46         result, err := Marshal(basicTestData)
47         if err != nil {
48                 t.Fatal(err)
49         }
50         expected := basicTestToml
51         if !bytes.Equal(result, expected) {
52                 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
53         }
54 }
55
56 func TestBasicUnmarshal(t *testing.T) {
57         result := basicMarshalTestStruct{}
58         err := Unmarshal(basicTestToml, &result)
59         expected := basicTestData
60         if err != nil {
61                 t.Fatal(err)
62         }
63         if !reflect.DeepEqual(result, expected) {
64                 t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
65         }
66 }
67
68 type testDoc struct {
69         Title       string            `toml:"title"`
70         Basics      testDocBasics     `toml:"basic"`
71         BasicLists  testDocBasicLists `toml:"basic_lists"`
72         BasicMap    map[string]string `toml:"basic_map"`
73         Subdocs     testDocSubs       `toml:"subdoc"`
74         SubDocList  []testSubDoc      `toml:"subdoclist"`
75         SubDocPtrs  []*testSubDoc     `toml:"subdocptrs"`
76         err         int               `toml:"shouldntBeHere"`
77         unexported  int               `toml:"shouldntBeHere"`
78         Unexported2 int               `toml:"-"`
79 }
80
81 type testDocBasics struct {
82         Bool       bool      `toml:"bool"`
83         Date       time.Time `toml:"date"`
84         Float      float32   `toml:"float"`
85         Int        int       `toml:"int"`
86         Uint       uint      `toml:"uint"`
87         String     *string   `toml:"string"`
88         unexported int       `toml:"shouldntBeHere"`
89 }
90
91 type testDocBasicLists struct {
92         Bools   []bool      `toml:"bools"`
93         Dates   []time.Time `toml:"dates"`
94         Floats  []*float32  `toml:"floats"`
95         Ints    []int       `toml:"ints"`
96         Strings []string    `toml:"strings"`
97         UInts   []uint      `toml:"uints"`
98 }
99
100 type testDocSubs struct {
101         First  testSubDoc  `toml:"first"`
102         Second *testSubDoc `toml:"second"`
103 }
104
105 type testSubDoc struct {
106         Name       string `toml:"name"`
107         unexported int    `toml:"shouldntBeHere"`
108 }
109
110 var biteMe = "Bite me"
111 var float1 float32 = 12.3
112 var float2 float32 = 45.6
113 var float3 float32 = 78.9
114 var subdoc = testSubDoc{"Second", 0}
115
116 var docData = testDoc{
117         Title:       "TOML Marshal Testing",
118         unexported:  0,
119         Unexported2: 0,
120         Basics: testDocBasics{
121                 Bool:       true,
122                 Date:       time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC),
123                 Float:      123.4,
124                 Int:        5000,
125                 Uint:       5001,
126                 String:     &biteMe,
127                 unexported: 0,
128         },
129         BasicLists: testDocBasicLists{
130                 Bools: []bool{true, false, true},
131                 Dates: []time.Time{
132                         time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC),
133                         time.Date(1980, 5, 27, 7, 32, 0, 0, time.UTC),
134                 },
135                 Floats:  []*float32{&float1, &float2, &float3},
136                 Ints:    []int{8001, 8001, 8002},
137                 Strings: []string{"One", "Two", "Three"},
138                 UInts:   []uint{5002, 5003},
139         },
140         BasicMap: map[string]string{
141                 "one": "one",
142                 "two": "two",
143         },
144         Subdocs: testDocSubs{
145                 First:  testSubDoc{"First", 0},
146                 Second: &subdoc,
147         },
148         SubDocList: []testSubDoc{
149                 testSubDoc{"List.First", 0},
150                 testSubDoc{"List.Second", 0},
151         },
152         SubDocPtrs: []*testSubDoc{&subdoc},
153 }
154
155 func TestDocMarshal(t *testing.T) {
156         result, err := Marshal(docData)
157         if err != nil {
158                 t.Fatal(err)
159         }
160         expected, _ := ioutil.ReadFile("marshal_test.toml")
161         if !bytes.Equal(result, expected) {
162                 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
163         }
164 }
165
166 func TestDocUnmarshal(t *testing.T) {
167         result := testDoc{}
168         tomlData, _ := ioutil.ReadFile("marshal_test.toml")
169         err := Unmarshal(tomlData, &result)
170         expected := docData
171         if err != nil {
172                 t.Fatal(err)
173         }
174         if !reflect.DeepEqual(result, expected) {
175                 resStr, _ := json.MarshalIndent(result, "", "  ")
176                 expStr, _ := json.MarshalIndent(expected, "", "  ")
177                 t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
178         }
179 }
180
181 func TestDocPartialUnmarshal(t *testing.T) {
182         result := testDocSubs{}
183
184         tree, _ := LoadFile("marshal_test.toml")
185         subTree := tree.Get("subdoc").(*Tree)
186         err := subTree.Unmarshal(&result)
187         expected := docData.Subdocs
188         if err != nil {
189                 t.Fatal(err)
190         }
191         if !reflect.DeepEqual(result, expected) {
192                 resStr, _ := json.MarshalIndent(result, "", "  ")
193                 expStr, _ := json.MarshalIndent(expected, "", "  ")
194                 t.Errorf("Bad partial unmartial: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
195         }
196 }
197
198 type tomlTypeCheckTest struct {
199         name string
200         item interface{}
201         typ  int //0=primitive, 1=otherslice, 2=treeslice, 3=tree
202 }
203
204 func TestTypeChecks(t *testing.T) {
205         tests := []tomlTypeCheckTest{
206                 {"integer", 2, 0},
207                 {"time", time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC), 0},
208                 {"stringlist", []string{"hello", "hi"}, 1},
209                 {"timelist", []time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
210                 {"objectlist", []tomlTypeCheckTest{}, 2},
211                 {"object", tomlTypeCheckTest{}, 3},
212         }
213
214         for _, test := range tests {
215                 expected := []bool{false, false, false, false}
216                 expected[test.typ] = true
217                 result := []bool{
218                         isPrimitive(reflect.TypeOf(test.item)),
219                         isOtherSlice(reflect.TypeOf(test.item)),
220                         isTreeSlice(reflect.TypeOf(test.item)),
221                         isTree(reflect.TypeOf(test.item)),
222                 }
223                 if !reflect.DeepEqual(expected, result) {
224                         t.Errorf("Bad type check on %q: expected %v, got %v", test.name, expected, result)
225                 }
226         }
227 }
228
229 type unexportedMarshalTestStruct struct {
230         String      string                      `toml:"string"`
231         StringList  []string                    `toml:"strlist"`
232         Sub         basicMarshalTestSubStruct   `toml:"subdoc"`
233         SubList     []basicMarshalTestSubStruct `toml:"sublist"`
234         unexported  int                         `toml:"shouldntBeHere"`
235         Unexported2 int                         `toml:"-"`
236 }
237
238 var unexportedTestData = unexportedMarshalTestStruct{
239         String:      "Hello",
240         StringList:  []string{"Howdy", "Hey There"},
241         Sub:         basicMarshalTestSubStruct{"One"},
242         SubList:     []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
243         unexported:  0,
244         Unexported2: 0,
245 }
246
247 var unexportedTestToml = []byte(`string = "Hello"
248 strlist = ["Howdy","Hey There"]
249 unexported = 1
250 shouldntBeHere = 2
251
252 [subdoc]
253   String2 = "One"
254
255 [[sublist]]
256   String2 = "Two"
257
258 [[sublist]]
259   String2 = "Three"
260 `)
261
262 func TestUnexportedUnmarshal(t *testing.T) {
263         result := unexportedMarshalTestStruct{}
264         err := Unmarshal(unexportedTestToml, &result)
265         expected := unexportedTestData
266         if err != nil {
267                 t.Fatal(err)
268         }
269         if !reflect.DeepEqual(result, expected) {
270                 t.Errorf("Bad unexported unmarshal: expected %v, got %v", expected, result)
271         }
272 }
273
274 type errStruct struct {
275         Bool   bool      `toml:"bool"`
276         Date   time.Time `toml:"date"`
277         Float  float64   `toml:"float"`
278         Int    int16     `toml:"int"`
279         String *string   `toml:"string"`
280 }
281
282 var errTomls = []string{
283         "bool = truly\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
284         "bool = true\ndate = 1979-05-27T07:3200Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
285         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123a4\nint = 5000\nstring = \"Bite me\"",
286         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = j000\nstring = \"Bite me\"",
287         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me",
288         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me",
289         "bool = 1\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
290         "bool = true\ndate = 1\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
291         "bool = true\ndate = 1979-05-27T07:32:00Z\n\"sorry\"\nint = 5000\nstring = \"Bite me\"",
292         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = \"sorry\"\nstring = \"Bite me\"",
293         "bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = 1",
294 }
295
296 type mapErr struct {
297         Vals map[string]float64
298 }
299
300 type intErr struct {
301         Int1  int
302         Int2  int8
303         Int3  int16
304         Int4  int32
305         Int5  int64
306         UInt1 uint
307         UInt2 uint8
308         UInt3 uint16
309         UInt4 uint32
310         UInt5 uint64
311         Flt1  float32
312         Flt2  float64
313 }
314
315 var intErrTomls = []string{
316         "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",
317         "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",
318         "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",
319         "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",
320         "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",
321         "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",
322         "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",
323         "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",
324         "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",
325         "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",
326         "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = []\nFlt2 = 2.0",
327         "Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = []",
328 }
329
330 func TestErrUnmarshal(t *testing.T) {
331         for ind, toml := range errTomls {
332                 result := errStruct{}
333                 err := Unmarshal([]byte(toml), &result)
334                 if err == nil {
335                         t.Errorf("Expected err from case %d\n", ind)
336                 }
337         }
338         result2 := mapErr{}
339         err := Unmarshal([]byte("[Vals]\nfred=\"1.2\""), &result2)
340         if err == nil {
341                 t.Errorf("Expected err from map")
342         }
343         for ind, toml := range intErrTomls {
344                 result3 := intErr{}
345                 err := Unmarshal([]byte(toml), &result3)
346                 if err == nil {
347                         t.Errorf("Expected int err from case %d\n", ind)
348                 }
349         }
350 }
351
352 type emptyMarshalTestStruct struct {
353         Title      string                  `toml:"title"`
354         Bool       bool                    `toml:"bool"`
355         Int        int                     `toml:"int"`
356         String     string                  `toml:"string"`
357         StringList []string                `toml:"stringlist"`
358         Ptr        *basicMarshalTestStruct `toml:"ptr"`
359         Map        map[string]string       `toml:"map"`
360 }
361
362 var emptyTestData = emptyMarshalTestStruct{
363         Title:      "Placeholder",
364         Bool:       false,
365         Int:        0,
366         String:     "",
367         StringList: []string{},
368         Ptr:        nil,
369         Map:        map[string]string{},
370 }
371
372 var emptyTestToml = []byte(`bool = false
373 int = 0
374 string = ""
375 stringlist = []
376 title = "Placeholder"
377
378 [map]
379 `)
380
381 type emptyMarshalTestStruct2 struct {
382         Title      string                  `toml:"title"`
383         Bool       bool                    `toml:"bool,omitempty"`
384         Int        int                     `toml:"int, omitempty"`
385         String     string                  `toml:"string,omitempty "`
386         StringList []string                `toml:"stringlist,omitempty"`
387         Ptr        *basicMarshalTestStruct `toml:"ptr,omitempty"`
388         Map        map[string]string       `toml:"map,omitempty"`
389 }
390
391 var emptyTestData2 = emptyMarshalTestStruct2{
392         Title:      "Placeholder",
393         Bool:       false,
394         Int:        0,
395         String:     "",
396         StringList: []string{},
397         Ptr:        nil,
398         Map:        map[string]string{},
399 }
400
401 var emptyTestToml2 = []byte(`title = "Placeholder"
402 `)
403
404 func TestEmptyMarshal(t *testing.T) {
405         result, err := Marshal(emptyTestData)
406         if err != nil {
407                 t.Fatal(err)
408         }
409         expected := emptyTestToml
410         if !bytes.Equal(result, expected) {
411                 t.Errorf("Bad empty marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
412         }
413 }
414
415 func TestEmptyMarshalOmit(t *testing.T) {
416         result, err := Marshal(emptyTestData2)
417         if err != nil {
418                 t.Fatal(err)
419         }
420         expected := emptyTestToml2
421         if !bytes.Equal(result, expected) {
422                 t.Errorf("Bad empty omit marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
423         }
424 }
425
426 func TestEmptyUnmarshal(t *testing.T) {
427         result := emptyMarshalTestStruct{}
428         err := Unmarshal(emptyTestToml, &result)
429         expected := emptyTestData
430         if err != nil {
431                 t.Fatal(err)
432         }
433         if !reflect.DeepEqual(result, expected) {
434                 t.Errorf("Bad empty unmarshal: expected %v, got %v", expected, result)
435         }
436 }
437
438 func TestEmptyUnmarshalOmit(t *testing.T) {
439         result := emptyMarshalTestStruct2{}
440         err := Unmarshal(emptyTestToml, &result)
441         expected := emptyTestData2
442         if err != nil {
443                 t.Fatal(err)
444         }
445         if !reflect.DeepEqual(result, expected) {
446                 t.Errorf("Bad empty omit unmarshal: expected %v, got %v", expected, result)
447         }
448 }
449
450 type pointerMarshalTestStruct struct {
451         Str       *string
452         List      *[]string
453         ListPtr   *[]*string
454         Map       *map[string]string
455         MapPtr    *map[string]*string
456         EmptyStr  *string
457         EmptyList *[]string
458         EmptyMap  *map[string]string
459         DblPtr    *[]*[]*string
460 }
461
462 var pointerStr = "Hello"
463 var pointerList = []string{"Hello back"}
464 var pointerListPtr = []*string{&pointerStr}
465 var pointerMap = map[string]string{"response": "Goodbye"}
466 var pointerMapPtr = map[string]*string{"alternate": &pointerStr}
467 var pointerTestData = pointerMarshalTestStruct{
468         Str:       &pointerStr,
469         List:      &pointerList,
470         ListPtr:   &pointerListPtr,
471         Map:       &pointerMap,
472         MapPtr:    &pointerMapPtr,
473         EmptyStr:  nil,
474         EmptyList: nil,
475         EmptyMap:  nil,
476 }
477
478 var pointerTestToml = []byte(`List = ["Hello back"]
479 ListPtr = ["Hello"]
480 Str = "Hello"
481
482 [Map]
483   response = "Goodbye"
484
485 [MapPtr]
486   alternate = "Hello"
487 `)
488
489 func TestPointerMarshal(t *testing.T) {
490         result, err := Marshal(pointerTestData)
491         if err != nil {
492                 t.Fatal(err)
493         }
494         expected := pointerTestToml
495         if !bytes.Equal(result, expected) {
496                 t.Errorf("Bad pointer marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
497         }
498 }
499
500 func TestPointerUnmarshal(t *testing.T) {
501         result := pointerMarshalTestStruct{}
502         err := Unmarshal(pointerTestToml, &result)
503         expected := pointerTestData
504         if err != nil {
505                 t.Fatal(err)
506         }
507         if !reflect.DeepEqual(result, expected) {
508                 t.Errorf("Bad pointer unmarshal: expected %v, got %v", expected, result)
509         }
510 }
511
512 func TestUnmarshalTypeMismatch(t *testing.T) {
513         result := pointerMarshalTestStruct{}
514         err := Unmarshal([]byte("List = 123"), &result)
515         if !strings.HasPrefix(err.Error(), "(1, 1): Can't convert 123(int64) to []string(slice)") {
516                 t.Errorf("Type mismatch must be reported: got %v", err.Error())
517         }
518 }
519
520 type nestedMarshalTestStruct struct {
521         String [][]string
522         //Struct [][]basicMarshalTestSubStruct
523         StringPtr *[]*[]*string
524         // StructPtr *[]*[]*basicMarshalTestSubStruct
525 }
526
527 var str1 = "Three"
528 var str2 = "Four"
529 var strPtr = []*string{&str1, &str2}
530 var strPtr2 = []*[]*string{&strPtr}
531
532 var nestedTestData = nestedMarshalTestStruct{
533         String:    [][]string{[]string{"Five", "Six"}, []string{"One", "Two"}},
534         StringPtr: &strPtr2,
535 }
536
537 var nestedTestToml = []byte(`String = [["Five","Six"],["One","Two"]]
538 StringPtr = [["Three","Four"]]
539 `)
540
541 func TestNestedMarshal(t *testing.T) {
542         result, err := Marshal(nestedTestData)
543         if err != nil {
544                 t.Fatal(err)
545         }
546         expected := nestedTestToml
547         if !bytes.Equal(result, expected) {
548                 t.Errorf("Bad nested marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
549         }
550 }
551
552 func TestNestedUnmarshal(t *testing.T) {
553         result := nestedMarshalTestStruct{}
554         err := Unmarshal(nestedTestToml, &result)
555         expected := nestedTestData
556         if err != nil {
557                 t.Fatal(err)
558         }
559         if !reflect.DeepEqual(result, expected) {
560                 t.Errorf("Bad nested unmarshal: expected %v, got %v", expected, result)
561         }
562 }
563
564 type customMarshalerParent struct {
565         Self    customMarshaler   `toml:"me"`
566         Friends []customMarshaler `toml:"friends"`
567 }
568
569 type customMarshaler struct {
570         FirsName string
571         LastName string
572 }
573
574 func (c customMarshaler) MarshalTOML() ([]byte, error) {
575         fullName := fmt.Sprintf("%s %s", c.FirsName, c.LastName)
576         return []byte(fullName), nil
577 }
578
579 var customMarshalerData = customMarshaler{FirsName: "Sally", LastName: "Fields"}
580 var customMarshalerToml = []byte(`Sally Fields`)
581 var nestedCustomMarshalerData = customMarshalerParent{
582         Self:    customMarshaler{FirsName: "Maiku", LastName: "Suteda"},
583         Friends: []customMarshaler{customMarshalerData},
584 }
585 var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"]
586 me = "Maiku Suteda"
587 `)
588
589 func TestCustomMarshaler(t *testing.T) {
590         result, err := Marshal(customMarshalerData)
591         if err != nil {
592                 t.Fatal(err)
593         }
594         expected := customMarshalerToml
595         if !bytes.Equal(result, expected) {
596                 t.Errorf("Bad custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
597         }
598 }
599
600 func TestNestedCustomMarshaler(t *testing.T) {
601         result, err := Marshal(nestedCustomMarshalerData)
602         if err != nil {
603                 t.Fatal(err)
604         }
605         expected := nestedCustomMarshalerToml
606         if !bytes.Equal(result, expected) {
607                 t.Errorf("Bad nested custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
608         }
609 }
610
611 var commentTestToml = []byte(`
612 # it's a comment on type
613 [postgres]
614   # isCommented = "dvalue"
615   noComment = "cvalue"
616
617   # A comment on AttrB with a
618   # break line
619   password = "bvalue"
620
621   # A comment on AttrA
622   user = "avalue"
623
624   [[postgres.My]]
625
626     # a comment on my on typeC
627     My = "Foo"
628
629   [[postgres.My]]
630
631     # a comment on my on typeC
632     My = "Baar"
633 `)
634
635 func TestMarshalComment(t *testing.T) {
636         type TypeC struct {
637                 My string `comment:"a comment on my on typeC"`
638         }
639         type TypeB struct {
640                 AttrA string `toml:"user" comment:"A comment on AttrA"`
641                 AttrB string `toml:"password" comment:"A comment on AttrB with a\n break line"`
642                 AttrC string `toml:"noComment"`
643                 AttrD string `toml:"isCommented" commented:"true"`
644                 My    []TypeC
645         }
646         type TypeA struct {
647                 TypeB TypeB `toml:"postgres" comment:"it's a comment on type"`
648         }
649
650         ta := []TypeC{{My: "Foo"}, {My: "Baar"}}
651         config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", AttrC: "cvalue", AttrD: "dvalue", My: ta}}
652         result, err := Marshal(config)
653         if err != nil {
654                 t.Fatal(err)
655         }
656         expected := commentTestToml
657         if !bytes.Equal(result, expected) {
658                 t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
659         }
660 }
661
662 type mapsTestStruct struct {
663         Simple map[string]string
664         Paths  map[string]string
665         Other  map[string]float64
666         X      struct {
667                 Y struct {
668                         Z map[string]bool
669                 }
670         }
671 }
672
673 var mapsTestData = mapsTestStruct{
674         Simple: map[string]string{
675                 "one plus one": "two",
676                 "next":         "three",
677         },
678         Paths: map[string]string{
679                 "/this/is/a/path": "/this/is/also/a/path",
680                 "/heloo.txt":      "/tmp/lololo.txt",
681         },
682         Other: map[string]float64{
683                 "testing": 3.9999,
684         },
685         X: struct{ Y struct{ Z map[string]bool } }{
686                 Y: struct{ Z map[string]bool }{
687                         Z: map[string]bool{
688                                 "is.Nested": true,
689                         },
690                 },
691         },
692 }
693 var mapsTestToml = []byte(`
694 [Other]
695   "testing" = 3.9999
696
697 [Paths]
698   "/heloo.txt" = "/tmp/lololo.txt"
699   "/this/is/a/path" = "/this/is/also/a/path"
700
701 [Simple]
702   "next" = "three"
703   "one plus one" = "two"
704
705 [X]
706
707   [X.Y]
708
709     [X.Y.Z]
710       "is.Nested" = true
711 `)
712
713 func TestEncodeQuotedMapKeys(t *testing.T) {
714         var buf bytes.Buffer
715         if err := NewEncoder(&buf).QuoteMapKeys(true).Encode(mapsTestData); err != nil {
716                 t.Fatal(err)
717         }
718         result := buf.Bytes()
719         expected := mapsTestToml
720         if !bytes.Equal(result, expected) {
721                 t.Errorf("Bad maps marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
722         }
723 }
724 func TestDecodeQuotedMapKeys(t *testing.T) {
725         result := mapsTestStruct{}
726         err := NewDecoder(bytes.NewBuffer(mapsTestToml)).Decode(&result)
727         expected := mapsTestData
728         if err != nil {
729                 t.Fatal(err)
730         }
731         if !reflect.DeepEqual(result, expected) {
732                 t.Errorf("Bad maps unmarshal: expected %v, got %v", expected, result)
733         }
734 }