...

Source file src/github.com/pelletier/go-toml/marshal_test.go

Documentation: github.com/pelletier/go-toml

     1  package toml
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"reflect"
    11  	"strconv"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  type basicMarshalTestStruct struct {
    18  	String     string   `toml:"Zstring"`
    19  	StringList []string `toml:"Ystrlist"`
    20  	BasicMarshalTestSubAnonymousStruct
    21  	Sub     basicMarshalTestSubStruct   `toml:"Xsubdoc"`
    22  	SubList []basicMarshalTestSubStruct `toml:"Wsublist"`
    23  }
    24  
    25  type basicMarshalTestSubStruct struct {
    26  	String2 string
    27  }
    28  
    29  type BasicMarshalTestSubAnonymousStruct struct {
    30  	String3 string
    31  }
    32  
    33  var basicTestData = basicMarshalTestStruct{
    34  	String:                             "Hello",
    35  	StringList:                         []string{"Howdy", "Hey There"},
    36  	BasicMarshalTestSubAnonymousStruct: BasicMarshalTestSubAnonymousStruct{"One"},
    37  	Sub:                                basicMarshalTestSubStruct{"Two"},
    38  	SubList:                            []basicMarshalTestSubStruct{{"Three"}, {"Four"}},
    39  }
    40  
    41  var basicTestToml = []byte(`String3 = "One"
    42  Ystrlist = ["Howdy", "Hey There"]
    43  Zstring = "Hello"
    44  
    45  [[Wsublist]]
    46    String2 = "Three"
    47  
    48  [[Wsublist]]
    49    String2 = "Four"
    50  
    51  [Xsubdoc]
    52    String2 = "Two"
    53  `)
    54  
    55  var basicTestTomlCustomIndentation = []byte(`String3 = "One"
    56  Ystrlist = ["Howdy", "Hey There"]
    57  Zstring = "Hello"
    58  
    59  [[Wsublist]]
    60  	String2 = "Three"
    61  
    62  [[Wsublist]]
    63  	String2 = "Four"
    64  
    65  [Xsubdoc]
    66  	String2 = "Two"
    67  `)
    68  
    69  var basicTestTomlOrdered = []byte(`Zstring = "Hello"
    70  Ystrlist = ["Howdy", "Hey There"]
    71  String3 = "One"
    72  
    73  [Xsubdoc]
    74    String2 = "Two"
    75  
    76  [[Wsublist]]
    77    String2 = "Three"
    78  
    79  [[Wsublist]]
    80    String2 = "Four"
    81  `)
    82  
    83  var marshalTestToml = []byte(`title = "TOML Marshal Testing"
    84  
    85  [basic]
    86    bool = true
    87    date = 1979-05-27T07:32:00Z
    88    float = 123.4
    89    float64 = 123.456782132399
    90    int = 5000
    91    string = "Bite me"
    92    uint = 5001
    93  
    94  [basic_lists]
    95    bools = [true, false, true]
    96    dates = [1979-05-27T07:32:00Z, 1980-05-27T07:32:00Z]
    97    floats = [12.3, 45.6, 78.9]
    98    ints = [8001, 8001, 8002]
    99    strings = ["One", "Two", "Three"]
   100    uints = [5002, 5003]
   101  
   102  [basic_map]
   103    one = "one"
   104    two = "two"
   105  
   106  [subdoc]
   107  
   108    [subdoc.first]
   109      name = "First"
   110  
   111    [subdoc.second]
   112      name = "Second"
   113  
   114  [[subdoclist]]
   115    name = "List.First"
   116  
   117  [[subdoclist]]
   118    name = "List.Second"
   119  
   120  [[subdocptrs]]
   121    name = "Second"
   122  `)
   123  
   124  var marshalOrderPreserveToml = []byte(`title = "TOML Marshal Testing"
   125  
   126  [basic_lists]
   127    floats = [12.3, 45.6, 78.9]
   128    bools = [true, false, true]
   129    dates = [1979-05-27T07:32:00Z, 1980-05-27T07:32:00Z]
   130    ints = [8001, 8001, 8002]
   131    uints = [5002, 5003]
   132    strings = ["One", "Two", "Three"]
   133  
   134  [[subdocptrs]]
   135    name = "Second"
   136  
   137  [basic_map]
   138    one = "one"
   139    two = "two"
   140  
   141  [subdoc]
   142  
   143    [subdoc.second]
   144      name = "Second"
   145  
   146    [subdoc.first]
   147      name = "First"
   148  
   149  [basic]
   150    uint = 5001
   151    bool = true
   152    float = 123.4
   153    float64 = 123.456782132399
   154    int = 5000
   155    string = "Bite me"
   156    date = 1979-05-27T07:32:00Z
   157  
   158  [[subdoclist]]
   159    name = "List.First"
   160  
   161  [[subdoclist]]
   162    name = "List.Second"
   163  `)
   164  
   165  var mashalOrderPreserveMapToml = []byte(`title = "TOML Marshal Testing"
   166  
   167  [basic_map]
   168    one = "one"
   169    two = "two"
   170  
   171  [long_map]
   172    a7 = "1"
   173    b3 = "2"
   174    c8 = "3"
   175    d4 = "4"
   176    e6 = "5"
   177    f5 = "6"
   178    g10 = "7"
   179    h1 = "8"
   180    i2 = "9"
   181    j9 = "10"
   182  `)
   183  
   184  type Conf struct {
   185  	Name  string
   186  	Age   int
   187  	Inter interface{}
   188  }
   189  
   190  type NestedStruct struct {
   191  	FirstName string
   192  	LastName  string
   193  	Age       int
   194  }
   195  
   196  var doc = []byte(`Name = "rui"
   197  Age = 18
   198  
   199  [Inter]
   200    FirstName = "wang"
   201    LastName = "jl"
   202    Age = 100`)
   203  
   204  func TestInterface(t *testing.T) {
   205  	var config Conf
   206  	config.Inter = &NestedStruct{}
   207  	err := Unmarshal(doc, &config)
   208  	expected := Conf{
   209  		Name: "rui",
   210  		Age:  18,
   211  		Inter: &NestedStruct{
   212  			FirstName: "wang",
   213  			LastName:  "jl",
   214  			Age:       100,
   215  		},
   216  	}
   217  	if err != nil || !reflect.DeepEqual(config, expected) {
   218  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, config)
   219  	}
   220  }
   221  
   222  func TestBasicMarshal(t *testing.T) {
   223  	result, err := Marshal(basicTestData)
   224  	if err != nil {
   225  		t.Fatal(err)
   226  	}
   227  	expected := basicTestToml
   228  	if !bytes.Equal(result, expected) {
   229  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   230  	}
   231  }
   232  
   233  func TestBasicMarshalCustomIndentation(t *testing.T) {
   234  	var result bytes.Buffer
   235  	err := NewEncoder(&result).Indentation("\t").Encode(basicTestData)
   236  	if err != nil {
   237  		t.Fatal(err)
   238  	}
   239  	expected := basicTestTomlCustomIndentation
   240  	if !bytes.Equal(result.Bytes(), expected) {
   241  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
   242  	}
   243  }
   244  
   245  func TestBasicMarshalWrongIndentation(t *testing.T) {
   246  	var result bytes.Buffer
   247  	err := NewEncoder(&result).Indentation("  \n").Encode(basicTestData)
   248  	if err.Error() != "invalid indentation: must only contains space or tab characters" {
   249  		t.Error("expect err:invalid indentation: must only contains space or tab characters but got:", err)
   250  	}
   251  }
   252  
   253  func TestBasicMarshalOrdered(t *testing.T) {
   254  	var result bytes.Buffer
   255  	err := NewEncoder(&result).Order(OrderPreserve).Encode(basicTestData)
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	}
   259  	expected := basicTestTomlOrdered
   260  	if !bytes.Equal(result.Bytes(), expected) {
   261  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
   262  	}
   263  }
   264  
   265  func TestBasicMarshalWithPointer(t *testing.T) {
   266  	result, err := Marshal(&basicTestData)
   267  	if err != nil {
   268  		t.Fatal(err)
   269  	}
   270  	expected := basicTestToml
   271  	if !bytes.Equal(result, expected) {
   272  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   273  	}
   274  }
   275  
   276  func TestBasicMarshalOrderedWithPointer(t *testing.T) {
   277  	var result bytes.Buffer
   278  	err := NewEncoder(&result).Order(OrderPreserve).Encode(&basicTestData)
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  	expected := basicTestTomlOrdered
   283  	if !bytes.Equal(result.Bytes(), expected) {
   284  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
   285  	}
   286  }
   287  
   288  func TestBasicUnmarshal(t *testing.T) {
   289  	result := basicMarshalTestStruct{}
   290  	err := Unmarshal(basicTestToml, &result)
   291  	expected := basicTestData
   292  	if err != nil {
   293  		t.Fatal(err)
   294  	}
   295  	if !reflect.DeepEqual(result, expected) {
   296  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
   297  	}
   298  }
   299  
   300  type quotedKeyMarshalTestStruct struct {
   301  	String  string                      `toml:"Z.string-àéù"`
   302  	Float   float64                     `toml:"Yfloat-𝟘"`
   303  	Sub     basicMarshalTestSubStruct   `toml:"Xsubdoc-àéù"`
   304  	SubList []basicMarshalTestSubStruct `toml:"W.sublist-𝟘"`
   305  }
   306  
   307  var quotedKeyMarshalTestData = quotedKeyMarshalTestStruct{
   308  	String:  "Hello",
   309  	Float:   3.5,
   310  	Sub:     basicMarshalTestSubStruct{"One"},
   311  	SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
   312  }
   313  
   314  var quotedKeyMarshalTestToml = []byte(`"Yfloat-𝟘" = 3.5
   315  "Z.string-àéù" = "Hello"
   316  
   317  [["W.sublist-𝟘"]]
   318    String2 = "Two"
   319  
   320  [["W.sublist-𝟘"]]
   321    String2 = "Three"
   322  
   323  ["Xsubdoc-àéù"]
   324    String2 = "One"
   325  `)
   326  
   327  func TestBasicMarshalQuotedKey(t *testing.T) {
   328  	result, err := Marshal(quotedKeyMarshalTestData)
   329  	if err != nil {
   330  		t.Fatal(err)
   331  	}
   332  	expected := quotedKeyMarshalTestToml
   333  	if !bytes.Equal(result, expected) {
   334  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   335  	}
   336  }
   337  
   338  func TestBasicUnmarshalQuotedKey(t *testing.T) {
   339  	tree, err := LoadBytes(quotedKeyMarshalTestToml)
   340  	if err != nil {
   341  		t.Fatal(err)
   342  	}
   343  
   344  	var q quotedKeyMarshalTestStruct
   345  	tree.Unmarshal(&q)
   346  	fmt.Println(q)
   347  
   348  	if !reflect.DeepEqual(quotedKeyMarshalTestData, q) {
   349  		t.Errorf("Bad unmarshal: expected\n-----\n%v\n-----\ngot\n-----\n%v\n-----\n", quotedKeyMarshalTestData, q)
   350  	}
   351  }
   352  
   353  type testDoc struct {
   354  	Title       string            `toml:"title"`
   355  	BasicLists  testDocBasicLists `toml:"basic_lists"`
   356  	SubDocPtrs  []*testSubDoc     `toml:"subdocptrs"`
   357  	BasicMap    map[string]string `toml:"basic_map"`
   358  	Subdocs     testDocSubs       `toml:"subdoc"`
   359  	Basics      testDocBasics     `toml:"basic"`
   360  	SubDocList  []testSubDoc      `toml:"subdoclist"`
   361  	err         int               `toml:"shouldntBeHere"`
   362  	unexported  int               `toml:"shouldntBeHere"`
   363  	Unexported2 int               `toml:"-"`
   364  }
   365  
   366  type testMapDoc struct {
   367  	Title    string            `toml:"title"`
   368  	BasicMap map[string]string `toml:"basic_map"`
   369  	LongMap  map[string]string `toml:"long_map"`
   370  }
   371  
   372  type testDocBasics struct {
   373  	Uint       uint      `toml:"uint"`
   374  	Bool       bool      `toml:"bool"`
   375  	Float32    float32   `toml:"float"`
   376  	Float64    float64   `toml:"float64"`
   377  	Int        int       `toml:"int"`
   378  	String     *string   `toml:"string"`
   379  	Date       time.Time `toml:"date"`
   380  	unexported int       `toml:"shouldntBeHere"`
   381  }
   382  
   383  type testDocBasicLists struct {
   384  	Floats  []*float32  `toml:"floats"`
   385  	Bools   []bool      `toml:"bools"`
   386  	Dates   []time.Time `toml:"dates"`
   387  	Ints    []int       `toml:"ints"`
   388  	UInts   []uint      `toml:"uints"`
   389  	Strings []string    `toml:"strings"`
   390  }
   391  
   392  type testDocSubs struct {
   393  	Second *testSubDoc `toml:"second"`
   394  	First  testSubDoc  `toml:"first"`
   395  }
   396  
   397  type testSubDoc struct {
   398  	Name       string `toml:"name"`
   399  	unexported int    `toml:"shouldntBeHere"`
   400  }
   401  
   402  var biteMe = "Bite me"
   403  var float1 float32 = 12.3
   404  var float2 float32 = 45.6
   405  var float3 float32 = 78.9
   406  var subdoc = testSubDoc{"Second", 0}
   407  
   408  var docData = testDoc{
   409  	Title:       "TOML Marshal Testing",
   410  	unexported:  0,
   411  	Unexported2: 0,
   412  	Basics: testDocBasics{
   413  		Bool:       true,
   414  		Date:       time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC),
   415  		Float32:    123.4,
   416  		Float64:    123.456782132399,
   417  		Int:        5000,
   418  		Uint:       5001,
   419  		String:     &biteMe,
   420  		unexported: 0,
   421  	},
   422  	BasicLists: testDocBasicLists{
   423  		Bools: []bool{true, false, true},
   424  		Dates: []time.Time{
   425  			time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC),
   426  			time.Date(1980, 5, 27, 7, 32, 0, 0, time.UTC),
   427  		},
   428  		Floats:  []*float32{&float1, &float2, &float3},
   429  		Ints:    []int{8001, 8001, 8002},
   430  		Strings: []string{"One", "Two", "Three"},
   431  		UInts:   []uint{5002, 5003},
   432  	},
   433  	BasicMap: map[string]string{
   434  		"one": "one",
   435  		"two": "two",
   436  	},
   437  	Subdocs: testDocSubs{
   438  		First:  testSubDoc{"First", 0},
   439  		Second: &subdoc,
   440  	},
   441  	SubDocList: []testSubDoc{
   442  		{"List.First", 0},
   443  		{"List.Second", 0},
   444  	},
   445  	SubDocPtrs: []*testSubDoc{&subdoc},
   446  }
   447  
   448  var mapTestDoc = testMapDoc{
   449  	Title: "TOML Marshal Testing",
   450  	BasicMap: map[string]string{
   451  		"one": "one",
   452  		"two": "two",
   453  	},
   454  	LongMap: map[string]string{
   455  		"h1":  "8",
   456  		"i2":  "9",
   457  		"b3":  "2",
   458  		"d4":  "4",
   459  		"f5":  "6",
   460  		"e6":  "5",
   461  		"a7":  "1",
   462  		"c8":  "3",
   463  		"j9":  "10",
   464  		"g10": "7",
   465  	},
   466  }
   467  
   468  func TestDocMarshal(t *testing.T) {
   469  	result, err := Marshal(docData)
   470  	if err != nil {
   471  		t.Fatal(err)
   472  	}
   473  	if !bytes.Equal(result, marshalTestToml) {
   474  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", marshalTestToml, result)
   475  	}
   476  }
   477  
   478  func TestDocMarshalOrdered(t *testing.T) {
   479  	var result bytes.Buffer
   480  	err := NewEncoder(&result).Order(OrderPreserve).Encode(docData)
   481  	if err != nil {
   482  		t.Fatal(err)
   483  	}
   484  	if !bytes.Equal(result.Bytes(), marshalOrderPreserveToml) {
   485  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", marshalOrderPreserveToml, result.Bytes())
   486  	}
   487  }
   488  
   489  func TestDocMarshalMaps(t *testing.T) {
   490  	result, err := Marshal(mapTestDoc)
   491  	if err != nil {
   492  		t.Fatal(err)
   493  	}
   494  	if !bytes.Equal(result, mashalOrderPreserveMapToml) {
   495  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", mashalOrderPreserveMapToml, result)
   496  	}
   497  }
   498  
   499  func TestDocMarshalOrderedMaps(t *testing.T) {
   500  	var result bytes.Buffer
   501  	err := NewEncoder(&result).Order(OrderPreserve).Encode(mapTestDoc)
   502  	if err != nil {
   503  		t.Fatal(err)
   504  	}
   505  	if !bytes.Equal(result.Bytes(), mashalOrderPreserveMapToml) {
   506  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", mashalOrderPreserveMapToml, result.Bytes())
   507  	}
   508  }
   509  
   510  func TestDocMarshalPointer(t *testing.T) {
   511  	result, err := Marshal(&docData)
   512  	if err != nil {
   513  		t.Fatal(err)
   514  	}
   515  
   516  	if !bytes.Equal(result, marshalTestToml) {
   517  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", marshalTestToml, result)
   518  	}
   519  }
   520  
   521  func TestDocUnmarshal(t *testing.T) {
   522  	result := testDoc{}
   523  	err := Unmarshal(marshalTestToml, &result)
   524  	expected := docData
   525  	if err != nil {
   526  		t.Fatal(err)
   527  	}
   528  	if !reflect.DeepEqual(result, expected) {
   529  		resStr, _ := json.MarshalIndent(result, "", "  ")
   530  		expStr, _ := json.MarshalIndent(expected, "", "  ")
   531  		t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
   532  	}
   533  }
   534  
   535  func TestDocPartialUnmarshal(t *testing.T) {
   536  	file, err := ioutil.TempFile("", "test-*.toml")
   537  	if err != nil {
   538  		t.Fatal(err)
   539  	}
   540  	defer os.Remove(file.Name())
   541  
   542  	err = ioutil.WriteFile(file.Name(), marshalTestToml, 0)
   543  	if err != nil {
   544  		t.Fatal(err)
   545  	}
   546  
   547  	tree, _ := LoadFile(file.Name())
   548  	subTree := tree.Get("subdoc").(*Tree)
   549  
   550  	result := testDocSubs{}
   551  	err = subTree.Unmarshal(&result)
   552  	expected := docData.Subdocs
   553  	if err != nil {
   554  		t.Fatal(err)
   555  	}
   556  	if !reflect.DeepEqual(result, expected) {
   557  		resStr, _ := json.MarshalIndent(result, "", "  ")
   558  		expStr, _ := json.MarshalIndent(expected, "", "  ")
   559  		t.Errorf("Bad partial unmartial: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
   560  	}
   561  }
   562  
   563  type tomlTypeCheckTest struct {
   564  	name string
   565  	item interface{}
   566  	typ  int //0=primitive, 1=otherslice, 2=treeslice, 3=tree
   567  }
   568  
   569  func TestTypeChecks(t *testing.T) {
   570  	tests := []tomlTypeCheckTest{
   571  		{"bool", true, 0},
   572  		{"bool", false, 0},
   573  		{"int", int(2), 0},
   574  		{"int8", int8(2), 0},
   575  		{"int16", int16(2), 0},
   576  		{"int32", int32(2), 0},
   577  		{"int64", int64(2), 0},
   578  		{"uint", uint(2), 0},
   579  		{"uint8", uint8(2), 0},
   580  		{"uint16", uint16(2), 0},
   581  		{"uint32", uint32(2), 0},
   582  		{"uint64", uint64(2), 0},
   583  		{"float32", float32(3.14), 0},
   584  		{"float64", float64(3.14), 0},
   585  		{"string", "lorem ipsum", 0},
   586  		{"time", time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC), 0},
   587  		{"stringlist", []string{"hello", "hi"}, 1},
   588  		{"stringlistptr", &[]string{"hello", "hi"}, 1},
   589  		{"stringarray", [2]string{"hello", "hi"}, 1},
   590  		{"stringarrayptr", &[2]string{"hello", "hi"}, 1},
   591  		{"timelist", []time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
   592  		{"timelistptr", &[]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
   593  		{"timearray", [1]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
   594  		{"timearrayptr", &[1]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
   595  		{"objectlist", []tomlTypeCheckTest{}, 2},
   596  		{"objectlistptr", &[]tomlTypeCheckTest{}, 2},
   597  		{"objectarray", [2]tomlTypeCheckTest{{}, {}}, 2},
   598  		{"objectlistptr", &[2]tomlTypeCheckTest{{}, {}}, 2},
   599  		{"object", tomlTypeCheckTest{}, 3},
   600  		{"objectptr", &tomlTypeCheckTest{}, 3},
   601  	}
   602  
   603  	for _, test := range tests {
   604  		expected := []bool{false, false, false, false}
   605  		expected[test.typ] = true
   606  		result := []bool{
   607  			isPrimitive(reflect.TypeOf(test.item)),
   608  			isOtherSequence(reflect.TypeOf(test.item)),
   609  			isTreeSequence(reflect.TypeOf(test.item)),
   610  			isTree(reflect.TypeOf(test.item)),
   611  		}
   612  		if !reflect.DeepEqual(expected, result) {
   613  			t.Errorf("Bad type check on %q: expected %v, got %v", test.name, expected, result)
   614  		}
   615  	}
   616  }
   617  
   618  type unexportedMarshalTestStruct struct {
   619  	String      string                      `toml:"string"`
   620  	StringList  []string                    `toml:"strlist"`
   621  	Sub         basicMarshalTestSubStruct   `toml:"subdoc"`
   622  	SubList     []basicMarshalTestSubStruct `toml:"sublist"`
   623  	unexported  int                         `toml:"shouldntBeHere"`
   624  	Unexported2 int                         `toml:"-"`
   625  }
   626  
   627  var unexportedTestData = unexportedMarshalTestStruct{
   628  	String:      "Hello",
   629  	StringList:  []string{"Howdy", "Hey There"},
   630  	Sub:         basicMarshalTestSubStruct{"One"},
   631  	SubList:     []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
   632  	unexported:  0,
   633  	Unexported2: 0,
   634  }
   635  
   636  var unexportedTestToml = []byte(`string = "Hello"
   637  strlist = ["Howdy","Hey There"]
   638  unexported = 1
   639  shouldntBeHere = 2
   640  
   641  [subdoc]
   642    String2 = "One"
   643  
   644  [[sublist]]
   645    String2 = "Two"
   646  
   647  [[sublist]]
   648    String2 = "Three"
   649  `)
   650  
   651  func TestUnexportedUnmarshal(t *testing.T) {
   652  	result := unexportedMarshalTestStruct{}
   653  	err := Unmarshal(unexportedTestToml, &result)
   654  	expected := unexportedTestData
   655  	if err != nil {
   656  		t.Fatal(err)
   657  	}
   658  	if !reflect.DeepEqual(result, expected) {
   659  		t.Errorf("Bad unexported unmarshal: expected %v, got %v", expected, result)
   660  	}
   661  }
   662  
   663  type errStruct struct {
   664  	Bool   bool      `toml:"bool"`
   665  	Date   time.Time `toml:"date"`
   666  	Float  float64   `toml:"float"`
   667  	Int    int16     `toml:"int"`
   668  	String *string   `toml:"string"`
   669  }
   670  
   671  var errTomls = []string{
   672  	"bool = truly\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
   673  	"bool = true\ndate = 1979-05-27T07:3200Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
   674  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123a4\nint = 5000\nstring = \"Bite me\"",
   675  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = j000\nstring = \"Bite me\"",
   676  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me",
   677  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = Bite me",
   678  	"bool = 1\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
   679  	"bool = true\ndate = 1\nfloat = 123.4\nint = 5000\nstring = \"Bite me\"",
   680  	"bool = true\ndate = 1979-05-27T07:32:00Z\n\"sorry\"\nint = 5000\nstring = \"Bite me\"",
   681  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = \"sorry\"\nstring = \"Bite me\"",
   682  	"bool = true\ndate = 1979-05-27T07:32:00Z\nfloat = 123.4\nint = 5000\nstring = 1",
   683  }
   684  
   685  type mapErr struct {
   686  	Vals map[string]float64
   687  }
   688  
   689  type intErr struct {
   690  	Int1  int
   691  	Int2  int8
   692  	Int3  int16
   693  	Int4  int32
   694  	Int5  int64
   695  	UInt1 uint
   696  	UInt2 uint8
   697  	UInt3 uint16
   698  	UInt4 uint32
   699  	UInt5 uint64
   700  	Flt1  float32
   701  	Flt2  float64
   702  }
   703  
   704  var intErrTomls = []string{
   705  	"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",
   706  	"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",
   707  	"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",
   708  	"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",
   709  	"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",
   710  	"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",
   711  	"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",
   712  	"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",
   713  	"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",
   714  	"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",
   715  	"Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = []\nFlt2 = 2.0",
   716  	"Int1 = 1\nInt2 = 2\nInt3 = 3\nInt4 = 4\nInt5 = 5\nUInt1 = 1\nUInt2 = 2\nUInt3 = 3\nUInt4 = 4\nUInt5 = 5\nFlt1 = 1.0\nFlt2 = []",
   717  }
   718  
   719  func TestErrUnmarshal(t *testing.T) {
   720  	for ind, toml := range errTomls {
   721  		result := errStruct{}
   722  		err := Unmarshal([]byte(toml), &result)
   723  		if err == nil {
   724  			t.Errorf("Expected err from case %d\n", ind)
   725  		}
   726  	}
   727  	result2 := mapErr{}
   728  	err := Unmarshal([]byte("[Vals]\nfred=\"1.2\""), &result2)
   729  	if err == nil {
   730  		t.Errorf("Expected err from map")
   731  	}
   732  	for ind, toml := range intErrTomls {
   733  		result3 := intErr{}
   734  		err := Unmarshal([]byte(toml), &result3)
   735  		if err == nil {
   736  			t.Errorf("Expected int err from case %d\n", ind)
   737  		}
   738  	}
   739  }
   740  
   741  type emptyMarshalTestStruct struct {
   742  	Title      string                  `toml:"title"`
   743  	Bool       bool                    `toml:"bool"`
   744  	Int        int                     `toml:"int"`
   745  	String     string                  `toml:"string"`
   746  	StringList []string                `toml:"stringlist"`
   747  	Ptr        *basicMarshalTestStruct `toml:"ptr"`
   748  	Map        map[string]string       `toml:"map"`
   749  }
   750  
   751  var emptyTestData = emptyMarshalTestStruct{
   752  	Title:      "Placeholder",
   753  	Bool:       false,
   754  	Int:        0,
   755  	String:     "",
   756  	StringList: []string{},
   757  	Ptr:        nil,
   758  	Map:        map[string]string{},
   759  }
   760  
   761  var emptyTestToml = []byte(`bool = false
   762  int = 0
   763  string = ""
   764  stringlist = []
   765  title = "Placeholder"
   766  
   767  [map]
   768  `)
   769  
   770  type emptyMarshalTestStruct2 struct {
   771  	Title      string                  `toml:"title"`
   772  	Bool       bool                    `toml:"bool,omitempty"`
   773  	Int        int                     `toml:"int, omitempty"`
   774  	String     string                  `toml:"string,omitempty "`
   775  	StringList []string                `toml:"stringlist,omitempty"`
   776  	Ptr        *basicMarshalTestStruct `toml:"ptr,omitempty"`
   777  	Map        map[string]string       `toml:"map,omitempty"`
   778  }
   779  
   780  var emptyTestData2 = emptyMarshalTestStruct2{
   781  	Title:      "Placeholder",
   782  	Bool:       false,
   783  	Int:        0,
   784  	String:     "",
   785  	StringList: []string{},
   786  	Ptr:        nil,
   787  	Map:        map[string]string{},
   788  }
   789  
   790  var emptyTestToml2 = []byte(`title = "Placeholder"
   791  `)
   792  
   793  func TestEmptyMarshal(t *testing.T) {
   794  	result, err := Marshal(emptyTestData)
   795  	if err != nil {
   796  		t.Fatal(err)
   797  	}
   798  	expected := emptyTestToml
   799  	if !bytes.Equal(result, expected) {
   800  		t.Errorf("Bad empty marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   801  	}
   802  }
   803  
   804  func TestEmptyMarshalOmit(t *testing.T) {
   805  	result, err := Marshal(emptyTestData2)
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  	expected := emptyTestToml2
   810  	if !bytes.Equal(result, expected) {
   811  		t.Errorf("Bad empty omit marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   812  	}
   813  }
   814  
   815  func TestEmptyUnmarshal(t *testing.T) {
   816  	result := emptyMarshalTestStruct{}
   817  	err := Unmarshal(emptyTestToml, &result)
   818  	expected := emptyTestData
   819  	if err != nil {
   820  		t.Fatal(err)
   821  	}
   822  	if !reflect.DeepEqual(result, expected) {
   823  		t.Errorf("Bad empty unmarshal: expected %v, got %v", expected, result)
   824  	}
   825  }
   826  
   827  func TestEmptyUnmarshalOmit(t *testing.T) {
   828  	result := emptyMarshalTestStruct2{}
   829  	err := Unmarshal(emptyTestToml, &result)
   830  	expected := emptyTestData2
   831  	if err != nil {
   832  		t.Fatal(err)
   833  	}
   834  	if !reflect.DeepEqual(result, expected) {
   835  		t.Errorf("Bad empty omit unmarshal: expected %v, got %v", expected, result)
   836  	}
   837  }
   838  
   839  type pointerMarshalTestStruct struct {
   840  	Str       *string
   841  	List      *[]string
   842  	ListPtr   *[]*string
   843  	Map       *map[string]string
   844  	MapPtr    *map[string]*string
   845  	EmptyStr  *string
   846  	EmptyList *[]string
   847  	EmptyMap  *map[string]string
   848  	DblPtr    *[]*[]*string
   849  }
   850  
   851  var pointerStr = "Hello"
   852  var pointerList = []string{"Hello back"}
   853  var pointerListPtr = []*string{&pointerStr}
   854  var pointerMap = map[string]string{"response": "Goodbye"}
   855  var pointerMapPtr = map[string]*string{"alternate": &pointerStr}
   856  var pointerTestData = pointerMarshalTestStruct{
   857  	Str:       &pointerStr,
   858  	List:      &pointerList,
   859  	ListPtr:   &pointerListPtr,
   860  	Map:       &pointerMap,
   861  	MapPtr:    &pointerMapPtr,
   862  	EmptyStr:  nil,
   863  	EmptyList: nil,
   864  	EmptyMap:  nil,
   865  }
   866  
   867  var pointerTestToml = []byte(`List = ["Hello back"]
   868  ListPtr = ["Hello"]
   869  Str = "Hello"
   870  
   871  [Map]
   872    response = "Goodbye"
   873  
   874  [MapPtr]
   875    alternate = "Hello"
   876  `)
   877  
   878  func TestPointerMarshal(t *testing.T) {
   879  	result, err := Marshal(pointerTestData)
   880  	if err != nil {
   881  		t.Fatal(err)
   882  	}
   883  	expected := pointerTestToml
   884  	if !bytes.Equal(result, expected) {
   885  		t.Errorf("Bad pointer marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   886  	}
   887  }
   888  
   889  func TestPointerUnmarshal(t *testing.T) {
   890  	result := pointerMarshalTestStruct{}
   891  	err := Unmarshal(pointerTestToml, &result)
   892  	expected := pointerTestData
   893  	if err != nil {
   894  		t.Fatal(err)
   895  	}
   896  	if !reflect.DeepEqual(result, expected) {
   897  		t.Errorf("Bad pointer unmarshal: expected %v, got %v", expected, result)
   898  	}
   899  }
   900  
   901  func TestUnmarshalTypeMismatch(t *testing.T) {
   902  	result := pointerMarshalTestStruct{}
   903  	err := Unmarshal([]byte("List = 123"), &result)
   904  	if !strings.HasPrefix(err.Error(), "(1, 1): Can't convert 123(int64) to []string(slice)") {
   905  		t.Errorf("Type mismatch must be reported: got %v", err.Error())
   906  	}
   907  }
   908  
   909  type nestedMarshalTestStruct struct {
   910  	String [][]string
   911  	//Struct [][]basicMarshalTestSubStruct
   912  	StringPtr *[]*[]*string
   913  	// StructPtr *[]*[]*basicMarshalTestSubStruct
   914  }
   915  
   916  var str1 = "Three"
   917  var str2 = "Four"
   918  var strPtr = []*string{&str1, &str2}
   919  var strPtr2 = []*[]*string{&strPtr}
   920  
   921  var nestedTestData = nestedMarshalTestStruct{
   922  	String:    [][]string{{"Five", "Six"}, {"One", "Two"}},
   923  	StringPtr: &strPtr2,
   924  }
   925  
   926  var nestedTestToml = []byte(`String = [["Five", "Six"], ["One", "Two"]]
   927  StringPtr = [["Three", "Four"]]
   928  `)
   929  
   930  func TestNestedMarshal(t *testing.T) {
   931  	result, err := Marshal(nestedTestData)
   932  	if err != nil {
   933  		t.Fatal(err)
   934  	}
   935  	expected := nestedTestToml
   936  	if !bytes.Equal(result, expected) {
   937  		t.Errorf("Bad nested marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   938  	}
   939  }
   940  
   941  func TestNestedUnmarshal(t *testing.T) {
   942  	result := nestedMarshalTestStruct{}
   943  	err := Unmarshal(nestedTestToml, &result)
   944  	expected := nestedTestData
   945  	if err != nil {
   946  		t.Fatal(err)
   947  	}
   948  	if !reflect.DeepEqual(result, expected) {
   949  		t.Errorf("Bad nested unmarshal: expected %v, got %v", expected, result)
   950  	}
   951  }
   952  
   953  type customMarshalerParent struct {
   954  	Self    customMarshaler   `toml:"me"`
   955  	Friends []customMarshaler `toml:"friends"`
   956  }
   957  
   958  type customMarshaler struct {
   959  	FirstName string
   960  	LastName  string
   961  }
   962  
   963  func (c customMarshaler) MarshalTOML() ([]byte, error) {
   964  	fullName := fmt.Sprintf("%s %s", c.FirstName, c.LastName)
   965  	return []byte(fullName), nil
   966  }
   967  
   968  var customMarshalerData = customMarshaler{FirstName: "Sally", LastName: "Fields"}
   969  var customMarshalerToml = []byte(`Sally Fields`)
   970  var nestedCustomMarshalerData = customMarshalerParent{
   971  	Self:    customMarshaler{FirstName: "Maiku", LastName: "Suteda"},
   972  	Friends: []customMarshaler{customMarshalerData},
   973  }
   974  var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"]
   975  me = "Maiku Suteda"
   976  `)
   977  var nestedCustomMarshalerTomlForUnmarshal = []byte(`[friends]
   978  FirstName = "Sally"
   979  LastName = "Fields"`)
   980  
   981  func TestCustomMarshaler(t *testing.T) {
   982  	result, err := Marshal(customMarshalerData)
   983  	if err != nil {
   984  		t.Fatal(err)
   985  	}
   986  	expected := customMarshalerToml
   987  	if !bytes.Equal(result, expected) {
   988  		t.Errorf("Bad custom marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
   989  	}
   990  }
   991  
   992  type IntOrString string
   993  
   994  func (x *IntOrString) MarshalTOML() ([]byte, error) {
   995  	s := *(*string)(x)
   996  	_, err := strconv.Atoi(s)
   997  	if err != nil {
   998  		return []byte(fmt.Sprintf(`"%s"`, s)), nil
   999  	}
  1000  	return []byte(s), nil
  1001  }
  1002  
  1003  func TestNestedCustomMarshaler(t *testing.T) {
  1004  	num := IntOrString("100")
  1005  	str := IntOrString("hello")
  1006  	var parent = struct {
  1007  		IntField    *IntOrString `toml:"int"`
  1008  		StringField *IntOrString `toml:"string"`
  1009  	}{
  1010  		&num,
  1011  		&str,
  1012  	}
  1013  
  1014  	result, err := Marshal(parent)
  1015  	if err != nil {
  1016  		t.Fatal(err)
  1017  	}
  1018  	expected := `int = 100
  1019  string = "hello"
  1020  `
  1021  	if !bytes.Equal(result, []byte(expected)) {
  1022  		t.Errorf("Bad nested text marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1023  	}
  1024  }
  1025  
  1026  type textMarshaler struct {
  1027  	FirstName string
  1028  	LastName  string
  1029  }
  1030  
  1031  func (m textMarshaler) MarshalText() ([]byte, error) {
  1032  	fullName := fmt.Sprintf("%s %s", m.FirstName, m.LastName)
  1033  	return []byte(fullName), nil
  1034  }
  1035  
  1036  func TestTextMarshaler(t *testing.T) {
  1037  	m := textMarshaler{FirstName: "Sally", LastName: "Fields"}
  1038  
  1039  	result, err := Marshal(m)
  1040  	if err != nil {
  1041  		t.Fatal(err)
  1042  	}
  1043  	expected := `Sally Fields`
  1044  	if !bytes.Equal(result, []byte(expected)) {
  1045  		t.Errorf("Bad text marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1046  	}
  1047  }
  1048  
  1049  func TestUnmarshalTextMarshaler(t *testing.T) {
  1050  	var nested = struct {
  1051  		Friends textMarshaler `toml:"friends"`
  1052  	}{}
  1053  
  1054  	var expected = struct {
  1055  		Friends textMarshaler `toml:"friends"`
  1056  	}{
  1057  		Friends: textMarshaler{FirstName: "Sally", LastName: "Fields"},
  1058  	}
  1059  
  1060  	err := Unmarshal(nestedCustomMarshalerTomlForUnmarshal, &nested)
  1061  	if err != nil {
  1062  		t.Fatal(err)
  1063  	}
  1064  	if !reflect.DeepEqual(nested, expected) {
  1065  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, nested)
  1066  	}
  1067  }
  1068  
  1069  func TestNestedTextMarshaler(t *testing.T) {
  1070  	var parent = struct {
  1071  		Self     textMarshaler   `toml:"me"`
  1072  		Friends  []textMarshaler `toml:"friends"`
  1073  		Stranger *textMarshaler  `toml:"stranger"`
  1074  	}{
  1075  		Self:     textMarshaler{FirstName: "Maiku", LastName: "Suteda"},
  1076  		Friends:  []textMarshaler{textMarshaler{FirstName: "Sally", LastName: "Fields"}},
  1077  		Stranger: &textMarshaler{FirstName: "Earl", LastName: "Henson"},
  1078  	}
  1079  
  1080  	result, err := Marshal(parent)
  1081  	if err != nil {
  1082  		t.Fatal(err)
  1083  	}
  1084  	expected := `friends = ["Sally Fields"]
  1085  me = "Maiku Suteda"
  1086  stranger = "Earl Henson"
  1087  `
  1088  	if !bytes.Equal(result, []byte(expected)) {
  1089  		t.Errorf("Bad nested text marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1090  	}
  1091  }
  1092  
  1093  type precedentMarshaler struct {
  1094  	FirstName string
  1095  	LastName  string
  1096  }
  1097  
  1098  func (m precedentMarshaler) MarshalText() ([]byte, error) {
  1099  	return []byte("shadowed"), nil
  1100  }
  1101  
  1102  func (m precedentMarshaler) MarshalTOML() ([]byte, error) {
  1103  	fullName := fmt.Sprintf("%s %s", m.FirstName, m.LastName)
  1104  	return []byte(fullName), nil
  1105  }
  1106  
  1107  func TestPrecedentMarshaler(t *testing.T) {
  1108  	m := textMarshaler{FirstName: "Sally", LastName: "Fields"}
  1109  
  1110  	result, err := Marshal(m)
  1111  	if err != nil {
  1112  		t.Fatal(err)
  1113  	}
  1114  	expected := `Sally Fields`
  1115  	if !bytes.Equal(result, []byte(expected)) {
  1116  		t.Errorf("Bad text marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1117  	}
  1118  }
  1119  
  1120  type customPointerMarshaler struct {
  1121  	FirstName string
  1122  	LastName  string
  1123  }
  1124  
  1125  func (m *customPointerMarshaler) MarshalTOML() ([]byte, error) {
  1126  	return []byte(`"hidden"`), nil
  1127  }
  1128  
  1129  type textPointerMarshaler struct {
  1130  	FirstName string
  1131  	LastName  string
  1132  }
  1133  
  1134  func (m *textPointerMarshaler) MarshalText() ([]byte, error) {
  1135  	return []byte("hidden"), nil
  1136  }
  1137  
  1138  func TestPointerMarshaler(t *testing.T) {
  1139  	var parent = struct {
  1140  		Self     customPointerMarshaler  `toml:"me"`
  1141  		Stranger *customPointerMarshaler `toml:"stranger"`
  1142  		Friend   textPointerMarshaler    `toml:"friend"`
  1143  		Fiend    *textPointerMarshaler   `toml:"fiend"`
  1144  	}{
  1145  		Self:     customPointerMarshaler{FirstName: "Maiku", LastName: "Suteda"},
  1146  		Stranger: &customPointerMarshaler{FirstName: "Earl", LastName: "Henson"},
  1147  		Friend:   textPointerMarshaler{FirstName: "Sally", LastName: "Fields"},
  1148  		Fiend:    &textPointerMarshaler{FirstName: "Casper", LastName: "Snider"},
  1149  	}
  1150  
  1151  	result, err := Marshal(parent)
  1152  	if err != nil {
  1153  		t.Fatal(err)
  1154  	}
  1155  	expected := `fiend = "hidden"
  1156  stranger = "hidden"
  1157  
  1158  [friend]
  1159    FirstName = "Sally"
  1160    LastName = "Fields"
  1161  
  1162  [me]
  1163    FirstName = "Maiku"
  1164    LastName = "Suteda"
  1165  `
  1166  	if !bytes.Equal(result, []byte(expected)) {
  1167  		t.Errorf("Bad nested text marshaler: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1168  	}
  1169  }
  1170  
  1171  func TestPointerCustomMarshalerSequence(t *testing.T) {
  1172  	var customPointerMarshalerSlice *[]*customPointerMarshaler
  1173  	var customPointerMarshalerArray *[2]*customPointerMarshaler
  1174  
  1175  	if !isCustomMarshalerSequence(reflect.TypeOf(customPointerMarshalerSlice)) {
  1176  		t.Errorf("error: should be a sequence of custom marshaler interfaces")
  1177  	}
  1178  	if !isCustomMarshalerSequence(reflect.TypeOf(customPointerMarshalerArray)) {
  1179  		t.Errorf("error: should be a sequence of custom marshaler interfaces")
  1180  	}
  1181  }
  1182  
  1183  func TestPointerTextMarshalerSequence(t *testing.T) {
  1184  	var textPointerMarshalerSlice *[]*textPointerMarshaler
  1185  	var textPointerMarshalerArray *[2]*textPointerMarshaler
  1186  
  1187  	if !isTextMarshalerSequence(reflect.TypeOf(textPointerMarshalerSlice)) {
  1188  		t.Errorf("error: should be a sequence of text marshaler interfaces")
  1189  	}
  1190  	if !isTextMarshalerSequence(reflect.TypeOf(textPointerMarshalerArray)) {
  1191  		t.Errorf("error: should be a sequence of text marshaler interfaces")
  1192  	}
  1193  }
  1194  
  1195  var commentTestToml = []byte(`
  1196  # it's a comment on type
  1197  [postgres]
  1198    # isCommented = "dvalue"
  1199    noComment = "cvalue"
  1200  
  1201    # A comment on AttrB with a
  1202    # break line
  1203    password = "bvalue"
  1204  
  1205    # A comment on AttrA
  1206    user = "avalue"
  1207  
  1208    [[postgres.My]]
  1209  
  1210      # a comment on my on typeC
  1211      My = "Foo"
  1212  
  1213    [[postgres.My]]
  1214  
  1215      # a comment on my on typeC
  1216      My = "Baar"
  1217  `)
  1218  
  1219  func TestMarshalComment(t *testing.T) {
  1220  	type TypeC struct {
  1221  		My string `comment:"a comment on my on typeC"`
  1222  	}
  1223  	type TypeB struct {
  1224  		AttrA string `toml:"user" comment:"A comment on AttrA"`
  1225  		AttrB string `toml:"password" comment:"A comment on AttrB with a\n break line"`
  1226  		AttrC string `toml:"noComment"`
  1227  		AttrD string `toml:"isCommented" commented:"true"`
  1228  		My    []TypeC
  1229  	}
  1230  	type TypeA struct {
  1231  		TypeB TypeB `toml:"postgres" comment:"it's a comment on type"`
  1232  	}
  1233  
  1234  	ta := []TypeC{{My: "Foo"}, {My: "Baar"}}
  1235  	config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", AttrC: "cvalue", AttrD: "dvalue", My: ta}}
  1236  	result, err := Marshal(config)
  1237  	if err != nil {
  1238  		t.Fatal(err)
  1239  	}
  1240  	expected := commentTestToml
  1241  	if !bytes.Equal(result, expected) {
  1242  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1243  	}
  1244  }
  1245  
  1246  func TestMarshalMultilineCommented(t *testing.T) {
  1247  	expectedToml := []byte(`# MultilineArray = [
  1248    # 100,
  1249    # 200,
  1250    # 300,
  1251  # ]
  1252  # MultilineNestedArray = [
  1253    # [
  1254    # "a",
  1255    # "b",
  1256    # "c",
  1257  # ],
  1258    # [
  1259    # "d",
  1260    # "e",
  1261    # "f",
  1262  # ],
  1263  # ]
  1264  # MultilineString = """
  1265  # I
  1266  # am
  1267  # Allen"""
  1268  NonCommented = "Not commented line"
  1269  `)
  1270  	type StructWithMultiline struct {
  1271  		NonCommented         string
  1272  		MultilineString      string     `commented:"true" multiline:"true"`
  1273  		MultilineArray       []int      `commented:"true"`
  1274  		MultilineNestedArray [][]string `commented:"true"`
  1275  	}
  1276  
  1277  	var buf bytes.Buffer
  1278  	enc := NewEncoder(&buf)
  1279  	if err := enc.ArraysWithOneElementPerLine(true).Encode(StructWithMultiline{
  1280  		NonCommented:    "Not commented line",
  1281  		MultilineString: "I\nam\nAllen",
  1282  		MultilineArray:  []int{100, 200, 300},
  1283  		MultilineNestedArray: [][]string{
  1284  			{"a", "b", "c"},
  1285  			{"d", "e", "f"},
  1286  		},
  1287  	}); err == nil {
  1288  		result := buf.Bytes()
  1289  		if !bytes.Equal(result, expectedToml) {
  1290  			t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedToml, result)
  1291  		}
  1292  	} else {
  1293  		t.Fatal(err)
  1294  	}
  1295  }
  1296  
  1297  func TestMarshalMultilineLiteral(t *testing.T) {
  1298  	type Doc struct {
  1299  		Value string `multiline:"true" literal:"true"`
  1300  	}
  1301  
  1302  	d := Doc{
  1303  		Value: "hello\nworld\ttest\nend",
  1304  	}
  1305  
  1306  	expected := []byte(`Value = '''
  1307  hello
  1308  world	test
  1309  end
  1310  '''
  1311  `)
  1312  
  1313  	b, err := Marshal(d)
  1314  	if err != nil {
  1315  		t.Fatal("unexpected error")
  1316  	}
  1317  
  1318  	if !bytes.Equal(b, expected) {
  1319  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, b)
  1320  	}
  1321  }
  1322  
  1323  func TestMarshalNonPrimitiveTypeCommented(t *testing.T) {
  1324  	expectedToml := []byte(`
  1325  # [CommentedMapField]
  1326  
  1327    # [CommentedMapField.CommentedMapField1]
  1328      # SingleLineString = "This line should be commented out"
  1329  
  1330    # [CommentedMapField.CommentedMapField2]
  1331      # SingleLineString = "This line should be commented out"
  1332  
  1333  # [CommentedStructField]
  1334  
  1335    # [CommentedStructField.CommentedStructField]
  1336      # MultilineArray = [
  1337        # 1,
  1338        # 2,
  1339      # ]
  1340      # MultilineNestedArray = [
  1341        # [
  1342        # 10,
  1343        # 20,
  1344      # ],
  1345        # [
  1346        # 100,
  1347        # 200,
  1348      # ],
  1349      # ]
  1350      # MultilineString = """
  1351  # This line
  1352  # should be
  1353  # commented out"""
  1354  
  1355    # [CommentedStructField.NotCommentedStructField]
  1356      # MultilineArray = [
  1357        # 1,
  1358        # 2,
  1359      # ]
  1360      # MultilineNestedArray = [
  1361        # [
  1362        # 10,
  1363        # 20,
  1364      # ],
  1365        # [
  1366        # 100,
  1367        # 200,
  1368      # ],
  1369      # ]
  1370      # MultilineString = """
  1371  # This line
  1372  # should be
  1373  # commented out"""
  1374  
  1375  [NotCommentedStructField]
  1376  
  1377    # [NotCommentedStructField.CommentedStructField]
  1378      # MultilineArray = [
  1379        # 1,
  1380        # 2,
  1381      # ]
  1382      # MultilineNestedArray = [
  1383        # [
  1384        # 10,
  1385        # 20,
  1386      # ],
  1387        # [
  1388        # 100,
  1389        # 200,
  1390      # ],
  1391      # ]
  1392      # MultilineString = """
  1393  # This line
  1394  # should be
  1395  # commented out"""
  1396  
  1397    [NotCommentedStructField.NotCommentedStructField]
  1398      MultilineArray = [
  1399        3,
  1400        4,
  1401      ]
  1402      MultilineNestedArray = [
  1403        [
  1404        30,
  1405        40,
  1406      ],
  1407        [
  1408        300,
  1409        400,
  1410      ],
  1411      ]
  1412      MultilineString = """
  1413  This line
  1414  should NOT be
  1415  commented out"""
  1416  `)
  1417  	type InnerStruct struct {
  1418  		MultilineString      string `multiline:"true"`
  1419  		MultilineArray       []int
  1420  		MultilineNestedArray [][]int
  1421  	}
  1422  	type MiddleStruct struct {
  1423  		NotCommentedStructField InnerStruct
  1424  		CommentedStructField    InnerStruct `commented:"true"`
  1425  	}
  1426  	type OuterStruct struct {
  1427  		CommentedStructField    MiddleStruct `commented:"true"`
  1428  		NotCommentedStructField MiddleStruct
  1429  		CommentedMapField       map[string]struct{ SingleLineString string } `commented:"true"`
  1430  	}
  1431  
  1432  	commentedTestStruct := OuterStruct{
  1433  		CommentedStructField: MiddleStruct{
  1434  			NotCommentedStructField: InnerStruct{
  1435  				MultilineString:      "This line\nshould be\ncommented out",
  1436  				MultilineArray:       []int{1, 2},
  1437  				MultilineNestedArray: [][]int{{10, 20}, {100, 200}},
  1438  			},
  1439  			CommentedStructField: InnerStruct{
  1440  				MultilineString:      "This line\nshould be\ncommented out",
  1441  				MultilineArray:       []int{1, 2},
  1442  				MultilineNestedArray: [][]int{{10, 20}, {100, 200}},
  1443  			},
  1444  		},
  1445  		NotCommentedStructField: MiddleStruct{
  1446  			NotCommentedStructField: InnerStruct{
  1447  				MultilineString:      "This line\nshould NOT be\ncommented out",
  1448  				MultilineArray:       []int{3, 4},
  1449  				MultilineNestedArray: [][]int{{30, 40}, {300, 400}},
  1450  			},
  1451  			CommentedStructField: InnerStruct{
  1452  				MultilineString:      "This line\nshould be\ncommented out",
  1453  				MultilineArray:       []int{1, 2},
  1454  				MultilineNestedArray: [][]int{{10, 20}, {100, 200}},
  1455  			},
  1456  		},
  1457  		CommentedMapField: map[string]struct{ SingleLineString string }{
  1458  			"CommentedMapField1": {
  1459  				SingleLineString: "This line should be commented out",
  1460  			},
  1461  			"CommentedMapField2": {
  1462  				SingleLineString: "This line should be commented out",
  1463  			},
  1464  		},
  1465  	}
  1466  
  1467  	var buf bytes.Buffer
  1468  	enc := NewEncoder(&buf)
  1469  	if err := enc.ArraysWithOneElementPerLine(true).Encode(commentedTestStruct); err == nil {
  1470  		result := buf.Bytes()
  1471  		if !bytes.Equal(result, expectedToml) {
  1472  			t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedToml, result)
  1473  		}
  1474  	} else {
  1475  		t.Fatal(err)
  1476  	}
  1477  }
  1478  
  1479  func TestCompactComments(t *testing.T) {
  1480  	expected := []byte(`
  1481  [first-section]
  1482    # comment for first-key
  1483    first-key = 1
  1484    # comment for second-key
  1485    second-key = "value"
  1486    # comment for commented third-key
  1487    # third-key = []
  1488  
  1489  [second-section]
  1490    # comment for first-key
  1491    first-key = 2
  1492    # comment for second-key
  1493    second-key = "another value"
  1494    # comment for commented third-key
  1495    # third-key = ["value1", "value2"]
  1496  `)
  1497  	type Settings struct {
  1498  		FirstKey  int      `toml:"first-key" comment:"comment for first-key"`
  1499  		SecondKey string   `toml:"second-key" comment:"comment for second-key"`
  1500  		ThirdKey  []string `toml:"third-key" comment:"comment for commented third-key" commented:"true"`
  1501  	}
  1502  	type Config struct {
  1503  		FirstSection  Settings `toml:"first-section"`
  1504  		SecondSection Settings `toml:"second-section"`
  1505  	}
  1506  	data := Config{
  1507  		FirstSection:  Settings{1, "value", []string{}},
  1508  		SecondSection: Settings{2, "another value", []string{"value1", "value2"}},
  1509  	}
  1510  	buf := new(bytes.Buffer)
  1511  	if err := NewEncoder(buf).CompactComments(true).Encode(data); err != nil {
  1512  		t.Fatal(err)
  1513  	}
  1514  
  1515  	if !bytes.Equal(expected, buf.Bytes()) {
  1516  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, buf.Bytes())
  1517  	}
  1518  }
  1519  
  1520  type mapsTestStruct struct {
  1521  	Simple map[string]string
  1522  	Paths  map[string]string
  1523  	Other  map[string]float64
  1524  	X      struct {
  1525  		Y struct {
  1526  			Z map[string]bool
  1527  		}
  1528  	}
  1529  }
  1530  
  1531  var mapsTestData = mapsTestStruct{
  1532  	Simple: map[string]string{
  1533  		"one plus one": "two",
  1534  		"next":         "three",
  1535  	},
  1536  	Paths: map[string]string{
  1537  		"/this/is/a/path": "/this/is/also/a/path",
  1538  		"/heloo.txt":      "/tmp/lololo.txt",
  1539  	},
  1540  	Other: map[string]float64{
  1541  		"testing": 3.9999,
  1542  	},
  1543  	X: struct{ Y struct{ Z map[string]bool } }{
  1544  		Y: struct{ Z map[string]bool }{
  1545  			Z: map[string]bool{
  1546  				"is.Nested": true,
  1547  			},
  1548  		},
  1549  	},
  1550  }
  1551  var mapsTestToml = []byte(`
  1552  [Other]
  1553    "testing" = 3.9999
  1554  
  1555  [Paths]
  1556    "/heloo.txt" = "/tmp/lololo.txt"
  1557    "/this/is/a/path" = "/this/is/also/a/path"
  1558  
  1559  [Simple]
  1560    "next" = "three"
  1561    "one plus one" = "two"
  1562  
  1563  [X]
  1564  
  1565    [X.Y]
  1566  
  1567      [X.Y.Z]
  1568        "is.Nested" = true
  1569  `)
  1570  
  1571  func TestEncodeQuotedMapKeys(t *testing.T) {
  1572  	var buf bytes.Buffer
  1573  	if err := NewEncoder(&buf).QuoteMapKeys(true).Encode(mapsTestData); err != nil {
  1574  		t.Fatal(err)
  1575  	}
  1576  	result := buf.Bytes()
  1577  	expected := mapsTestToml
  1578  	if !bytes.Equal(result, expected) {
  1579  		t.Errorf("Bad maps marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1580  	}
  1581  }
  1582  
  1583  func TestDecodeQuotedMapKeys(t *testing.T) {
  1584  	result := mapsTestStruct{}
  1585  	err := NewDecoder(bytes.NewBuffer(mapsTestToml)).Decode(&result)
  1586  	expected := mapsTestData
  1587  	if err != nil {
  1588  		t.Fatal(err)
  1589  	}
  1590  	if !reflect.DeepEqual(result, expected) {
  1591  		t.Errorf("Bad maps unmarshal: expected %v, got %v", expected, result)
  1592  	}
  1593  }
  1594  
  1595  type structArrayNoTag struct {
  1596  	A struct {
  1597  		B []int64
  1598  		C []int64
  1599  	}
  1600  }
  1601  
  1602  func TestMarshalArray(t *testing.T) {
  1603  	expected := []byte(`
  1604  [A]
  1605    B = [1, 2, 3]
  1606    C = [1]
  1607  `)
  1608  
  1609  	m := structArrayNoTag{
  1610  		A: struct {
  1611  			B []int64
  1612  			C []int64
  1613  		}{
  1614  			B: []int64{1, 2, 3},
  1615  			C: []int64{1},
  1616  		},
  1617  	}
  1618  
  1619  	b, err := Marshal(m)
  1620  
  1621  	if err != nil {
  1622  		t.Fatal(err)
  1623  	}
  1624  
  1625  	if !bytes.Equal(b, expected) {
  1626  		t.Errorf("Bad arrays marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, b)
  1627  	}
  1628  }
  1629  
  1630  func TestMarshalArrayOnePerLine(t *testing.T) {
  1631  	expected := []byte(`
  1632  [A]
  1633    B = [
  1634      1,
  1635      2,
  1636      3,
  1637    ]
  1638    C = [1]
  1639  `)
  1640  
  1641  	m := structArrayNoTag{
  1642  		A: struct {
  1643  			B []int64
  1644  			C []int64
  1645  		}{
  1646  			B: []int64{1, 2, 3},
  1647  			C: []int64{1},
  1648  		},
  1649  	}
  1650  
  1651  	var buf bytes.Buffer
  1652  	encoder := NewEncoder(&buf).ArraysWithOneElementPerLine(true)
  1653  	err := encoder.Encode(m)
  1654  
  1655  	if err != nil {
  1656  		t.Fatal(err)
  1657  	}
  1658  
  1659  	b := buf.Bytes()
  1660  
  1661  	if !bytes.Equal(b, expected) {
  1662  		t.Errorf("Bad arrays marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, b)
  1663  	}
  1664  }
  1665  
  1666  var customTagTestToml = []byte(`
  1667  [postgres]
  1668    password = "bvalue"
  1669    user = "avalue"
  1670  
  1671    [[postgres.My]]
  1672      My = "Foo"
  1673  
  1674    [[postgres.My]]
  1675      My = "Baar"
  1676  `)
  1677  
  1678  func TestMarshalCustomTag(t *testing.T) {
  1679  	type TypeC struct {
  1680  		My string
  1681  	}
  1682  	type TypeB struct {
  1683  		AttrA string `file:"user"`
  1684  		AttrB string `file:"password"`
  1685  		My    []TypeC
  1686  	}
  1687  	type TypeA struct {
  1688  		TypeB TypeB `file:"postgres"`
  1689  	}
  1690  
  1691  	ta := []TypeC{{My: "Foo"}, {My: "Baar"}}
  1692  	config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue", My: ta}}
  1693  	var buf bytes.Buffer
  1694  	err := NewEncoder(&buf).SetTagName("file").Encode(config)
  1695  	if err != nil {
  1696  		t.Fatal(err)
  1697  	}
  1698  	expected := customTagTestToml
  1699  	result := buf.Bytes()
  1700  	if !bytes.Equal(result, expected) {
  1701  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1702  	}
  1703  }
  1704  
  1705  var customCommentTagTestToml = []byte(`
  1706  # db connection
  1707  [postgres]
  1708  
  1709    # db pass
  1710    password = "bvalue"
  1711  
  1712    # db user
  1713    user = "avalue"
  1714  `)
  1715  
  1716  func TestMarshalCustomComment(t *testing.T) {
  1717  	type TypeB struct {
  1718  		AttrA string `toml:"user" descr:"db user"`
  1719  		AttrB string `toml:"password" descr:"db pass"`
  1720  	}
  1721  	type TypeA struct {
  1722  		TypeB TypeB `toml:"postgres" descr:"db connection"`
  1723  	}
  1724  
  1725  	config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue"}}
  1726  	var buf bytes.Buffer
  1727  	err := NewEncoder(&buf).SetTagComment("descr").Encode(config)
  1728  	if err != nil {
  1729  		t.Fatal(err)
  1730  	}
  1731  	expected := customCommentTagTestToml
  1732  	result := buf.Bytes()
  1733  	if !bytes.Equal(result, expected) {
  1734  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1735  	}
  1736  }
  1737  
  1738  var customCommentedTagTestToml = []byte(`
  1739  [postgres]
  1740    # password = "bvalue"
  1741    # user = "avalue"
  1742  `)
  1743  
  1744  func TestMarshalCustomCommented(t *testing.T) {
  1745  	type TypeB struct {
  1746  		AttrA string `toml:"user" disable:"true"`
  1747  		AttrB string `toml:"password" disable:"true"`
  1748  	}
  1749  	type TypeA struct {
  1750  		TypeB TypeB `toml:"postgres"`
  1751  	}
  1752  
  1753  	config := TypeA{TypeB{AttrA: "avalue", AttrB: "bvalue"}}
  1754  	var buf bytes.Buffer
  1755  	err := NewEncoder(&buf).SetTagCommented("disable").Encode(config)
  1756  	if err != nil {
  1757  		t.Fatal(err)
  1758  	}
  1759  	expected := customCommentedTagTestToml
  1760  	result := buf.Bytes()
  1761  	if !bytes.Equal(result, expected) {
  1762  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1763  	}
  1764  }
  1765  
  1766  func TestMarshalDirectMultilineString(t *testing.T) {
  1767  	tree := newTree()
  1768  	tree.SetWithOptions("mykey", SetOptions{
  1769  		Multiline: true,
  1770  	}, "my\x11multiline\nstring\ba\tb\fc\rd\"e\\!")
  1771  	result, err := tree.Marshal()
  1772  	if err != nil {
  1773  		t.Fatal("marshal should not error:", err)
  1774  	}
  1775  	expected := []byte("mykey = \"\"\"\nmy\\u0011multiline\nstring\\ba\tb\\fc\rd\"e\\!\"\"\"\n")
  1776  	if !bytes.Equal(result, expected) {
  1777  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1778  	}
  1779  }
  1780  
  1781  func TestUnmarshalTabInStringAndQuotedKey(t *testing.T) {
  1782  	type Test struct {
  1783  		Field1 string `toml:"Fie	ld1"`
  1784  		Field2 string
  1785  	}
  1786  
  1787  	type TestCase struct {
  1788  		desc     string
  1789  		input    []byte
  1790  		expected Test
  1791  	}
  1792  
  1793  	testCases := []TestCase{
  1794  		{
  1795  			desc:  "multiline string with tab",
  1796  			input: []byte("Field2 = \"\"\"\nhello\tworld\"\"\""),
  1797  			expected: Test{
  1798  				Field2: "hello\tworld",
  1799  			},
  1800  		},
  1801  		{
  1802  			desc:  "quoted key with tab",
  1803  			input: []byte("\"Fie\tld1\" = \"key with tab\""),
  1804  			expected: Test{
  1805  				Field1: "key with tab",
  1806  			},
  1807  		},
  1808  		{
  1809  			desc:  "basic string tab",
  1810  			input: []byte("Field2 = \"hello\tworld\""),
  1811  			expected: Test{
  1812  				Field2: "hello\tworld",
  1813  			},
  1814  		},
  1815  	}
  1816  
  1817  	for i := range testCases {
  1818  		result := Test{}
  1819  		err := Unmarshal(testCases[i].input, &result)
  1820  		if err != nil {
  1821  			t.Errorf("%s test error:%v", testCases[i].desc, err)
  1822  			continue
  1823  		}
  1824  
  1825  		if !reflect.DeepEqual(result, testCases[i].expected) {
  1826  			t.Errorf("%s test error: expected\n-----\n%+v\n-----\ngot\n-----\n%+v\n-----\n",
  1827  				testCases[i].desc, testCases[i].expected, result)
  1828  		}
  1829  	}
  1830  }
  1831  
  1832  var customMultilineTagTestToml = []byte(`int_slice = [
  1833    1,
  1834    2,
  1835    3,
  1836  ]
  1837  `)
  1838  
  1839  func TestMarshalCustomMultiline(t *testing.T) {
  1840  	type TypeA struct {
  1841  		AttrA []int `toml:"int_slice" mltln:"true"`
  1842  	}
  1843  
  1844  	config := TypeA{AttrA: []int{1, 2, 3}}
  1845  	var buf bytes.Buffer
  1846  	err := NewEncoder(&buf).ArraysWithOneElementPerLine(true).SetTagMultiline("mltln").Encode(config)
  1847  	if err != nil {
  1848  		t.Fatal(err)
  1849  	}
  1850  	expected := customMultilineTagTestToml
  1851  	result := buf.Bytes()
  1852  	if !bytes.Equal(result, expected) {
  1853  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  1854  	}
  1855  }
  1856  
  1857  func TestMultilineWithAdjacentQuotationMarks(t *testing.T) {
  1858  	type testStruct struct {
  1859  		Str string `multiline:"true"`
  1860  	}
  1861  	type testCase struct {
  1862  		expected []byte
  1863  		data     testStruct
  1864  	}
  1865  
  1866  	testCases := []testCase{
  1867  		{
  1868  			expected: []byte(`Str = """
  1869  hello\""""
  1870  `),
  1871  			data: testStruct{
  1872  				Str: "hello\"",
  1873  			},
  1874  		},
  1875  		{
  1876  			expected: []byte(`Str = """
  1877  ""\"""\"""\""""
  1878  `),
  1879  			data: testStruct{
  1880  				Str: "\"\"\"\"\"\"\"\"\"",
  1881  			},
  1882  		},
  1883  	}
  1884  	for i := range testCases {
  1885  		result, err := Marshal(testCases[i].data)
  1886  		if err != nil {
  1887  			t.Fatal(err)
  1888  		}
  1889  
  1890  		if !bytes.Equal(result, testCases[i].expected) {
  1891  			t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n",
  1892  				testCases[i].expected, result)
  1893  		} else {
  1894  			var data testStruct
  1895  			if err = Unmarshal(result, &data); err != nil {
  1896  				t.Fatal(err)
  1897  			}
  1898  			if data.Str != testCases[i].data.Str {
  1899  				t.Errorf("Round trip test fail: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n",
  1900  					testCases[i].data.Str, data.Str)
  1901  			}
  1902  		}
  1903  	}
  1904  }
  1905  
  1906  func TestMarshalEmbedTree(t *testing.T) {
  1907  	expected := []byte(`OuterField1 = "Out"
  1908  OuterField2 = 1024
  1909  
  1910  [TreeField]
  1911    InnerField1 = "In"
  1912    InnerField2 = 2048
  1913  
  1914    [TreeField.EmbedStruct]
  1915      EmbedField = "Embed"
  1916  `)
  1917  	type InnerStruct struct {
  1918  		InnerField1 string
  1919  		InnerField2 int
  1920  		EmbedStruct struct {
  1921  			EmbedField string
  1922  		}
  1923  	}
  1924  
  1925  	type OuterStruct struct {
  1926  		OuterField1 string
  1927  		OuterField2 int
  1928  		TreeField   *Tree
  1929  	}
  1930  
  1931  	tree, err := Load(`
  1932  InnerField1 = "In"
  1933  InnerField2 = 2048
  1934  
  1935  [EmbedStruct]
  1936  	EmbedField = "Embed"
  1937  `)
  1938  	if err != nil {
  1939  		t.Fatal(err)
  1940  	}
  1941  
  1942  	out := OuterStruct{
  1943  		"Out",
  1944  		1024,
  1945  		tree,
  1946  	}
  1947  	actual, _ := Marshal(out)
  1948  
  1949  	if !bytes.Equal(actual, expected) {
  1950  		t.Errorf("Bad marshal: expected %s, got %s", expected, actual)
  1951  	}
  1952  }
  1953  
  1954  var testDocBasicToml = []byte(`
  1955  [document]
  1956    bool_val = true
  1957    date_val = 1979-05-27T07:32:00Z
  1958    float_val = 123.4
  1959    int_val = 5000
  1960    string_val = "Bite me"
  1961    uint_val = 5001
  1962  `)
  1963  
  1964  type testDocCustomTag struct {
  1965  	Doc testDocBasicsCustomTag `file:"document"`
  1966  }
  1967  type testDocBasicsCustomTag struct {
  1968  	Bool       bool      `file:"bool_val"`
  1969  	Date       time.Time `file:"date_val"`
  1970  	Float      float32   `file:"float_val"`
  1971  	Int        int       `file:"int_val"`
  1972  	Uint       uint      `file:"uint_val"`
  1973  	String     *string   `file:"string_val"`
  1974  	unexported int       `file:"shouldntBeHere"`
  1975  }
  1976  
  1977  var testDocCustomTagData = testDocCustomTag{
  1978  	Doc: testDocBasicsCustomTag{
  1979  		Bool:       true,
  1980  		Date:       time.Date(1979, 5, 27, 7, 32, 0, 0, time.UTC),
  1981  		Float:      123.4,
  1982  		Int:        5000,
  1983  		Uint:       5001,
  1984  		String:     &biteMe,
  1985  		unexported: 0,
  1986  	},
  1987  }
  1988  
  1989  func TestUnmarshalCustomTag(t *testing.T) {
  1990  	buf := bytes.NewBuffer(testDocBasicToml)
  1991  
  1992  	result := testDocCustomTag{}
  1993  	err := NewDecoder(buf).SetTagName("file").Decode(&result)
  1994  	if err != nil {
  1995  		t.Fatal(err)
  1996  	}
  1997  	expected := testDocCustomTagData
  1998  	if !reflect.DeepEqual(result, expected) {
  1999  		resStr, _ := json.MarshalIndent(result, "", "  ")
  2000  		expStr, _ := json.MarshalIndent(expected, "", "  ")
  2001  		t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
  2002  
  2003  	}
  2004  }
  2005  
  2006  func TestUnmarshalMap(t *testing.T) {
  2007  	testToml := []byte(`
  2008  		a = 1
  2009  		b = 2
  2010  		c = 3
  2011  		`)
  2012  	var result map[string]int
  2013  	err := Unmarshal(testToml, &result)
  2014  	if err != nil {
  2015  		t.Errorf("Received unexpected error: %s", err)
  2016  		return
  2017  	}
  2018  
  2019  	expected := map[string]int{
  2020  		"a": 1,
  2021  		"b": 2,
  2022  		"c": 3,
  2023  	}
  2024  
  2025  	if !reflect.DeepEqual(result, expected) {
  2026  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
  2027  	}
  2028  }
  2029  
  2030  func TestUnmarshalMapWithTypedKey(t *testing.T) {
  2031  	testToml := []byte(`
  2032  		a = 1
  2033  		b = 2
  2034  		c = 3
  2035  		`)
  2036  
  2037  	type letter string
  2038  	var result map[letter]int
  2039  	err := Unmarshal(testToml, &result)
  2040  	if err != nil {
  2041  		t.Errorf("Received unexpected error: %s", err)
  2042  		return
  2043  	}
  2044  
  2045  	expected := map[letter]int{
  2046  		"a": 1,
  2047  		"b": 2,
  2048  		"c": 3,
  2049  	}
  2050  
  2051  	if !reflect.DeepEqual(result, expected) {
  2052  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, result)
  2053  	}
  2054  }
  2055  
  2056  func TestUnmarshalNonPointer(t *testing.T) {
  2057  	a := 1
  2058  	err := Unmarshal([]byte{}, a)
  2059  	if err == nil {
  2060  		t.Fatal("unmarshal should err when given a non pointer")
  2061  	}
  2062  }
  2063  
  2064  func TestUnmarshalInvalidPointerKind(t *testing.T) {
  2065  	a := 1
  2066  	err := Unmarshal([]byte{}, &a)
  2067  	if err == nil {
  2068  		t.Fatal("unmarshal should err when given an invalid pointer type")
  2069  	}
  2070  }
  2071  
  2072  func TestMarshalSlice(t *testing.T) {
  2073  	m := make([]int, 1)
  2074  	m[0] = 1
  2075  
  2076  	var buf bytes.Buffer
  2077  	err := NewEncoder(&buf).Encode(&m)
  2078  	if err == nil {
  2079  		t.Error("expected error, got nil")
  2080  		return
  2081  	}
  2082  	if err.Error() != "Only pointer to struct can be marshaled to TOML" {
  2083  		t.Fail()
  2084  	}
  2085  }
  2086  
  2087  func TestMarshalSlicePointer(t *testing.T) {
  2088  	m := make([]int, 1)
  2089  	m[0] = 1
  2090  
  2091  	var buf bytes.Buffer
  2092  	err := NewEncoder(&buf).Encode(m)
  2093  	if err == nil {
  2094  		t.Error("expected error, got nil")
  2095  		return
  2096  	}
  2097  	if err.Error() != "Only a struct or map can be marshaled to TOML" {
  2098  		t.Fail()
  2099  	}
  2100  }
  2101  
  2102  func TestMarshalNestedArrayInlineTables(t *testing.T) {
  2103  	type table struct {
  2104  		Value1 int `toml:"ZValue1"`
  2105  		Value2 int `toml:"YValue2"`
  2106  		Value3 int `toml:"XValue3"`
  2107  	}
  2108  
  2109  	type nestedTable struct {
  2110  		Table table
  2111  	}
  2112  
  2113  	nestedArray := struct {
  2114  		Simple        [][]table
  2115  		SimplePointer *[]*[]table
  2116  		Nested        [][]nestedTable
  2117  		NestedPointer *[]*[]nestedTable
  2118  	}{
  2119  		Simple:        [][]table{{{Value1: 1}, {Value1: 10}}},
  2120  		SimplePointer: &[]*[]table{{{Value2: 2}}},
  2121  		Nested:        [][]nestedTable{{{Table: table{Value3: 3}}}},
  2122  		NestedPointer: &[]*[]nestedTable{{{Table: table{Value3: -3}}}},
  2123  	}
  2124  
  2125  	expectedPreserve := `Simple = [[{ ZValue1 = 1, YValue2 = 0, XValue3 = 0 }, { ZValue1 = 10, YValue2 = 0, XValue3 = 0 }]]
  2126  SimplePointer = [[{ ZValue1 = 0, YValue2 = 2, XValue3 = 0 }]]
  2127  Nested = [[{ Table = { ZValue1 = 0, YValue2 = 0, XValue3 = 3 } }]]
  2128  NestedPointer = [[{ Table = { ZValue1 = 0, YValue2 = 0, XValue3 = -3 } }]]
  2129  `
  2130  
  2131  	expectedAlphabetical := `Nested = [[{ Table = { XValue3 = 3, YValue2 = 0, ZValue1 = 0 } }]]
  2132  NestedPointer = [[{ Table = { XValue3 = -3, YValue2 = 0, ZValue1 = 0 } }]]
  2133  Simple = [[{ XValue3 = 0, YValue2 = 0, ZValue1 = 1 }, { XValue3 = 0, YValue2 = 0, ZValue1 = 10 }]]
  2134  SimplePointer = [[{ XValue3 = 0, YValue2 = 2, ZValue1 = 0 }]]
  2135  `
  2136  
  2137  	var bufPreserve bytes.Buffer
  2138  	if err := NewEncoder(&bufPreserve).Order(OrderPreserve).Encode(nestedArray); err != nil {
  2139  		t.Fatalf("unexpected error: %s", err.Error())
  2140  	}
  2141  	if !bytes.Equal(bufPreserve.Bytes(), []byte(expectedPreserve)) {
  2142  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedPreserve, bufPreserve.String())
  2143  	}
  2144  
  2145  	var bufAlphabetical bytes.Buffer
  2146  	if err := NewEncoder(&bufAlphabetical).Order(OrderAlphabetical).Encode(nestedArray); err != nil {
  2147  		t.Fatalf("unexpected error: %s", err.Error())
  2148  	}
  2149  	if !bytes.Equal(bufAlphabetical.Bytes(), []byte(expectedAlphabetical)) {
  2150  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expectedAlphabetical, bufAlphabetical.String())
  2151  	}
  2152  }
  2153  
  2154  type testDuration struct {
  2155  	Nanosec   time.Duration  `toml:"nanosec"`
  2156  	Microsec1 time.Duration  `toml:"microsec1"`
  2157  	Microsec2 *time.Duration `toml:"microsec2"`
  2158  	Millisec  time.Duration  `toml:"millisec"`
  2159  	Sec       time.Duration  `toml:"sec"`
  2160  	Min       time.Duration  `toml:"min"`
  2161  	Hour      time.Duration  `toml:"hour"`
  2162  	Mixed     time.Duration  `toml:"mixed"`
  2163  	AString   string         `toml:"a_string"`
  2164  }
  2165  
  2166  var testDurationToml = []byte(`
  2167  nanosec = "1ns"
  2168  microsec1 = "1us"
  2169  microsec2 = "1µs"
  2170  millisec = "1ms"
  2171  sec = "1s"
  2172  min = "1m"
  2173  hour = "1h"
  2174  mixed = "1h1m1s1ms1µs1ns"
  2175  a_string = "15s"
  2176  `)
  2177  
  2178  func TestUnmarshalDuration(t *testing.T) {
  2179  	buf := bytes.NewBuffer(testDurationToml)
  2180  
  2181  	result := testDuration{}
  2182  	err := NewDecoder(buf).Decode(&result)
  2183  	if err != nil {
  2184  		t.Fatal(err)
  2185  	}
  2186  	ms := time.Duration(1) * time.Microsecond
  2187  	expected := testDuration{
  2188  		Nanosec:   1,
  2189  		Microsec1: time.Microsecond,
  2190  		Microsec2: &ms,
  2191  		Millisec:  time.Millisecond,
  2192  		Sec:       time.Second,
  2193  		Min:       time.Minute,
  2194  		Hour:      time.Hour,
  2195  		Mixed: time.Hour +
  2196  			time.Minute +
  2197  			time.Second +
  2198  			time.Millisecond +
  2199  			time.Microsecond +
  2200  			time.Nanosecond,
  2201  		AString: "15s",
  2202  	}
  2203  	if !reflect.DeepEqual(result, expected) {
  2204  		resStr, _ := json.MarshalIndent(result, "", "  ")
  2205  		expStr, _ := json.MarshalIndent(expected, "", "  ")
  2206  		t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
  2207  
  2208  	}
  2209  }
  2210  
  2211  var testDurationToml2 = []byte(`a_string = "15s"
  2212  hour = "1h0m0s"
  2213  microsec1 = "1µs"
  2214  microsec2 = "1µs"
  2215  millisec = "1ms"
  2216  min = "1m0s"
  2217  mixed = "1h1m1.001001001s"
  2218  nanosec = "1ns"
  2219  sec = "1s"
  2220  `)
  2221  
  2222  func TestMarshalDuration(t *testing.T) {
  2223  	ms := time.Duration(1) * time.Microsecond
  2224  	data := testDuration{
  2225  		Nanosec:   1,
  2226  		Microsec1: time.Microsecond,
  2227  		Microsec2: &ms,
  2228  		Millisec:  time.Millisecond,
  2229  		Sec:       time.Second,
  2230  		Min:       time.Minute,
  2231  		Hour:      time.Hour,
  2232  		Mixed: time.Hour +
  2233  			time.Minute +
  2234  			time.Second +
  2235  			time.Millisecond +
  2236  			time.Microsecond +
  2237  			time.Nanosecond,
  2238  		AString: "15s",
  2239  	}
  2240  
  2241  	var buf bytes.Buffer
  2242  	err := NewEncoder(&buf).Encode(data)
  2243  	if err != nil {
  2244  		t.Fatal(err)
  2245  	}
  2246  	expected := testDurationToml2
  2247  	result := buf.Bytes()
  2248  	if !bytes.Equal(result, expected) {
  2249  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  2250  	}
  2251  }
  2252  
  2253  type testBadDuration struct {
  2254  	Val time.Duration `toml:"val"`
  2255  }
  2256  
  2257  var testBadDurationToml = []byte(`val = "1z"`)
  2258  
  2259  func TestUnmarshalBadDuration(t *testing.T) {
  2260  	buf := bytes.NewBuffer(testBadDurationToml)
  2261  
  2262  	result := testBadDuration{}
  2263  	err := NewDecoder(buf).Decode(&result)
  2264  	if err == nil {
  2265  		t.Fatal("expected bad duration error")
  2266  	}
  2267  }
  2268  
  2269  var testCamelCaseKeyToml = []byte(`fooBar = 10`)
  2270  
  2271  func TestUnmarshalCamelCaseKey(t *testing.T) {
  2272  	var x struct {
  2273  		FooBar int
  2274  		B      int
  2275  	}
  2276  
  2277  	if err := Unmarshal(testCamelCaseKeyToml, &x); err != nil {
  2278  		t.Fatal(err)
  2279  	}
  2280  
  2281  	if x.FooBar != 10 {
  2282  		t.Fatal("Did not set camelCase'd key")
  2283  	}
  2284  }
  2285  
  2286  func TestUnmarshalNegativeUint(t *testing.T) {
  2287  	type check struct{ U uint }
  2288  
  2289  	tree, _ := Load("u = -1")
  2290  	err := tree.Unmarshal(&check{})
  2291  	if err.Error() != "(1, 1): -1(int64) is negative so does not fit in uint" {
  2292  		t.Error("expect err:(1, 1): -1(int64) is negative so does not fit in uint but got:", err)
  2293  	}
  2294  }
  2295  
  2296  func TestUnmarshalCheckConversionFloatInt(t *testing.T) {
  2297  	type conversionCheck struct {
  2298  		U uint
  2299  		I int
  2300  		F float64
  2301  	}
  2302  
  2303  	treeU, _ := Load("u = 1e300")
  2304  	treeI, _ := Load("i = 1e300")
  2305  	treeF, _ := Load("f = 9223372036854775806")
  2306  
  2307  	errU := treeU.Unmarshal(&conversionCheck{})
  2308  	errI := treeI.Unmarshal(&conversionCheck{})
  2309  	errF := treeF.Unmarshal(&conversionCheck{})
  2310  
  2311  	if errU.Error() != "(1, 1): Can't convert 1e+300(float64) to uint" {
  2312  		t.Error("expect err:(1, 1): Can't convert 1e+300(float64) to uint but got:", errU)
  2313  	}
  2314  	if errI.Error() != "(1, 1): Can't convert 1e+300(float64) to int" {
  2315  		t.Error("expect err:(1, 1): Can't convert 1e+300(float64) to int but got:", errI)
  2316  	}
  2317  	if errF.Error() != "(1, 1): Can't convert 9223372036854775806(int64) to float64" {
  2318  		t.Error("expect err:(1, 1): Can't convert 9223372036854775806(int64) to float64 but got:", errF)
  2319  	}
  2320  }
  2321  
  2322  func TestUnmarshalOverflow(t *testing.T) {
  2323  	type overflow struct {
  2324  		U8  uint8
  2325  		I8  int8
  2326  		F32 float32
  2327  	}
  2328  
  2329  	treeU8, _ := Load("u8 = 300")
  2330  	treeI8, _ := Load("i8 = 300")
  2331  	treeF32, _ := Load("f32 = 1e300")
  2332  
  2333  	errU8 := treeU8.Unmarshal(&overflow{})
  2334  	errI8 := treeI8.Unmarshal(&overflow{})
  2335  	errF32 := treeF32.Unmarshal(&overflow{})
  2336  
  2337  	if errU8.Error() != "(1, 1): 300(int64) would overflow uint8" {
  2338  		t.Error("expect err:(1, 1): 300(int64) would overflow uint8 but got:", errU8)
  2339  	}
  2340  	if errI8.Error() != "(1, 1): 300(int64) would overflow int8" {
  2341  		t.Error("expect err:(1, 1): 300(int64) would overflow int8 but got:", errI8)
  2342  	}
  2343  	if errF32.Error() != "(1, 1): 1e+300(float64) would overflow float32" {
  2344  		t.Error("expect err:(1, 1): 1e+300(float64) would overflow float32 but got:", errF32)
  2345  	}
  2346  }
  2347  
  2348  func TestUnmarshalDefault(t *testing.T) {
  2349  	type EmbeddedStruct struct {
  2350  		StringField string `default:"c"`
  2351  	}
  2352  
  2353  	type aliasUint uint
  2354  
  2355  	var doc struct {
  2356  		StringField       string        `default:"a"`
  2357  		BoolField         bool          `default:"true"`
  2358  		UintField         uint          `default:"1"`
  2359  		Uint8Field        uint8         `default:"8"`
  2360  		Uint16Field       uint16        `default:"16"`
  2361  		Uint32Field       uint32        `default:"32"`
  2362  		Uint64Field       uint64        `default:"64"`
  2363  		IntField          int           `default:"-1"`
  2364  		Int8Field         int8          `default:"-8"`
  2365  		Int16Field        int16         `default:"-16"`
  2366  		Int32Field        int32         `default:"-32"`
  2367  		Int64Field        int64         `default:"-64"`
  2368  		Float32Field      float32       `default:"32.1"`
  2369  		Float64Field      float64       `default:"64.1"`
  2370  		DurationField     time.Duration `default:"120ms"`
  2371  		DurationField2    time.Duration `default:"120000000"`
  2372  		NonEmbeddedStruct struct {
  2373  			StringField string `default:"b"`
  2374  		}
  2375  		EmbeddedStruct
  2376  		AliasUintField aliasUint `default:"1000"`
  2377  	}
  2378  
  2379  	err := Unmarshal([]byte(``), &doc)
  2380  	if err != nil {
  2381  		t.Fatal(err)
  2382  	}
  2383  	if doc.BoolField != true {
  2384  		t.Errorf("BoolField should be true, not %t", doc.BoolField)
  2385  	}
  2386  	if doc.StringField != "a" {
  2387  		t.Errorf("StringField should be \"a\", not %s", doc.StringField)
  2388  	}
  2389  	if doc.UintField != 1 {
  2390  		t.Errorf("UintField should be 1, not %d", doc.UintField)
  2391  	}
  2392  	if doc.Uint8Field != 8 {
  2393  		t.Errorf("Uint8Field should be 8, not %d", doc.Uint8Field)
  2394  	}
  2395  	if doc.Uint16Field != 16 {
  2396  		t.Errorf("Uint16Field should be 16, not %d", doc.Uint16Field)
  2397  	}
  2398  	if doc.Uint32Field != 32 {
  2399  		t.Errorf("Uint32Field should be 32, not %d", doc.Uint32Field)
  2400  	}
  2401  	if doc.Uint64Field != 64 {
  2402  		t.Errorf("Uint64Field should be 64, not %d", doc.Uint64Field)
  2403  	}
  2404  	if doc.IntField != -1 {
  2405  		t.Errorf("IntField should be -1, not %d", doc.IntField)
  2406  	}
  2407  	if doc.Int8Field != -8 {
  2408  		t.Errorf("Int8Field should be -8, not %d", doc.Int8Field)
  2409  	}
  2410  	if doc.Int16Field != -16 {
  2411  		t.Errorf("Int16Field should be -16, not %d", doc.Int16Field)
  2412  	}
  2413  	if doc.Int32Field != -32 {
  2414  		t.Errorf("Int32Field should be -32, not %d", doc.Int32Field)
  2415  	}
  2416  	if doc.Int64Field != -64 {
  2417  		t.Errorf("Int64Field should be -64, not %d", doc.Int64Field)
  2418  	}
  2419  	if doc.Float32Field != 32.1 {
  2420  		t.Errorf("Float32Field should be 32.1, not %f", doc.Float32Field)
  2421  	}
  2422  	if doc.Float64Field != 64.1 {
  2423  		t.Errorf("Float64Field should be 64.1, not %f", doc.Float64Field)
  2424  	}
  2425  	if doc.DurationField != 120*time.Millisecond {
  2426  		t.Errorf("DurationField should be 120ms, not %s", doc.DurationField.String())
  2427  	}
  2428  	if doc.DurationField2 != 120*time.Millisecond {
  2429  		t.Errorf("DurationField2 should be 120000000, not %d", doc.DurationField2)
  2430  	}
  2431  	if doc.NonEmbeddedStruct.StringField != "b" {
  2432  		t.Errorf("StringField should be \"b\", not %s", doc.NonEmbeddedStruct.StringField)
  2433  	}
  2434  	if doc.EmbeddedStruct.StringField != "c" {
  2435  		t.Errorf("StringField should be \"c\", not %s", doc.EmbeddedStruct.StringField)
  2436  	}
  2437  	if doc.AliasUintField != 1000 {
  2438  		t.Errorf("AliasUintField should be 1000, not %d", doc.AliasUintField)
  2439  	}
  2440  }
  2441  
  2442  func TestUnmarshalDefaultFailureBool(t *testing.T) {
  2443  	var doc struct {
  2444  		Field bool `default:"blah"`
  2445  	}
  2446  
  2447  	err := Unmarshal([]byte(``), &doc)
  2448  	if err == nil {
  2449  		t.Fatal("should error")
  2450  	}
  2451  }
  2452  
  2453  func TestUnmarshalDefaultFailureInt(t *testing.T) {
  2454  	var doc struct {
  2455  		Field int `default:"blah"`
  2456  	}
  2457  
  2458  	err := Unmarshal([]byte(``), &doc)
  2459  	if err == nil {
  2460  		t.Fatal("should error")
  2461  	}
  2462  }
  2463  
  2464  func TestUnmarshalDefaultFailureInt64(t *testing.T) {
  2465  	var doc struct {
  2466  		Field int64 `default:"blah"`
  2467  	}
  2468  
  2469  	err := Unmarshal([]byte(``), &doc)
  2470  	if err == nil {
  2471  		t.Fatal("should error")
  2472  	}
  2473  }
  2474  
  2475  func TestUnmarshalDefaultFailureFloat64(t *testing.T) {
  2476  	var doc struct {
  2477  		Field float64 `default:"blah"`
  2478  	}
  2479  
  2480  	err := Unmarshal([]byte(``), &doc)
  2481  	if err == nil {
  2482  		t.Fatal("should error")
  2483  	}
  2484  }
  2485  
  2486  func TestUnmarshalDefaultFailureDuration(t *testing.T) {
  2487  	var doc struct {
  2488  		Field time.Duration `default:"blah"`
  2489  	}
  2490  
  2491  	err := Unmarshal([]byte(``), &doc)
  2492  	if err == nil {
  2493  		t.Fatal("should error")
  2494  	}
  2495  }
  2496  
  2497  func TestUnmarshalDefaultFailureUnsupported(t *testing.T) {
  2498  	var doc struct {
  2499  		Field struct{} `default:"blah"`
  2500  	}
  2501  
  2502  	err := Unmarshal([]byte(``), &doc)
  2503  	if err == nil {
  2504  		t.Fatal("should error")
  2505  	}
  2506  }
  2507  
  2508  func TestMarshalNestedAnonymousStructs(t *testing.T) {
  2509  	type Embedded struct {
  2510  		Value string `toml:"value"`
  2511  		Top   struct {
  2512  			Value string `toml:"value"`
  2513  		} `toml:"top"`
  2514  	}
  2515  
  2516  	type Named struct {
  2517  		Value string `toml:"value"`
  2518  	}
  2519  
  2520  	var doc struct {
  2521  		Embedded
  2522  		Named     `toml:"named"`
  2523  		Anonymous struct {
  2524  			Value string `toml:"value"`
  2525  		} `toml:"anonymous"`
  2526  	}
  2527  
  2528  	expected := `value = ""
  2529  
  2530  [anonymous]
  2531    value = ""
  2532  
  2533  [named]
  2534    value = ""
  2535  
  2536  [top]
  2537    value = ""
  2538  `
  2539  
  2540  	result, err := Marshal(doc)
  2541  	if err != nil {
  2542  		t.Fatalf("unexpected error: %s", err.Error())
  2543  	}
  2544  	if !bytes.Equal(result, []byte(expected)) {
  2545  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, string(result))
  2546  	}
  2547  }
  2548  
  2549  func TestEncoderPromoteNestedAnonymousStructs(t *testing.T) {
  2550  	type Embedded struct {
  2551  		Value string `toml:"value"`
  2552  	}
  2553  
  2554  	var doc struct {
  2555  		Embedded
  2556  	}
  2557  
  2558  	expected := `
  2559  [Embedded]
  2560    value = ""
  2561  `
  2562  	var buf bytes.Buffer
  2563  	if err := NewEncoder(&buf).PromoteAnonymous(true).Encode(doc); err != nil {
  2564  		t.Fatalf("unexpected error: %s", err.Error())
  2565  	}
  2566  	if !bytes.Equal(buf.Bytes(), []byte(expected)) {
  2567  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, buf.String())
  2568  	}
  2569  }
  2570  
  2571  func TestMarshalNestedAnonymousStructs_DuplicateField(t *testing.T) {
  2572  	type Embedded struct {
  2573  		Value string `toml:"value"`
  2574  		Top   struct {
  2575  			Value string `toml:"value"`
  2576  		} `toml:"top"`
  2577  	}
  2578  
  2579  	var doc struct {
  2580  		Value string `toml:"value"`
  2581  		Embedded
  2582  	}
  2583  	doc.Embedded.Value = "shadowed"
  2584  	doc.Value = "shadows"
  2585  
  2586  	expected := `value = "shadows"
  2587  
  2588  [top]
  2589    value = ""
  2590  `
  2591  
  2592  	result, err := Marshal(doc)
  2593  	if err != nil {
  2594  		t.Fatalf("unexpected error: %s", err.Error())
  2595  	}
  2596  	if !bytes.Equal(result, []byte(expected)) {
  2597  		t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, string(result))
  2598  	}
  2599  }
  2600  
  2601  func TestUnmarshalNestedAnonymousStructs(t *testing.T) {
  2602  	type Nested struct {
  2603  		Value string `toml:"nested_field"`
  2604  	}
  2605  	type Deep struct {
  2606  		Nested
  2607  	}
  2608  	type Document struct {
  2609  		Deep
  2610  		Value string `toml:"own_field"`
  2611  	}
  2612  
  2613  	var doc Document
  2614  
  2615  	err := Unmarshal([]byte(`nested_field = "nested value"`+"\n"+`own_field = "own value"`), &doc)
  2616  	if err != nil {
  2617  		t.Fatal("should not error")
  2618  	}
  2619  	if doc.Value != "own value" || doc.Nested.Value != "nested value" {
  2620  		t.Fatal("unexpected values")
  2621  	}
  2622  }
  2623  
  2624  func TestUnmarshalNestedAnonymousStructs_Controversial(t *testing.T) {
  2625  	type Nested struct {
  2626  		Value string `toml:"nested"`
  2627  	}
  2628  	type Deep struct {
  2629  		Nested
  2630  	}
  2631  	type Document struct {
  2632  		Deep
  2633  		Value string `toml:"own"`
  2634  	}
  2635  
  2636  	var doc Document
  2637  
  2638  	err := Unmarshal([]byte(`nested = "nested value"`+"\n"+`own = "own value"`), &doc)
  2639  	if err == nil {
  2640  		t.Fatal("should error")
  2641  	}
  2642  }
  2643  
  2644  type unexportedFieldPreservationTest struct {
  2645  	Exported   string `toml:"exported"`
  2646  	unexported string
  2647  	Nested1    unexportedFieldPreservationTestNested    `toml:"nested1"`
  2648  	Nested2    *unexportedFieldPreservationTestNested   `toml:"nested2"`
  2649  	Nested3    *unexportedFieldPreservationTestNested   `toml:"nested3"`
  2650  	Slice1     []unexportedFieldPreservationTestNested  `toml:"slice1"`
  2651  	Slice2     []*unexportedFieldPreservationTestNested `toml:"slice2"`
  2652  }
  2653  
  2654  type unexportedFieldPreservationTestNested struct {
  2655  	Exported1   string `toml:"exported1"`
  2656  	unexported1 string
  2657  }
  2658  
  2659  func TestUnmarshalPreservesUnexportedFields(t *testing.T) {
  2660  	toml := `
  2661  	exported = "visible"
  2662  	unexported = "ignored"
  2663  
  2664  	[nested1]
  2665  	exported1 = "visible1"
  2666  	unexported1 = "ignored1"
  2667  
  2668  	[nested2]
  2669  	exported1 = "visible2"
  2670  	unexported1 = "ignored2"
  2671  
  2672  	[nested3]
  2673  	exported1 = "visible3"
  2674  	unexported1 = "ignored3"
  2675  
  2676  	[[slice1]]
  2677  	exported1 = "visible3"
  2678  
  2679  	[[slice1]]
  2680  	exported1 = "visible4"
  2681  
  2682  	[[slice2]]
  2683  	exported1 = "visible5"
  2684  	`
  2685  
  2686  	t.Run("unexported field should not be set from toml", func(t *testing.T) {
  2687  		var actual unexportedFieldPreservationTest
  2688  		err := Unmarshal([]byte(toml), &actual)
  2689  
  2690  		if err != nil {
  2691  			t.Fatal("did not expect an error")
  2692  		}
  2693  
  2694  		expect := unexportedFieldPreservationTest{
  2695  			Exported:   "visible",
  2696  			unexported: "",
  2697  			Nested1:    unexportedFieldPreservationTestNested{"visible1", ""},
  2698  			Nested2:    &unexportedFieldPreservationTestNested{"visible2", ""},
  2699  			Nested3:    &unexportedFieldPreservationTestNested{"visible3", ""},
  2700  			Slice1: []unexportedFieldPreservationTestNested{
  2701  				{Exported1: "visible3"},
  2702  				{Exported1: "visible4"},
  2703  			},
  2704  			Slice2: []*unexportedFieldPreservationTestNested{
  2705  				{Exported1: "visible5"},
  2706  			},
  2707  		}
  2708  
  2709  		if !reflect.DeepEqual(actual, expect) {
  2710  			t.Fatalf("%+v did not equal %+v", actual, expect)
  2711  		}
  2712  	})
  2713  
  2714  	t.Run("unexported field should be preserved", func(t *testing.T) {
  2715  		actual := unexportedFieldPreservationTest{
  2716  			Exported:   "foo",
  2717  			unexported: "bar",
  2718  			Nested1:    unexportedFieldPreservationTestNested{"baz", "bax"},
  2719  			Nested2:    nil,
  2720  			Nested3:    &unexportedFieldPreservationTestNested{"baz", "bax"},
  2721  		}
  2722  		err := Unmarshal([]byte(toml), &actual)
  2723  
  2724  		if err != nil {
  2725  			t.Fatal("did not expect an error")
  2726  		}
  2727  
  2728  		expect := unexportedFieldPreservationTest{
  2729  			Exported:   "visible",
  2730  			unexported: "bar",
  2731  			Nested1:    unexportedFieldPreservationTestNested{"visible1", "bax"},
  2732  			Nested2:    &unexportedFieldPreservationTestNested{"visible2", ""},
  2733  			Nested3:    &unexportedFieldPreservationTestNested{"visible3", "bax"},
  2734  			Slice1: []unexportedFieldPreservationTestNested{
  2735  				{Exported1: "visible3"},
  2736  				{Exported1: "visible4"},
  2737  			},
  2738  			Slice2: []*unexportedFieldPreservationTestNested{
  2739  				{Exported1: "visible5"},
  2740  			},
  2741  		}
  2742  
  2743  		if !reflect.DeepEqual(actual, expect) {
  2744  			t.Fatalf("%+v did not equal %+v", actual, expect)
  2745  		}
  2746  	})
  2747  }
  2748  
  2749  func TestTreeMarshal(t *testing.T) {
  2750  	cases := [][]byte{
  2751  		basicTestToml,
  2752  		marshalTestToml,
  2753  		emptyTestToml,
  2754  		pointerTestToml,
  2755  	}
  2756  	for _, expected := range cases {
  2757  		t.Run("", func(t *testing.T) {
  2758  			tree, err := LoadBytes(expected)
  2759  			if err != nil {
  2760  				t.Fatal(err)
  2761  			}
  2762  			result, err := tree.Marshal()
  2763  			if err != nil {
  2764  				t.Fatal(err)
  2765  			}
  2766  			if !bytes.Equal(result, expected) {
  2767  				t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
  2768  			}
  2769  		})
  2770  	}
  2771  }
  2772  
  2773  func TestMarshalArrays(t *testing.T) {
  2774  	cases := []struct {
  2775  		Data     interface{}
  2776  		Expected string
  2777  	}{
  2778  		{
  2779  			Data: struct {
  2780  				XY [2]int
  2781  			}{
  2782  				XY: [2]int{1, 2},
  2783  			},
  2784  			Expected: `XY = [1, 2]
  2785  `,
  2786  		},
  2787  		{
  2788  			Data: struct {
  2789  				XY [1][2]int
  2790  			}{
  2791  				XY: [1][2]int{{1, 2}},
  2792  			},
  2793  			Expected: `XY = [[1, 2]]
  2794  `,
  2795  		},
  2796  		{
  2797  			Data: struct {
  2798  				XY [1][]int
  2799  			}{
  2800  				XY: [1][]int{{1, 2}},
  2801  			},
  2802  			Expected: `XY = [[1, 2]]
  2803  `,
  2804  		},
  2805  		{
  2806  			Data: struct {
  2807  				XY [][2]int
  2808  			}{
  2809  				XY: [][2]int{{1, 2}},
  2810  			},
  2811  			Expected: `XY = [[1, 2]]
  2812  `,
  2813  		},
  2814  	}
  2815  	for _, tc := range cases {
  2816  		t.Run("", func(t *testing.T) {
  2817  			result, err := Marshal(tc.Data)
  2818  			if err != nil {
  2819  				t.Fatal(err)
  2820  			}
  2821  			if !bytes.Equal(result, []byte(tc.Expected)) {
  2822  				t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", []byte(tc.Expected), result)
  2823  			}
  2824  		})
  2825  	}
  2826  }
  2827  
  2828  func TestUnmarshalLocalDate(t *testing.T) {
  2829  	t.Run("ToLocalDate", func(t *testing.T) {
  2830  		type dateStruct struct {
  2831  			Date LocalDate
  2832  		}
  2833  
  2834  		toml := `date = 1979-05-27`
  2835  
  2836  		var obj dateStruct
  2837  
  2838  		err := Unmarshal([]byte(toml), &obj)
  2839  
  2840  		if err != nil {
  2841  			t.Fatal(err)
  2842  		}
  2843  
  2844  		if obj.Date.Year != 1979 {
  2845  			t.Errorf("expected year 1979, got %d", obj.Date.Year)
  2846  		}
  2847  		if obj.Date.Month != 5 {
  2848  			t.Errorf("expected month 5, got %d", obj.Date.Month)
  2849  		}
  2850  		if obj.Date.Day != 27 {
  2851  			t.Errorf("expected day 27, got %d", obj.Date.Day)
  2852  		}
  2853  	})
  2854  
  2855  	t.Run("ToLocalDate", func(t *testing.T) {
  2856  		type dateStruct struct {
  2857  			Date time.Time
  2858  		}
  2859  
  2860  		toml := `date = 1979-05-27`
  2861  
  2862  		var obj dateStruct
  2863  
  2864  		err := Unmarshal([]byte(toml), &obj)
  2865  
  2866  		if err != nil {
  2867  			t.Fatal(err)
  2868  		}
  2869  
  2870  		if obj.Date.Year() != 1979 {
  2871  			t.Errorf("expected year 1979, got %d", obj.Date.Year())
  2872  		}
  2873  		if obj.Date.Month() != 5 {
  2874  			t.Errorf("expected month 5, got %d", obj.Date.Month())
  2875  		}
  2876  		if obj.Date.Day() != 27 {
  2877  			t.Errorf("expected day 27, got %d", obj.Date.Day())
  2878  		}
  2879  	})
  2880  }
  2881  
  2882  func TestMarshalLocalDate(t *testing.T) {
  2883  	type dateStruct struct {
  2884  		Date LocalDate
  2885  	}
  2886  
  2887  	obj := dateStruct{Date: LocalDate{
  2888  		Year:  1979,
  2889  		Month: 5,
  2890  		Day:   27,
  2891  	}}
  2892  
  2893  	b, err := Marshal(obj)
  2894  
  2895  	if err != nil {
  2896  		t.Fatalf("unexpected error: %v", err)
  2897  	}
  2898  
  2899  	got := string(b)
  2900  	expected := `Date = 1979-05-27
  2901  `
  2902  
  2903  	if got != expected {
  2904  		t.Errorf("expected '%s', got '%s'", expected, got)
  2905  	}
  2906  }
  2907  
  2908  func TestUnmarshalLocalDateTime(t *testing.T) {
  2909  	examples := []struct {
  2910  		name string
  2911  		in   string
  2912  		out  LocalDateTime
  2913  	}{
  2914  		{
  2915  			name: "normal",
  2916  			in:   "1979-05-27T07:32:00",
  2917  			out: LocalDateTime{
  2918  				Date: LocalDate{
  2919  					Year:  1979,
  2920  					Month: 5,
  2921  					Day:   27,
  2922  				},
  2923  				Time: LocalTime{
  2924  					Hour:       7,
  2925  					Minute:     32,
  2926  					Second:     0,
  2927  					Nanosecond: 0,
  2928  				},
  2929  			}},
  2930  		{
  2931  			name: "with nanoseconds",
  2932  			in:   "1979-05-27T00:32:00.999999",
  2933  			out: LocalDateTime{
  2934  				Date: LocalDate{
  2935  					Year:  1979,
  2936  					Month: 5,
  2937  					Day:   27,
  2938  				},
  2939  				Time: LocalTime{
  2940  					Hour:       0,
  2941  					Minute:     32,
  2942  					Second:     0,
  2943  					Nanosecond: 999999000,
  2944  				},
  2945  			},
  2946  		},
  2947  	}
  2948  
  2949  	for i, example := range examples {
  2950  		toml := fmt.Sprintf(`date = %s`, example.in)
  2951  
  2952  		t.Run(fmt.Sprintf("ToLocalDateTime_%d_%s", i, example.name), func(t *testing.T) {
  2953  			type dateStruct struct {
  2954  				Date LocalDateTime
  2955  			}
  2956  
  2957  			var obj dateStruct
  2958  
  2959  			err := Unmarshal([]byte(toml), &obj)
  2960  
  2961  			if err != nil {
  2962  				t.Fatal(err)
  2963  			}
  2964  
  2965  			if obj.Date != example.out {
  2966  				t.Errorf("expected '%s', got '%s'", example.out, obj.Date)
  2967  			}
  2968  		})
  2969  
  2970  		t.Run(fmt.Sprintf("ToTime_%d_%s", i, example.name), func(t *testing.T) {
  2971  			type dateStruct struct {
  2972  				Date time.Time
  2973  			}
  2974  
  2975  			var obj dateStruct
  2976  
  2977  			err := Unmarshal([]byte(toml), &obj)
  2978  
  2979  			if err != nil {
  2980  				t.Fatal(err)
  2981  			}
  2982  
  2983  			if obj.Date.Year() != example.out.Date.Year {
  2984  				t.Errorf("expected year %d, got %d", example.out.Date.Year, obj.Date.Year())
  2985  			}
  2986  			if obj.Date.Month() != example.out.Date.Month {
  2987  				t.Errorf("expected month %d, got %d", example.out.Date.Month, obj.Date.Month())
  2988  			}
  2989  			if obj.Date.Day() != example.out.Date.Day {
  2990  				t.Errorf("expected day %d, got %d", example.out.Date.Day, obj.Date.Day())
  2991  			}
  2992  			if obj.Date.Hour() != example.out.Time.Hour {
  2993  				t.Errorf("expected hour %d, got %d", example.out.Time.Hour, obj.Date.Hour())
  2994  			}
  2995  			if obj.Date.Minute() != example.out.Time.Minute {
  2996  				t.Errorf("expected minute %d, got %d", example.out.Time.Minute, obj.Date.Minute())
  2997  			}
  2998  			if obj.Date.Second() != example.out.Time.Second {
  2999  				t.Errorf("expected second %d, got %d", example.out.Time.Second, obj.Date.Second())
  3000  			}
  3001  			if obj.Date.Nanosecond() != example.out.Time.Nanosecond {
  3002  				t.Errorf("expected nanoseconds %d, got %d", example.out.Time.Nanosecond, obj.Date.Nanosecond())
  3003  			}
  3004  		})
  3005  	}
  3006  }
  3007  
  3008  func TestMarshalLocalDateTime(t *testing.T) {
  3009  	type dateStruct struct {
  3010  		DateTime LocalDateTime
  3011  	}
  3012  
  3013  	examples := []struct {
  3014  		name string
  3015  		in   LocalDateTime
  3016  		out  string
  3017  	}{
  3018  		{
  3019  			name: "normal",
  3020  			out:  "DateTime = 1979-05-27T07:32:00\n",
  3021  			in: LocalDateTime{
  3022  				Date: LocalDate{
  3023  					Year:  1979,
  3024  					Month: 5,
  3025  					Day:   27,
  3026  				},
  3027  				Time: LocalTime{
  3028  					Hour:       7,
  3029  					Minute:     32,
  3030  					Second:     0,
  3031  					Nanosecond: 0,
  3032  				},
  3033  			}},
  3034  		{
  3035  			name: "with nanoseconds",
  3036  			out:  "DateTime = 1979-05-27T00:32:00.999999000\n",
  3037  			in: LocalDateTime{
  3038  				Date: LocalDate{
  3039  					Year:  1979,
  3040  					Month: 5,
  3041  					Day:   27,
  3042  				},
  3043  				Time: LocalTime{
  3044  					Hour:       0,
  3045  					Minute:     32,
  3046  					Second:     0,
  3047  					Nanosecond: 999999000,
  3048  				},
  3049  			},
  3050  		},
  3051  	}
  3052  
  3053  	for i, example := range examples {
  3054  		t.Run(fmt.Sprintf("%d_%s", i, example.name), func(t *testing.T) {
  3055  			obj := dateStruct{
  3056  				DateTime: example.in,
  3057  			}
  3058  			b, err := Marshal(obj)
  3059  
  3060  			if err != nil {
  3061  				t.Fatalf("unexpected error: %v", err)
  3062  			}
  3063  
  3064  			got := string(b)
  3065  
  3066  			if got != example.out {
  3067  				t.Errorf("expected '%s', got '%s'", example.out, got)
  3068  			}
  3069  		})
  3070  	}
  3071  }
  3072  
  3073  func TestUnmarshalLocalTime(t *testing.T) {
  3074  	examples := []struct {
  3075  		name string
  3076  		in   string
  3077  		out  LocalTime
  3078  	}{
  3079  		{
  3080  			name: "normal",
  3081  			in:   "07:32:00",
  3082  			out: LocalTime{
  3083  				Hour:       7,
  3084  				Minute:     32,
  3085  				Second:     0,
  3086  				Nanosecond: 0,
  3087  			},
  3088  		},
  3089  		{
  3090  			name: "with nanoseconds",
  3091  			in:   "00:32:00.999999",
  3092  			out: LocalTime{
  3093  				Hour:       0,
  3094  				Minute:     32,
  3095  				Second:     0,
  3096  				Nanosecond: 999999000,
  3097  			},
  3098  		},
  3099  	}
  3100  
  3101  	for i, example := range examples {
  3102  		toml := fmt.Sprintf(`Time = %s`, example.in)
  3103  
  3104  		t.Run(fmt.Sprintf("ToLocalTime_%d_%s", i, example.name), func(t *testing.T) {
  3105  			type dateStruct struct {
  3106  				Time LocalTime
  3107  			}
  3108  
  3109  			var obj dateStruct
  3110  
  3111  			err := Unmarshal([]byte(toml), &obj)
  3112  
  3113  			if err != nil {
  3114  				t.Fatal(err)
  3115  			}
  3116  
  3117  			if obj.Time != example.out {
  3118  				t.Errorf("expected '%s', got '%s'", example.out, obj.Time)
  3119  			}
  3120  		})
  3121  	}
  3122  }
  3123  
  3124  func TestMarshalLocalTime(t *testing.T) {
  3125  	type timeStruct struct {
  3126  		Time LocalTime
  3127  	}
  3128  
  3129  	examples := []struct {
  3130  		name string
  3131  		in   LocalTime
  3132  		out  string
  3133  	}{
  3134  		{
  3135  			name: "normal",
  3136  			out:  "Time = 07:32:00\n",
  3137  			in: LocalTime{
  3138  				Hour:       7,
  3139  				Minute:     32,
  3140  				Second:     0,
  3141  				Nanosecond: 0,
  3142  			}},
  3143  		{
  3144  			name: "with nanoseconds",
  3145  			out:  "Time = 00:32:00.999999000\n",
  3146  			in: LocalTime{
  3147  				Hour:       0,
  3148  				Minute:     32,
  3149  				Second:     0,
  3150  				Nanosecond: 999999000,
  3151  			},
  3152  		},
  3153  	}
  3154  
  3155  	for i, example := range examples {
  3156  		t.Run(fmt.Sprintf("%d_%s", i, example.name), func(t *testing.T) {
  3157  			obj := timeStruct{
  3158  				Time: example.in,
  3159  			}
  3160  			b, err := Marshal(obj)
  3161  
  3162  			if err != nil {
  3163  				t.Fatalf("unexpected error: %v", err)
  3164  			}
  3165  
  3166  			got := string(b)
  3167  
  3168  			if got != example.out {
  3169  				t.Errorf("expected '%s', got '%s'", example.out, got)
  3170  			}
  3171  		})
  3172  	}
  3173  }
  3174  
  3175  // test case for issue #339
  3176  func TestUnmarshalSameInnerField(t *testing.T) {
  3177  	type InterStruct2 struct {
  3178  		Test string
  3179  		Name string
  3180  		Age  int
  3181  	}
  3182  	type Inter2 struct {
  3183  		Name         string
  3184  		Age          int
  3185  		InterStruct2 InterStruct2
  3186  	}
  3187  	type Server struct {
  3188  		Name   string `toml:"name"`
  3189  		Inter2 Inter2 `toml:"inter2"`
  3190  	}
  3191  
  3192  	var server Server
  3193  
  3194  	if err := Unmarshal([]byte(`name = "123"
  3195  [inter2]
  3196  name = "inter2"
  3197  age = 222`), &server); err == nil {
  3198  		expected := Server{
  3199  			Name: "123",
  3200  			Inter2: Inter2{
  3201  				Name: "inter2",
  3202  				Age:  222,
  3203  			},
  3204  		}
  3205  		if !reflect.DeepEqual(server, expected) {
  3206  			t.Errorf("Bad unmarshal: expected %v, got %v", expected, server)
  3207  		}
  3208  	} else {
  3209  		t.Fatalf("unexpected error: %v", err)
  3210  	}
  3211  }
  3212  
  3213  func TestMarshalInterface(t *testing.T) {
  3214  	type InnerStruct struct {
  3215  		InnerField string
  3216  	}
  3217  
  3218  	type OuterStruct struct {
  3219  		PrimitiveField        interface{}
  3220  		ArrayField            interface{}
  3221  		StructArrayField      interface{}
  3222  		MapField              map[string]interface{}
  3223  		StructField           interface{}
  3224  		PointerField          interface{}
  3225  		NilField              interface{}
  3226  		InterfacePointerField *interface{}
  3227  	}
  3228  
  3229  	expected := []byte(`ArrayField = [1, 2, 3]
  3230  InterfacePointerField = "hello world"
  3231  PrimitiveField = "string"
  3232  
  3233  [MapField]
  3234    key1 = "value1"
  3235    key2 = false
  3236  
  3237    [MapField.key3]
  3238      InnerField = "value3"
  3239  
  3240  [PointerField]
  3241    InnerField = "yyy"
  3242  
  3243  [[StructArrayField]]
  3244    InnerField = "s1"
  3245  
  3246  [[StructArrayField]]
  3247    InnerField = "s2"
  3248  
  3249  [StructField]
  3250    InnerField = "xxx"
  3251  `)
  3252  
  3253  	var h interface{} = "hello world"
  3254  	if result, err := Marshal(OuterStruct{
  3255  		"string",
  3256  		[]int{1, 2, 3},
  3257  		[]InnerStruct{{"s1"}, {"s2"}},
  3258  		map[string]interface{}{
  3259  			"key1":      "value1",
  3260  			"key2":      false,
  3261  			"key3":      InnerStruct{"value3"},
  3262  			"nil value": nil,
  3263  		},
  3264  		InnerStruct{
  3265  			"xxx",
  3266  		},
  3267  		&InnerStruct{
  3268  			"yyy",
  3269  		},
  3270  		nil,
  3271  		&h,
  3272  	}); err == nil {
  3273  		if !bytes.Equal(result, expected) {
  3274  			t.Errorf("Bad marshal: expected\n----\n%s\n----\ngot\n----\n%s\n----\n", expected, result)
  3275  		}
  3276  	} else {
  3277  		t.Fatal(err)
  3278  	}
  3279  }
  3280  
  3281  func TestUnmarshalToNilInterface(t *testing.T) {
  3282  	toml := []byte(`
  3283  PrimitiveField = "Hello"
  3284  ArrayField = [1,2,3]
  3285  InterfacePointerField = "World"
  3286  
  3287  [StructField]
  3288  Field1 = 123
  3289  Field2 = "Field2"
  3290  
  3291  [MapField]
  3292  MapField1 = [4,5,6]
  3293  MapField2 = {A = "A"}
  3294  MapField3 = false
  3295  
  3296  [[StructArrayField]]
  3297  Name = "Allen"
  3298  Age = 20
  3299  
  3300  [[StructArrayField]]
  3301  Name = "Jack"
  3302  Age = 23
  3303  `)
  3304  
  3305  	type OuterStruct struct {
  3306  		PrimitiveField        interface{}
  3307  		ArrayField            interface{}
  3308  		StructArrayField      interface{}
  3309  		MapField              map[string]interface{}
  3310  		StructField           interface{}
  3311  		NilField              interface{}
  3312  		InterfacePointerField *interface{}
  3313  	}
  3314  
  3315  	var s interface{} = "World"
  3316  	expected := OuterStruct{
  3317  		PrimitiveField: "Hello",
  3318  		ArrayField:     []interface{}{int64(1), int64(2), int64(3)},
  3319  		StructField: map[string]interface{}{
  3320  			"Field1": int64(123),
  3321  			"Field2": "Field2",
  3322  		},
  3323  		MapField: map[string]interface{}{
  3324  			"MapField1": []interface{}{int64(4), int64(5), int64(6)},
  3325  			"MapField2": map[string]interface{}{
  3326  				"A": "A",
  3327  			},
  3328  			"MapField3": false,
  3329  		},
  3330  		NilField:              nil,
  3331  		InterfacePointerField: &s,
  3332  		StructArrayField: []map[string]interface{}{
  3333  			{
  3334  				"Name": "Allen",
  3335  				"Age":  int64(20),
  3336  			},
  3337  			{
  3338  				"Name": "Jack",
  3339  				"Age":  int64(23),
  3340  			},
  3341  		},
  3342  	}
  3343  	actual := OuterStruct{}
  3344  	if err := Unmarshal(toml, &actual); err == nil {
  3345  		if !reflect.DeepEqual(actual, expected) {
  3346  			t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
  3347  		}
  3348  	} else {
  3349  		t.Fatal(err)
  3350  	}
  3351  }
  3352  
  3353  func TestUnmarshalToNonNilInterface(t *testing.T) {
  3354  	toml := []byte(`
  3355  PrimitiveField = "Allen"
  3356  ArrayField = [1,2,3]
  3357  
  3358  [StructField]
  3359  InnerField = "After1"
  3360  
  3361  [PointerField]
  3362  InnerField = "After2"
  3363  
  3364  [InterfacePointerField]
  3365  InnerField = "After"
  3366  
  3367  [MapField]
  3368  MapField1 = [4,5,6]
  3369  MapField2 = {A = "A"}
  3370  MapField3 = false
  3371  
  3372  [[StructArrayField]]
  3373  InnerField = "After3"
  3374  
  3375  [[StructArrayField]]
  3376  InnerField = "After4"
  3377  `)
  3378  	type InnerStruct struct {
  3379  		InnerField interface{}
  3380  	}
  3381  
  3382  	type OuterStruct struct {
  3383  		PrimitiveField        interface{}
  3384  		ArrayField            interface{}
  3385  		StructArrayField      interface{}
  3386  		MapField              map[string]interface{}
  3387  		StructField           interface{}
  3388  		PointerField          interface{}
  3389  		NilField              interface{}
  3390  		InterfacePointerField *interface{}
  3391  	}
  3392  
  3393  	var s interface{} = InnerStruct{"After"}
  3394  	expected := OuterStruct{
  3395  		PrimitiveField: "Allen",
  3396  		ArrayField:     []int{1, 2, 3},
  3397  		StructField:    InnerStruct{InnerField: "After1"},
  3398  		MapField: map[string]interface{}{
  3399  			"MapField1": []interface{}{int64(4), int64(5), int64(6)},
  3400  			"MapField2": map[string]interface{}{
  3401  				"A": "A",
  3402  			},
  3403  			"MapField3": false,
  3404  		},
  3405  		PointerField:          &InnerStruct{InnerField: "After2"},
  3406  		NilField:              nil,
  3407  		InterfacePointerField: &s,
  3408  		StructArrayField: []InnerStruct{
  3409  			{InnerField: "After3"},
  3410  			{InnerField: "After4"},
  3411  		},
  3412  	}
  3413  	actual := OuterStruct{
  3414  		PrimitiveField: "aaa",
  3415  		ArrayField:     []int{100, 200, 300, 400},
  3416  		StructField:    InnerStruct{InnerField: "Before1"},
  3417  		MapField: map[string]interface{}{
  3418  			"MapField1": []int{4, 5, 6},
  3419  			"MapField2": map[string]string{
  3420  				"B": "BBB",
  3421  			},
  3422  			"MapField3": true,
  3423  		},
  3424  		PointerField:          &InnerStruct{InnerField: "Before2"},
  3425  		NilField:              nil,
  3426  		InterfacePointerField: &s,
  3427  		StructArrayField: []InnerStruct{
  3428  			{InnerField: "Before3"},
  3429  			{InnerField: "Before4"},
  3430  		},
  3431  	}
  3432  	if err := Unmarshal(toml, &actual); err == nil {
  3433  		if !reflect.DeepEqual(actual, expected) {
  3434  			t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
  3435  		}
  3436  	} else {
  3437  		t.Fatal(err)
  3438  	}
  3439  }
  3440  
  3441  func TestUnmarshalEmbedTree(t *testing.T) {
  3442  	toml := []byte(`
  3443  OuterField1 = "Out"
  3444  OuterField2 = 1024
  3445  
  3446  [TreeField]
  3447  InnerField1 = "In"
  3448  InnerField2 = 2048
  3449  
  3450  	[TreeField.EmbedStruct]
  3451  		EmbedField = "Embed"
  3452  
  3453  `)
  3454  	type InnerStruct struct {
  3455  		InnerField1 string
  3456  		InnerField2 int
  3457  		EmbedStruct struct {
  3458  			EmbedField string
  3459  		}
  3460  	}
  3461  
  3462  	type OuterStruct struct {
  3463  		OuterField1 string
  3464  		OuterField2 int
  3465  		TreeField   *Tree
  3466  	}
  3467  
  3468  	out := OuterStruct{}
  3469  	actual := InnerStruct{}
  3470  	expected := InnerStruct{
  3471  		"In",
  3472  		2048,
  3473  		struct {
  3474  			EmbedField string
  3475  		}{
  3476  			EmbedField: "Embed",
  3477  		},
  3478  	}
  3479  	if err := Unmarshal(toml, &out); err != nil {
  3480  		t.Fatal(err)
  3481  	}
  3482  	if err := out.TreeField.Unmarshal(&actual); err != nil {
  3483  		t.Fatal(err)
  3484  	}
  3485  
  3486  	if !reflect.DeepEqual(actual, expected) {
  3487  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
  3488  	}
  3489  }
  3490  
  3491  func TestMarshalNil(t *testing.T) {
  3492  	if _, err := Marshal(nil); err == nil {
  3493  		t.Errorf("Expected err from nil marshal")
  3494  	}
  3495  	if _, err := Marshal((*struct{})(nil)); err == nil {
  3496  		t.Errorf("Expected err from nil marshal")
  3497  	}
  3498  }
  3499  
  3500  func TestUnmarshalNil(t *testing.T) {
  3501  	if err := Unmarshal([]byte(`whatever = "whatever"`), nil); err == nil {
  3502  		t.Errorf("Expected err from nil marshal")
  3503  	}
  3504  	if err := Unmarshal([]byte(`whatever = "whatever"`), (*struct{})(nil)); err == nil {
  3505  		t.Errorf("Expected err from nil marshal")
  3506  	}
  3507  }
  3508  
  3509  var sliceTomlDemo = []byte(`str_slice = ["Howdy","Hey There"]
  3510  str_slice_ptr= ["Howdy","Hey There"]
  3511  int_slice=[1,2]
  3512  int_slice_ptr=[1,2]
  3513  [[struct_slice]]
  3514  String2="1"
  3515  [[struct_slice]]
  3516  String2="2"
  3517  [[struct_slice_ptr]]
  3518  String2="1"
  3519  [[struct_slice_ptr]]
  3520  String2="2"
  3521  `)
  3522  
  3523  type sliceStruct struct {
  3524  	Slice          []string                     `  toml:"str_slice"  `
  3525  	SlicePtr       *[]string                    `  toml:"str_slice_ptr"  `
  3526  	IntSlice       []int                        `  toml:"int_slice"  `
  3527  	IntSlicePtr    *[]int                       `  toml:"int_slice_ptr"  `
  3528  	StructSlice    []basicMarshalTestSubStruct  `  toml:"struct_slice"  `
  3529  	StructSlicePtr *[]basicMarshalTestSubStruct `  toml:"struct_slice_ptr"  `
  3530  }
  3531  
  3532  type arrayStruct struct {
  3533  	Slice          [4]string                     `  toml:"str_slice"  `
  3534  	SlicePtr       *[4]string                    `  toml:"str_slice_ptr"  `
  3535  	IntSlice       [4]int                        `  toml:"int_slice"  `
  3536  	IntSlicePtr    *[4]int                       `  toml:"int_slice_ptr"  `
  3537  	StructSlice    [4]basicMarshalTestSubStruct  `  toml:"struct_slice"  `
  3538  	StructSlicePtr *[4]basicMarshalTestSubStruct `  toml:"struct_slice_ptr"  `
  3539  }
  3540  
  3541  type arrayTooSmallStruct struct {
  3542  	Slice       [1]string                    `  toml:"str_slice"  `
  3543  	StructSlice [1]basicMarshalTestSubStruct `  toml:"struct_slice"  `
  3544  }
  3545  
  3546  func TestUnmarshalSlice(t *testing.T) {
  3547  	tree, _ := LoadBytes(sliceTomlDemo)
  3548  	tree, _ = TreeFromMap(tree.ToMap())
  3549  
  3550  	var actual sliceStruct
  3551  	err := tree.Unmarshal(&actual)
  3552  	if err != nil {
  3553  		t.Error("shound not err", err)
  3554  	}
  3555  	expected := sliceStruct{
  3556  		Slice:          []string{"Howdy", "Hey There"},
  3557  		SlicePtr:       &[]string{"Howdy", "Hey There"},
  3558  		IntSlice:       []int{1, 2},
  3559  		IntSlicePtr:    &[]int{1, 2},
  3560  		StructSlice:    []basicMarshalTestSubStruct{{"1"}, {"2"}},
  3561  		StructSlicePtr: &[]basicMarshalTestSubStruct{{"1"}, {"2"}},
  3562  	}
  3563  	if !reflect.DeepEqual(actual, expected) {
  3564  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
  3565  	}
  3566  
  3567  }
  3568  
  3569  func TestUnmarshalSliceFail(t *testing.T) {
  3570  	tree, _ := TreeFromMap(map[string]interface{}{
  3571  		"str_slice": []int{1, 2},
  3572  	})
  3573  
  3574  	var actual sliceStruct
  3575  	err := tree.Unmarshal(&actual)
  3576  	if err.Error() != "(0, 0): Can't convert 1(int64) to string" {
  3577  		t.Error("expect err:(0, 0): Can't convert 1(int64) to string but got ", err)
  3578  	}
  3579  }
  3580  
  3581  func TestUnmarshalSliceFail2(t *testing.T) {
  3582  	tree, _ := Load(`str_slice=[1,2]`)
  3583  
  3584  	var actual sliceStruct
  3585  	err := tree.Unmarshal(&actual)
  3586  	if err.Error() != "(1, 1): Can't convert 1(int64) to string" {
  3587  		t.Error("expect err:(1, 1): Can't convert 1(int64) to string but got ", err)
  3588  	}
  3589  
  3590  }
  3591  
  3592  func TestMarshalMixedTypeArray(t *testing.T) {
  3593  	type InnerStruct struct {
  3594  		IntField int
  3595  		StrField string
  3596  	}
  3597  
  3598  	type TestStruct struct {
  3599  		ArrayField []interface{}
  3600  	}
  3601  
  3602  	expected := []byte(`ArrayField = [3.14, 100, true, "hello world", { IntField = 100, StrField = "inner1" }, [{ IntField = 200, StrField = "inner2" }, { IntField = 300, StrField = "inner3" }]]
  3603  `)
  3604  
  3605  	if result, err := Marshal(TestStruct{
  3606  		ArrayField: []interface{}{
  3607  			3.14,
  3608  			100,
  3609  			true,
  3610  			"hello world",
  3611  			InnerStruct{
  3612  				IntField: 100,
  3613  				StrField: "inner1",
  3614  			},
  3615  			[]InnerStruct{
  3616  				{IntField: 200, StrField: "inner2"},
  3617  				{IntField: 300, StrField: "inner3"},
  3618  			},
  3619  		},
  3620  	}); err == nil {
  3621  		if !bytes.Equal(result, expected) {
  3622  			t.Errorf("Bad marshal: expected\n----\n%s\n----\ngot\n----\n%s\n----\n", expected, result)
  3623  		}
  3624  	} else {
  3625  		t.Fatal(err)
  3626  	}
  3627  }
  3628  
  3629  func TestUnmarshalMixedTypeArray(t *testing.T) {
  3630  	type TestStruct struct {
  3631  		ArrayField []interface{}
  3632  	}
  3633  
  3634  	toml := []byte(`ArrayField = [3.14,100,true,"hello world",{Field = "inner1"},[{Field = "inner2"},{Field = "inner3"}]]
  3635  `)
  3636  
  3637  	actual := TestStruct{}
  3638  	expected := TestStruct{
  3639  		ArrayField: []interface{}{
  3640  			3.14,
  3641  			int64(100),
  3642  			true,
  3643  			"hello world",
  3644  			map[string]interface{}{
  3645  				"Field": "inner1",
  3646  			},
  3647  			[]map[string]interface{}{
  3648  				{"Field": "inner2"},
  3649  				{"Field": "inner3"},
  3650  			},
  3651  		},
  3652  	}
  3653  
  3654  	if err := Unmarshal(toml, &actual); err == nil {
  3655  		if !reflect.DeepEqual(actual, expected) {
  3656  			t.Errorf("Bad unmarshal: expected %#v, got %#v", expected, actual)
  3657  		}
  3658  	} else {
  3659  		t.Fatal(err)
  3660  	}
  3661  }
  3662  
  3663  func TestUnmarshalArray(t *testing.T) {
  3664  	var tree *Tree
  3665  	var err error
  3666  
  3667  	tree, _ = LoadBytes(sliceTomlDemo)
  3668  	var actual1 arrayStruct
  3669  	err = tree.Unmarshal(&actual1)
  3670  	if err != nil {
  3671  		t.Error("shound not err", err)
  3672  	}
  3673  
  3674  	tree, _ = TreeFromMap(tree.ToMap())
  3675  	var actual2 arrayStruct
  3676  	err = tree.Unmarshal(&actual2)
  3677  	if err != nil {
  3678  		t.Error("shound not err", err)
  3679  	}
  3680  
  3681  	expected := arrayStruct{
  3682  		Slice:          [4]string{"Howdy", "Hey There"},
  3683  		SlicePtr:       &[4]string{"Howdy", "Hey There"},
  3684  		IntSlice:       [4]int{1, 2},
  3685  		IntSlicePtr:    &[4]int{1, 2},
  3686  		StructSlice:    [4]basicMarshalTestSubStruct{{"1"}, {"2"}},
  3687  		StructSlicePtr: &[4]basicMarshalTestSubStruct{{"1"}, {"2"}},
  3688  	}
  3689  	if !reflect.DeepEqual(actual1, expected) {
  3690  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual1)
  3691  	}
  3692  	if !reflect.DeepEqual(actual2, expected) {
  3693  		t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual2)
  3694  	}
  3695  }
  3696  
  3697  func TestUnmarshalArrayFail(t *testing.T) {
  3698  	tree, _ := TreeFromMap(map[string]interface{}{
  3699  		"str_slice": []string{"Howdy", "Hey There"},
  3700  	})
  3701  
  3702  	var actual arrayTooSmallStruct
  3703  	err := tree.Unmarshal(&actual)
  3704  	if err.Error() != "(0, 0): unmarshal: TOML array length (2) exceeds destination array length (1)" {
  3705  		t.Error("expect err:(0, 0): unmarshal: TOML array length (2) exceeds destination array length (1) but got ", err)
  3706  	}
  3707  }
  3708  
  3709  func TestUnmarshalArrayFail2(t *testing.T) {
  3710  	tree, _ := Load(`str_slice=["Howdy","Hey There"]`)
  3711  
  3712  	var actual arrayTooSmallStruct
  3713  	err := tree.Unmarshal(&actual)
  3714  	if err.Error() != "(1, 1): unmarshal: TOML array length (2) exceeds destination array length (1)" {
  3715  		t.Error("expect err:(1, 1): unmarshal: TOML array length (2) exceeds destination array length (1) but got ", err)
  3716  	}
  3717  }
  3718  
  3719  func TestUnmarshalArrayFail3(t *testing.T) {
  3720  	tree, _ := Load(`[[struct_slice]]
  3721  String2="1"
  3722  [[struct_slice]]
  3723  String2="2"`)
  3724  
  3725  	var actual arrayTooSmallStruct
  3726  	err := tree.Unmarshal(&actual)
  3727  	if err.Error() != "(3, 1): unmarshal: TOML array length (2) exceeds destination array length (1)" {
  3728  		t.Error("expect err:(3, 1): unmarshal: TOML array length (2) exceeds destination array length (1) but got ", err)
  3729  	}
  3730  }
  3731  
  3732  func TestDecoderStrict(t *testing.T) {
  3733  	input := `
  3734  [decoded]
  3735    key = ""
  3736  
  3737  [undecoded]
  3738    key = ""
  3739  
  3740    [undecoded.inner]
  3741  	key = ""
  3742  
  3743    [[undecoded.array]]
  3744  	key = ""
  3745  
  3746    [[undecoded.array]]
  3747  	key = ""
  3748  
  3749  `
  3750  	var doc struct {
  3751  		Decoded struct {
  3752  			Key string
  3753  		}
  3754  	}
  3755  
  3756  	expected := `undecoded keys: ["undecoded.array.0.key" "undecoded.array.1.key" "undecoded.inner.key" "undecoded.key"]`
  3757  
  3758  	err := NewDecoder(bytes.NewReader([]byte(input))).Strict(true).Decode(&doc)
  3759  	if err == nil {
  3760  		t.Error("expected error, got none")
  3761  	} else if err.Error() != expected {
  3762  		t.Errorf("expect err: %s, got: %s", expected, err.Error())
  3763  	}
  3764  
  3765  	if err := NewDecoder(bytes.NewReader([]byte(input))).Decode(&doc); err != nil {
  3766  		t.Errorf("unexpected err: %s", err)
  3767  	}
  3768  
  3769  	var m map[string]interface{}
  3770  	if err := NewDecoder(bytes.NewReader([]byte(input))).Decode(&m); err != nil {
  3771  		t.Errorf("unexpected err: %s", err)
  3772  	}
  3773  }
  3774  
  3775  func TestDecoderStrictValid(t *testing.T) {
  3776  	input := `
  3777  [decoded]
  3778    key = ""
  3779  `
  3780  	var doc struct {
  3781  		Decoded struct {
  3782  			Key string
  3783  		}
  3784  	}
  3785  
  3786  	err := NewDecoder(bytes.NewReader([]byte(input))).Strict(true).Decode(&doc)
  3787  	if err != nil {
  3788  		t.Fatal("unexpected error:", err)
  3789  	}
  3790  }
  3791  
  3792  type docUnmarshalTOML struct {
  3793  	Decoded struct {
  3794  		Key string
  3795  	}
  3796  }
  3797  
  3798  func (d *docUnmarshalTOML) UnmarshalTOML(i interface{}) error {
  3799  	if iMap, ok := i.(map[string]interface{}); !ok {
  3800  		return fmt.Errorf("type assertion error: wants %T, have %T", map[string]interface{}{}, i)
  3801  	} else if key, ok := iMap["key"]; !ok {
  3802  		return fmt.Errorf("key '%s' not in map", "key")
  3803  	} else if keyString, ok := key.(string); !ok {
  3804  		return fmt.Errorf("type assertion error: wants %T, have %T", "", key)
  3805  	} else {
  3806  		d.Decoded.Key = keyString
  3807  	}
  3808  	return nil
  3809  }
  3810  
  3811  func TestDecoderStrictCustomUnmarshal(t *testing.T) {
  3812  	input := `key = "ok"`
  3813  	var doc docUnmarshalTOML
  3814  	err := NewDecoder(bytes.NewReader([]byte(input))).Strict(true).Decode(&doc)
  3815  	if err != nil {
  3816  		t.Fatal("unexpected error:", err)
  3817  	}
  3818  	if doc.Decoded.Key != "ok" {
  3819  		t.Errorf("Bad unmarshal: expected ok, got %v", doc.Decoded.Key)
  3820  	}
  3821  }
  3822  
  3823  type parent struct {
  3824  	Doc        docUnmarshalTOML
  3825  	DocPointer *docUnmarshalTOML
  3826  }
  3827  
  3828  func TestCustomUnmarshal(t *testing.T) {
  3829  	input := `
  3830  [Doc]
  3831      key = "ok1"
  3832  [DocPointer]
  3833      key = "ok2"
  3834  `
  3835  
  3836  	var d parent
  3837  	if err := Unmarshal([]byte(input), &d); err != nil {
  3838  		t.Fatalf("unexpected err: %s", err.Error())
  3839  	}
  3840  	if d.Doc.Decoded.Key != "ok1" {
  3841  		t.Errorf("Bad unmarshal: expected ok, got %v", d.Doc.Decoded.Key)
  3842  	}
  3843  	if d.DocPointer.Decoded.Key != "ok2" {
  3844  		t.Errorf("Bad unmarshal: expected ok, got %v", d.DocPointer.Decoded.Key)
  3845  	}
  3846  }
  3847  
  3848  func TestCustomUnmarshalError(t *testing.T) {
  3849  	input := `
  3850  [Doc]
  3851      key = 1
  3852  [DocPointer]
  3853      key = "ok2"
  3854  `
  3855  
  3856  	expected := "(2, 1): unmarshal toml: type assertion error: wants string, have int64"
  3857  
  3858  	var d parent
  3859  	err := Unmarshal([]byte(input), &d)
  3860  	if err == nil {
  3861  		t.Error("expected error, got none")
  3862  	} else if err.Error() != expected {
  3863  		t.Errorf("expect err: %s, got: %s", expected, err.Error())
  3864  	}
  3865  }
  3866  
  3867  type intWrapper struct {
  3868  	Value int
  3869  }
  3870  
  3871  func (w *intWrapper) UnmarshalText(text []byte) error {
  3872  	var err error
  3873  	if w.Value, err = strconv.Atoi(string(text)); err == nil {
  3874  		return nil
  3875  	}
  3876  	if b, err := strconv.ParseBool(string(text)); err == nil {
  3877  		if b {
  3878  			w.Value = 1
  3879  		}
  3880  		return nil
  3881  	}
  3882  	if f, err := strconv.ParseFloat(string(text), 32); err == nil {
  3883  		w.Value = int(f)
  3884  		return nil
  3885  	}
  3886  	return fmt.Errorf("unsupported: %s", text)
  3887  }
  3888  
  3889  func TestTextUnmarshal(t *testing.T) {
  3890  	var doc struct {
  3891  		UnixTime intWrapper
  3892  		Version  *intWrapper
  3893  
  3894  		Bool  intWrapper
  3895  		Int   intWrapper
  3896  		Float intWrapper
  3897  	}
  3898  
  3899  	input := `
  3900  UnixTime = "12"
  3901  Version = "42"
  3902  Bool = true
  3903  Int = 21
  3904  Float = 2.0
  3905  `
  3906  
  3907  	if err := Unmarshal([]byte(input), &doc); err != nil {
  3908  		t.Fatalf("unexpected err: %s", err.Error())
  3909  	}
  3910  	if doc.UnixTime.Value != 12 {
  3911  		t.Fatalf("expected UnixTime: 12 got: %d", doc.UnixTime.Value)
  3912  	}
  3913  	if doc.Version.Value != 42 {
  3914  		t.Fatalf("expected Version: 42 got: %d", doc.Version.Value)
  3915  	}
  3916  	if doc.Bool.Value != 1 {
  3917  		t.Fatalf("expected Bool: 1 got: %d", doc.Bool.Value)
  3918  	}
  3919  	if doc.Int.Value != 21 {
  3920  		t.Fatalf("expected Int: 21 got: %d", doc.Int.Value)
  3921  	}
  3922  	if doc.Float.Value != 2 {
  3923  		t.Fatalf("expected Float: 2 got: %d", doc.Float.Value)
  3924  	}
  3925  }
  3926  
  3927  func TestTextUnmarshalError(t *testing.T) {
  3928  	var doc struct {
  3929  		Failer intWrapper
  3930  	}
  3931  
  3932  	input := `Failer = "hello"`
  3933  	if err := Unmarshal([]byte(input), &doc); err == nil {
  3934  		t.Fatalf("expected err, got none")
  3935  	}
  3936  }
  3937  
  3938  // issue406
  3939  func TestPreserveNotEmptyField(t *testing.T) {
  3940  	toml := []byte(`Field1 = "ccc"`)
  3941  	type Inner struct {
  3942  		InnerField1 string
  3943  		InnerField2 int
  3944  	}
  3945  	type TestStruct struct {
  3946  		Field1 string
  3947  		Field2 int
  3948  		Field3 Inner
  3949  	}
  3950  
  3951  	actual := TestStruct{
  3952  		"aaa",
  3953  		100,
  3954  		Inner{
  3955  			"bbb",
  3956  			200,
  3957  		},
  3958  	}
  3959  
  3960  	expected := TestStruct{
  3961  		"ccc",
  3962  		100,
  3963  		Inner{
  3964  			"bbb",
  3965  			200,
  3966  		},
  3967  	}
  3968  
  3969  	err := Unmarshal(toml, &actual)
  3970  	if err != nil {
  3971  		t.Fatal(err)
  3972  	}
  3973  
  3974  	if !reflect.DeepEqual(actual, expected) {
  3975  		t.Errorf("Bad unmarshal: expected %+v, got %+v", expected, actual)
  3976  	}
  3977  }
  3978  
  3979  // github issue 432
  3980  func TestUnmarshalEmptyInterface(t *testing.T) {
  3981  	doc := []byte(`User = "pelletier"`)
  3982  
  3983  	var v interface{}
  3984  
  3985  	err := Unmarshal(doc, &v)
  3986  	if err != nil {
  3987  		t.Fatal(err)
  3988  	}
  3989  
  3990  	x, ok := v.(map[string]interface{})
  3991  	if !ok {
  3992  		t.Fatal(err)
  3993  	}
  3994  
  3995  	if x["User"] != "pelletier" {
  3996  		t.Fatalf("expected User=pelletier, but got %v", x)
  3997  	}
  3998  }
  3999  
  4000  func TestUnmarshalEmptyInterfaceDeep(t *testing.T) {
  4001  	doc := []byte(`
  4002  User = "pelletier"
  4003  Age = 99
  4004  
  4005  [foo]
  4006  bar = 42
  4007  `)
  4008  
  4009  	var v interface{}
  4010  
  4011  	err := Unmarshal(doc, &v)
  4012  	if err != nil {
  4013  		t.Fatal(err)
  4014  	}
  4015  
  4016  	x, ok := v.(map[string]interface{})
  4017  	if !ok {
  4018  		t.Fatal(err)
  4019  	}
  4020  
  4021  	expected := map[string]interface{}{
  4022  		"User": "pelletier",
  4023  		"Age":  99,
  4024  		"foo": map[string]interface{}{
  4025  			"bar": 42,
  4026  		},
  4027  	}
  4028  
  4029  	reflect.DeepEqual(x, expected)
  4030  }
  4031  
  4032  type Config struct {
  4033  	Key string `toml:"key"`
  4034  	Obj Custom `toml:"obj"`
  4035  }
  4036  
  4037  type Custom struct {
  4038  	v string
  4039  }
  4040  
  4041  func (c *Custom) UnmarshalTOML(v interface{}) error {
  4042  	c.v = "called"
  4043  	return nil
  4044  }
  4045  
  4046  func TestGithubIssue431(t *testing.T) {
  4047  	doc := `key = "value"`
  4048  	tree, err := LoadBytes([]byte(doc))
  4049  	if err != nil {
  4050  		t.Fatalf("unexpected error: %s", err)
  4051  	}
  4052  
  4053  	var c Config
  4054  	if err := tree.Unmarshal(&c); err != nil {
  4055  		t.Fatalf("unexpected error: %s", err)
  4056  	}
  4057  
  4058  	if c.Key != "value" {
  4059  		t.Errorf("expected c.Key='value', not '%s'", c.Key)
  4060  	}
  4061  
  4062  	if c.Obj.v == "called" {
  4063  		t.Errorf("UnmarshalTOML should not have been called")
  4064  	}
  4065  }
  4066  
  4067  type durationString struct {
  4068  	time.Duration
  4069  }
  4070  
  4071  func (d *durationString) UnmarshalTOML(v interface{}) error {
  4072  	d.Duration = 10 * time.Second
  4073  	return nil
  4074  }
  4075  
  4076  type config437Error struct {
  4077  }
  4078  
  4079  func (e *config437Error) UnmarshalTOML(v interface{}) error {
  4080  	return errors.New("expected")
  4081  }
  4082  
  4083  type config437 struct {
  4084  	HTTP struct {
  4085  		PingTimeout durationString `toml:"PingTimeout"`
  4086  		ErrorField  config437Error
  4087  	} `toml:"HTTP"`
  4088  }
  4089  
  4090  func TestGithubIssue437(t *testing.T) {
  4091  	src := `
  4092  [HTTP]
  4093  PingTimeout = "32m"
  4094  `
  4095  	cfg := &config437{}
  4096  	cfg.HTTP.PingTimeout = durationString{time.Second}
  4097  
  4098  	r := strings.NewReader(src)
  4099  	err := NewDecoder(r).Decode(cfg)
  4100  	if err != nil {
  4101  		t.Fatalf("unexpected errors %s", err)
  4102  	}
  4103  	expected := durationString{10 * time.Second}
  4104  	if cfg.HTTP.PingTimeout != expected {
  4105  		t.Fatalf("expected '%s', got '%s'", expected, cfg.HTTP.PingTimeout)
  4106  	}
  4107  }
  4108  
  4109  func TestLeafUnmarshalerError(t *testing.T) {
  4110  	src := `
  4111  [HTTP]
  4112  ErrorField = "foo"
  4113  `
  4114  	cfg := &config437{}
  4115  
  4116  	r := strings.NewReader(src)
  4117  	err := NewDecoder(r).Decode(cfg)
  4118  	if err == nil {
  4119  		t.Fatalf("error was expected")
  4120  	}
  4121  }
  4122  
  4123  func TestGithubIssue732(t *testing.T) {
  4124  	var v interface{}
  4125  	data := []byte("a=\nb=0")
  4126  
  4127  	err := Unmarshal(data, &v)
  4128  	if err == nil {
  4129  		t.Fatalf("error was expected")
  4130  	}
  4131  }
  4132  

View as plain text