Option to keep fields ordered when marshal struct (#266)

Adds a new `Order()` option to preserve order of struct fields when
marshaling.
This commit is contained in:
Brent DeSpain
2019-04-02 10:47:51 -06:00
committed by Thomas Pelletier
parent f9070d3b40
commit 63909f0a90
5 changed files with 335 additions and 143 deletions
+67 -18
View File
@@ -12,10 +12,10 @@ import (
)
type basicMarshalTestStruct struct {
String string `toml:"string"`
StringList []string `toml:"strlist"`
Sub basicMarshalTestSubStruct `toml:"subdoc"`
SubList []basicMarshalTestSubStruct `toml:"sublist"`
String string `toml:"Zstring"`
StringList []string `toml:"Ystrlist"`
Sub basicMarshalTestSubStruct `toml:"Xsubdoc"`
SubList []basicMarshalTestSubStruct `toml:"Wsublist"`
}
type basicMarshalTestSubStruct struct {
@@ -29,16 +29,29 @@ var basicTestData = basicMarshalTestStruct{
SubList: []basicMarshalTestSubStruct{{"Two"}, {"Three"}},
}
var basicTestToml = []byte(`string = "Hello"
strlist = ["Howdy","Hey There"]
var basicTestToml = []byte(`Ystrlist = ["Howdy","Hey There"]
Zstring = "Hello"
[subdoc]
String2 = "One"
[[sublist]]
[[Wsublist]]
String2 = "Two"
[[sublist]]
[[Wsublist]]
String2 = "Three"
[Xsubdoc]
String2 = "One"
`)
var basicTestTomlOrdered = []byte(`Zstring = "Hello"
Ystrlist = ["Howdy","Hey There"]
[Xsubdoc]
String2 = "One"
[[Wsublist]]
String2 = "Two"
[[Wsublist]]
String2 = "Three"
`)
@@ -53,6 +66,18 @@ func TestBasicMarshal(t *testing.T) {
}
}
func TestBasicMarshalOrdered(t *testing.T) {
var result bytes.Buffer
err := NewEncoder(&result).Order(OrderPreserve).Encode(basicTestData)
if err != nil {
t.Fatal(err)
}
expected := basicTestTomlOrdered
if !bytes.Equal(result.Bytes(), expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
}
}
func TestBasicMarshalWithPointer(t *testing.T) {
result, err := Marshal(&basicTestData)
if err != nil {
@@ -64,6 +89,18 @@ func TestBasicMarshalWithPointer(t *testing.T) {
}
}
func TestBasicMarshalOrderedWithPointer(t *testing.T) {
var result bytes.Buffer
err := NewEncoder(&result).Order(OrderPreserve).Encode(&basicTestData)
if err != nil {
t.Fatal(err)
}
expected := basicTestTomlOrdered
if !bytes.Equal(result.Bytes(), expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
}
}
func TestBasicUnmarshal(t *testing.T) {
result := basicMarshalTestStruct{}
err := Unmarshal(basicTestToml, &result)
@@ -78,39 +115,39 @@ func TestBasicUnmarshal(t *testing.T) {
type testDoc struct {
Title string `toml:"title"`
Basics testDocBasics `toml:"basic"`
BasicLists testDocBasicLists `toml:"basic_lists"`
SubDocPtrs []*testSubDoc `toml:"subdocptrs"`
BasicMap map[string]string `toml:"basic_map"`
Subdocs testDocSubs `toml:"subdoc"`
Basics testDocBasics `toml:"basic"`
SubDocList []testSubDoc `toml:"subdoclist"`
SubDocPtrs []*testSubDoc `toml:"subdocptrs"`
err int `toml:"shouldntBeHere"`
unexported int `toml:"shouldntBeHere"`
Unexported2 int `toml:"-"`
}
type testDocBasics struct {
Uint uint `toml:"uint"`
Bool bool `toml:"bool"`
Date time.Time `toml:"date"`
Float float32 `toml:"float"`
Int int `toml:"int"`
Uint uint `toml:"uint"`
String *string `toml:"string"`
Date time.Time `toml:"date"`
unexported int `toml:"shouldntBeHere"`
}
type testDocBasicLists struct {
Floats []*float32 `toml:"floats"`
Bools []bool `toml:"bools"`
Dates []time.Time `toml:"dates"`
Floats []*float32 `toml:"floats"`
Ints []int `toml:"ints"`
Strings []string `toml:"strings"`
UInts []uint `toml:"uints"`
Strings []string `toml:"strings"`
}
type testDocSubs struct {
First testSubDoc `toml:"first"`
Second *testSubDoc `toml:"second"`
First testSubDoc `toml:"first"`
}
type testSubDoc struct {
@@ -174,6 +211,18 @@ func TestDocMarshal(t *testing.T) {
}
}
func TestDocMarshalOrdered(t *testing.T) {
var result bytes.Buffer
err := NewEncoder(&result).Order(OrderPreserve).Encode(docData)
if err != nil {
t.Fatal(err)
}
expected, _ := ioutil.ReadFile("marshal_OrderPreserve_test.toml")
if !bytes.Equal(result.Bytes(), expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result.Bytes())
}
}
func TestDocMarshalPointer(t *testing.T) {
result, err := Marshal(&docData)
if err != nil {