Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / github.com / !burnt!sushi / toml@v0.3.1 / encode_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/!burnt!sushi/toml@v0.3.1/encode_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/github.com/!burnt!sushi/toml@v0.3.1/encode_test.go
new file mode 100644 (file)
index 0000000..673b7b0
--- /dev/null
@@ -0,0 +1,615 @@
+package toml
+
+import (
+       "bytes"
+       "fmt"
+       "log"
+       "net"
+       "testing"
+       "time"
+)
+
+func TestEncodeRoundTrip(t *testing.T) {
+       type Config struct {
+               Age        int
+               Cats       []string
+               Pi         float64
+               Perfection []int
+               DOB        time.Time
+               Ipaddress  net.IP
+       }
+
+       var inputs = Config{
+               13,
+               []string{"one", "two", "three"},
+               3.145,
+               []int{11, 2, 3, 4},
+               time.Now(),
+               net.ParseIP("192.168.59.254"),
+       }
+
+       var firstBuffer bytes.Buffer
+       e := NewEncoder(&firstBuffer)
+       err := e.Encode(inputs)
+       if err != nil {
+               t.Fatal(err)
+       }
+       var outputs Config
+       if _, err := Decode(firstBuffer.String(), &outputs); err != nil {
+               t.Logf("Could not decode:\n-----\n%s\n-----\n",
+                       firstBuffer.String())
+               t.Fatal(err)
+       }
+
+       // could test each value individually, but I'm lazy
+       var secondBuffer bytes.Buffer
+       e2 := NewEncoder(&secondBuffer)
+       err = e2.Encode(outputs)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if firstBuffer.String() != secondBuffer.String() {
+               t.Error(
+                       firstBuffer.String(),
+                       "\n\n is not identical to\n\n",
+                       secondBuffer.String())
+       }
+}
+
+// XXX(burntsushi)
+// I think these tests probably should be removed. They are good, but they
+// ought to be obsolete by toml-test.
+func TestEncode(t *testing.T) {
+       type Embedded struct {
+               Int int `toml:"_int"`
+       }
+       type NonStruct int
+
+       date := time.Date(2014, 5, 11, 20, 30, 40, 0, time.FixedZone("IST", 3600))
+       dateStr := "2014-05-11T19:30:40Z"
+
+       tests := map[string]struct {
+               input      interface{}
+               wantOutput string
+               wantError  error
+       }{
+               "bool field": {
+                       input: struct {
+                               BoolTrue  bool
+                               BoolFalse bool
+                       }{true, false},
+                       wantOutput: "BoolTrue = true\nBoolFalse = false\n",
+               },
+               "int fields": {
+                       input: struct {
+                               Int   int
+                               Int8  int8
+                               Int16 int16
+                               Int32 int32
+                               Int64 int64
+                       }{1, 2, 3, 4, 5},
+                       wantOutput: "Int = 1\nInt8 = 2\nInt16 = 3\nInt32 = 4\nInt64 = 5\n",
+               },
+               "uint fields": {
+                       input: struct {
+                               Uint   uint
+                               Uint8  uint8
+                               Uint16 uint16
+                               Uint32 uint32
+                               Uint64 uint64
+                       }{1, 2, 3, 4, 5},
+                       wantOutput: "Uint = 1\nUint8 = 2\nUint16 = 3\nUint32 = 4" +
+                               "\nUint64 = 5\n",
+               },
+               "float fields": {
+                       input: struct {
+                               Float32 float32
+                               Float64 float64
+                       }{1.5, 2.5},
+                       wantOutput: "Float32 = 1.5\nFloat64 = 2.5\n",
+               },
+               "string field": {
+                       input:      struct{ String string }{"foo"},
+                       wantOutput: "String = \"foo\"\n",
+               },
+               "string field and unexported field": {
+                       input: struct {
+                               String     string
+                               unexported int
+                       }{"foo", 0},
+                       wantOutput: "String = \"foo\"\n",
+               },
+               "datetime field in UTC": {
+                       input:      struct{ Date time.Time }{date},
+                       wantOutput: fmt.Sprintf("Date = %s\n", dateStr),
+               },
+               "datetime field as primitive": {
+                       // Using a map here to fail if isStructOrMap() returns true for
+                       // time.Time.
+                       input: map[string]interface{}{
+                               "Date": date,
+                               "Int":  1,
+                       },
+                       wantOutput: fmt.Sprintf("Date = %s\nInt = 1\n", dateStr),
+               },
+               "array fields": {
+                       input: struct {
+                               IntArray0 [0]int
+                               IntArray3 [3]int
+                       }{[0]int{}, [3]int{1, 2, 3}},
+                       wantOutput: "IntArray0 = []\nIntArray3 = [1, 2, 3]\n",
+               },
+               "slice fields": {
+                       input: struct{ IntSliceNil, IntSlice0, IntSlice3 []int }{
+                               nil, []int{}, []int{1, 2, 3},
+                       },
+                       wantOutput: "IntSlice0 = []\nIntSlice3 = [1, 2, 3]\n",
+               },
+               "datetime slices": {
+                       input: struct{ DatetimeSlice []time.Time }{
+                               []time.Time{date, date},
+                       },
+                       wantOutput: fmt.Sprintf("DatetimeSlice = [%s, %s]\n",
+                               dateStr, dateStr),
+               },
+               "nested arrays and slices": {
+                       input: struct {
+                               SliceOfArrays         [][2]int
+                               ArrayOfSlices         [2][]int
+                               SliceOfArraysOfSlices [][2][]int
+                               ArrayOfSlicesOfArrays [2][][2]int
+                               SliceOfMixedArrays    [][2]interface{}
+                               ArrayOfMixedSlices    [2][]interface{}
+                       }{
+                               [][2]int{{1, 2}, {3, 4}},
+                               [2][]int{{1, 2}, {3, 4}},
+                               [][2][]int{
+                                       {
+                                               {1, 2}, {3, 4},
+                                       },
+                                       {
+                                               {5, 6}, {7, 8},
+                                       },
+                               },
+                               [2][][2]int{
+                                       {
+                                               {1, 2}, {3, 4},
+                                       },
+                                       {
+                                               {5, 6}, {7, 8},
+                                       },
+                               },
+                               [][2]interface{}{
+                                       {1, 2}, {"a", "b"},
+                               },
+                               [2][]interface{}{
+                                       {1, 2}, {"a", "b"},
+                               },
+                       },
+                       wantOutput: `SliceOfArrays = [[1, 2], [3, 4]]
+ArrayOfSlices = [[1, 2], [3, 4]]
+SliceOfArraysOfSlices = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
+ArrayOfSlicesOfArrays = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
+SliceOfMixedArrays = [[1, 2], ["a", "b"]]
+ArrayOfMixedSlices = [[1, 2], ["a", "b"]]
+`,
+               },
+               "empty slice": {
+                       input:      struct{ Empty []interface{} }{[]interface{}{}},
+                       wantOutput: "Empty = []\n",
+               },
+               "(error) slice with element type mismatch (string and integer)": {
+                       input:     struct{ Mixed []interface{} }{[]interface{}{1, "a"}},
+                       wantError: errArrayMixedElementTypes,
+               },
+               "(error) slice with element type mismatch (integer and float)": {
+                       input:     struct{ Mixed []interface{} }{[]interface{}{1, 2.5}},
+                       wantError: errArrayMixedElementTypes,
+               },
+               "slice with elems of differing Go types, same TOML types": {
+                       input: struct {
+                               MixedInts   []interface{}
+                               MixedFloats []interface{}
+                       }{
+                               []interface{}{
+                                       int(1), int8(2), int16(3), int32(4), int64(5),
+                                       uint(1), uint8(2), uint16(3), uint32(4), uint64(5),
+                               },
+                               []interface{}{float32(1.5), float64(2.5)},
+                       },
+                       wantOutput: "MixedInts = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]\n" +
+                               "MixedFloats = [1.5, 2.5]\n",
+               },
+               "(error) slice w/ element type mismatch (one is nested array)": {
+                       input: struct{ Mixed []interface{} }{
+                               []interface{}{1, []interface{}{2}},
+                       },
+                       wantError: errArrayMixedElementTypes,
+               },
+               "(error) slice with 1 nil element": {
+                       input:     struct{ NilElement1 []interface{} }{[]interface{}{nil}},
+                       wantError: errArrayNilElement,
+               },
+               "(error) slice with 1 nil element (and other non-nil elements)": {
+                       input: struct{ NilElement []interface{} }{
+                               []interface{}{1, nil},
+                       },
+                       wantError: errArrayNilElement,
+               },
+               "simple map": {
+                       input:      map[string]int{"a": 1, "b": 2},
+                       wantOutput: "a = 1\nb = 2\n",
+               },
+               "map with interface{} value type": {
+                       input:      map[string]interface{}{"a": 1, "b": "c"},
+                       wantOutput: "a = 1\nb = \"c\"\n",
+               },
+               "map with interface{} value type, some of which are structs": {
+                       input: map[string]interface{}{
+                               "a": struct{ Int int }{2},
+                               "b": 1,
+                       },
+                       wantOutput: "b = 1\n\n[a]\n  Int = 2\n",
+               },
+               "nested map": {
+                       input: map[string]map[string]int{
+                               "a": {"b": 1},
+                               "c": {"d": 2},
+                       },
+                       wantOutput: "[a]\n  b = 1\n\n[c]\n  d = 2\n",
+               },
+               "nested struct": {
+                       input: struct{ Struct struct{ Int int } }{
+                               struct{ Int int }{1},
+                       },
+                       wantOutput: "[Struct]\n  Int = 1\n",
+               },
+               "nested struct and non-struct field": {
+                       input: struct {
+                               Struct struct{ Int int }
+                               Bool   bool
+                       }{struct{ Int int }{1}, true},
+                       wantOutput: "Bool = true\n\n[Struct]\n  Int = 1\n",
+               },
+               "2 nested structs": {
+                       input: struct{ Struct1, Struct2 struct{ Int int } }{
+                               struct{ Int int }{1}, struct{ Int int }{2},
+                       },
+                       wantOutput: "[Struct1]\n  Int = 1\n\n[Struct2]\n  Int = 2\n",
+               },
+               "deeply nested structs": {
+                       input: struct {
+                               Struct1, Struct2 struct{ Struct3 *struct{ Int int } }
+                       }{
+                               struct{ Struct3 *struct{ Int int } }{&struct{ Int int }{1}},
+                               struct{ Struct3 *struct{ Int int } }{nil},
+                       },
+                       wantOutput: "[Struct1]\n  [Struct1.Struct3]\n    Int = 1" +
+                               "\n\n[Struct2]\n",
+               },
+               "nested struct with nil struct elem": {
+                       input: struct {
+                               Struct struct{ Inner *struct{ Int int } }
+                       }{
+                               struct{ Inner *struct{ Int int } }{nil},
+                       },
+                       wantOutput: "[Struct]\n",
+               },
+               "nested struct with no fields": {
+                       input: struct {
+                               Struct struct{ Inner struct{} }
+                       }{
+                               struct{ Inner struct{} }{struct{}{}},
+                       },
+                       wantOutput: "[Struct]\n  [Struct.Inner]\n",
+               },
+               "struct with tags": {
+                       input: struct {
+                               Struct struct {
+                                       Int int `toml:"_int"`
+                               } `toml:"_struct"`
+                               Bool bool `toml:"_bool"`
+                       }{
+                               struct {
+                                       Int int `toml:"_int"`
+                               }{1}, true,
+                       },
+                       wantOutput: "_bool = true\n\n[_struct]\n  _int = 1\n",
+               },
+               "embedded struct": {
+                       input:      struct{ Embedded }{Embedded{1}},
+                       wantOutput: "_int = 1\n",
+               },
+               "embedded *struct": {
+                       input:      struct{ *Embedded }{&Embedded{1}},
+                       wantOutput: "_int = 1\n",
+               },
+               "nested embedded struct": {
+                       input: struct {
+                               Struct struct{ Embedded } `toml:"_struct"`
+                       }{struct{ Embedded }{Embedded{1}}},
+                       wantOutput: "[_struct]\n  _int = 1\n",
+               },
+               "nested embedded *struct": {
+                       input: struct {
+                               Struct struct{ *Embedded } `toml:"_struct"`
+                       }{struct{ *Embedded }{&Embedded{1}}},
+                       wantOutput: "[_struct]\n  _int = 1\n",
+               },
+               "embedded non-struct": {
+                       input:      struct{ NonStruct }{5},
+                       wantOutput: "NonStruct = 5\n",
+               },
+               "array of tables": {
+                       input: struct {
+                               Structs []*struct{ Int int } `toml:"struct"`
+                       }{
+                               []*struct{ Int int }{{1}, {3}},
+                       },
+                       wantOutput: "[[struct]]\n  Int = 1\n\n[[struct]]\n  Int = 3\n",
+               },
+               "array of tables order": {
+                       input: map[string]interface{}{
+                               "map": map[string]interface{}{
+                                       "zero": 5,
+                                       "arr": []map[string]int{
+                                               {
+                                                       "friend": 5,
+                                               },
+                                       },
+                               },
+                       },
+                       wantOutput: "[map]\n  zero = 5\n\n  [[map.arr]]\n    friend = 5\n",
+               },
+               "(error) top-level slice": {
+                       input:     []struct{ Int int }{{1}, {2}, {3}},
+                       wantError: errNoKey,
+               },
+               "(error) slice of slice": {
+                       input: struct {
+                               Slices [][]struct{ Int int }
+                       }{
+                               [][]struct{ Int int }{{{1}}, {{2}}, {{3}}},
+                       },
+                       wantError: errArrayNoTable,
+               },
+               "(error) map no string key": {
+                       input:     map[int]string{1: ""},
+                       wantError: errNonString,
+               },
+               "(error) empty key name": {
+                       input:     map[string]int{"": 1},
+                       wantError: errAnything,
+               },
+               "(error) empty map name": {
+                       input: map[string]interface{}{
+                               "": map[string]int{"v": 1},
+                       },
+                       wantError: errAnything,
+               },
+       }
+       for label, test := range tests {
+               encodeExpected(t, label, test.input, test.wantOutput, test.wantError)
+       }
+}
+
+func TestEncodeNestedTableArrays(t *testing.T) {
+       type song struct {
+               Name string `toml:"name"`
+       }
+       type album struct {
+               Name  string `toml:"name"`
+               Songs []song `toml:"songs"`
+       }
+       type springsteen struct {
+               Albums []album `toml:"albums"`
+       }
+       value := springsteen{
+               []album{
+                       {"Born to Run",
+                               []song{{"Jungleland"}, {"Meeting Across the River"}}},
+                       {"Born in the USA",
+                               []song{{"Glory Days"}, {"Dancing in the Dark"}}},
+               },
+       }
+       expected := `[[albums]]
+  name = "Born to Run"
+
+  [[albums.songs]]
+    name = "Jungleland"
+
+  [[albums.songs]]
+    name = "Meeting Across the River"
+
+[[albums]]
+  name = "Born in the USA"
+
+  [[albums.songs]]
+    name = "Glory Days"
+
+  [[albums.songs]]
+    name = "Dancing in the Dark"
+`
+       encodeExpected(t, "nested table arrays", value, expected, nil)
+}
+
+func TestEncodeArrayHashWithNormalHashOrder(t *testing.T) {
+       type Alpha struct {
+               V int
+       }
+       type Beta struct {
+               V int
+       }
+       type Conf struct {
+               V int
+               A Alpha
+               B []Beta
+       }
+
+       val := Conf{
+               V: 1,
+               A: Alpha{2},
+               B: []Beta{{3}},
+       }
+       expected := "V = 1\n\n[A]\n  V = 2\n\n[[B]]\n  V = 3\n"
+       encodeExpected(t, "array hash with normal hash order", val, expected, nil)
+}
+
+func TestEncodeWithOmitEmpty(t *testing.T) {
+       type simple struct {
+               Bool   bool              `toml:"bool,omitempty"`
+               String string            `toml:"string,omitempty"`
+               Array  [0]byte           `toml:"array,omitempty"`
+               Slice  []int             `toml:"slice,omitempty"`
+               Map    map[string]string `toml:"map,omitempty"`
+       }
+
+       var v simple
+       encodeExpected(t, "fields with omitempty are omitted when empty", v, "", nil)
+       v = simple{
+               Bool:   true,
+               String: " ",
+               Slice:  []int{2, 3, 4},
+               Map:    map[string]string{"foo": "bar"},
+       }
+       expected := `bool = true
+string = " "
+slice = [2, 3, 4]
+
+[map]
+  foo = "bar"
+`
+       encodeExpected(t, "fields with omitempty are not omitted when non-empty",
+               v, expected, nil)
+}
+
+func TestEncodeWithOmitZero(t *testing.T) {
+       type simple struct {
+               Number   int     `toml:"number,omitzero"`
+               Real     float64 `toml:"real,omitzero"`
+               Unsigned uint    `toml:"unsigned,omitzero"`
+       }
+
+       value := simple{0, 0.0, uint(0)}
+       expected := ""
+
+       encodeExpected(t, "simple with omitzero, all zero", value, expected, nil)
+
+       value.Number = 10
+       value.Real = 20
+       value.Unsigned = 5
+       expected = `number = 10
+real = 20.0
+unsigned = 5
+`
+       encodeExpected(t, "simple with omitzero, non-zero", value, expected, nil)
+}
+
+func TestEncodeOmitemptyWithEmptyName(t *testing.T) {
+       type simple struct {
+               S []int `toml:",omitempty"`
+       }
+       v := simple{[]int{1, 2, 3}}
+       expected := "S = [1, 2, 3]\n"
+       encodeExpected(t, "simple with omitempty, no name, non-empty field",
+               v, expected, nil)
+}
+
+func TestEncodeAnonymousStruct(t *testing.T) {
+       type Inner struct{ N int }
+       type Outer0 struct{ Inner }
+       type Outer1 struct {
+               Inner `toml:"inner"`
+       }
+
+       v0 := Outer0{Inner{3}}
+       expected := "N = 3\n"
+       encodeExpected(t, "embedded anonymous untagged struct", v0, expected, nil)
+
+       v1 := Outer1{Inner{3}}
+       expected = "[inner]\n  N = 3\n"
+       encodeExpected(t, "embedded anonymous tagged struct", v1, expected, nil)
+}
+
+func TestEncodeAnonymousStructPointerField(t *testing.T) {
+       type Inner struct{ N int }
+       type Outer0 struct{ *Inner }
+       type Outer1 struct {
+               *Inner `toml:"inner"`
+       }
+
+       v0 := Outer0{}
+       expected := ""
+       encodeExpected(t, "nil anonymous untagged struct pointer field", v0, expected, nil)
+
+       v0 = Outer0{&Inner{3}}
+       expected = "N = 3\n"
+       encodeExpected(t, "non-nil anonymous untagged struct pointer field", v0, expected, nil)
+
+       v1 := Outer1{}
+       expected = ""
+       encodeExpected(t, "nil anonymous tagged struct pointer field", v1, expected, nil)
+
+       v1 = Outer1{&Inner{3}}
+       expected = "[inner]\n  N = 3\n"
+       encodeExpected(t, "non-nil anonymous tagged struct pointer field", v1, expected, nil)
+}
+
+func TestEncodeIgnoredFields(t *testing.T) {
+       type simple struct {
+               Number int `toml:"-"`
+       }
+       value := simple{}
+       expected := ""
+       encodeExpected(t, "ignored field", value, expected, nil)
+}
+
+func encodeExpected(
+       t *testing.T, label string, val interface{}, wantStr string, wantErr error,
+) {
+       var buf bytes.Buffer
+       enc := NewEncoder(&buf)
+       err := enc.Encode(val)
+       if err != wantErr {
+               if wantErr != nil {
+                       if wantErr == errAnything && err != nil {
+                               return
+                       }
+                       t.Errorf("%s: want Encode error %v, got %v", label, wantErr, err)
+               } else {
+                       t.Errorf("%s: Encode failed: %s", label, err)
+               }
+       }
+       if err != nil {
+               return
+       }
+       if got := buf.String(); wantStr != got {
+               t.Errorf("%s: want\n-----\n%q\n-----\nbut got\n-----\n%q\n-----\n",
+                       label, wantStr, got)
+       }
+}
+
+func ExampleEncoder_Encode() {
+       date, _ := time.Parse(time.RFC822, "14 Mar 10 18:00 UTC")
+       var config = map[string]interface{}{
+               "date":   date,
+               "counts": []int{1, 1, 2, 3, 5, 8},
+               "hash": map[string]string{
+                       "key1": "val1",
+                       "key2": "val2",
+               },
+       }
+       buf := new(bytes.Buffer)
+       if err := NewEncoder(buf).Encode(config); err != nil {
+               log.Fatal(err)
+       }
+       fmt.Println(buf.String())
+
+       // Output:
+       // counts = [1, 1, 2, 3, 5, 8]
+       // date = 2010-03-14T18:00:00Z
+       //
+       // [hash]
+       //   key1 = "val1"
+       //   key2 = "val2"
+}