go-yaml/encode_test.go

409 lines
6.5 KiB
Go
Raw Normal View History

2019-10-19 18:28:36 +09:00
package yaml_test
import (
"bytes"
2019-10-23 21:00:00 +09:00
"fmt"
2019-10-19 18:28:36 +09:00
"math"
"testing"
"github.com/goccy/go-yaml"
)
func TestEncoder(t *testing.T) {
tests := []struct {
source string
value interface{}
}{
{
"null\n",
(*struct{})(nil),
},
{
"v: hi\n",
map[string]string{"v": "hi"},
},
{
"v: \"true\"\n",
map[string]string{"v": "true"},
},
{
"v: \"false\"\n",
map[string]string{"v": "false"},
},
{
"v: true\n",
map[string]interface{}{"v": true},
},
{
"v: false\n",
map[string]bool{"v": false},
},
{
"v: 10\n",
map[string]int{"v": 10},
},
{
"v: -10\n",
map[string]int{"v": -10},
},
{
"v: 4294967296\n",
map[string]int{"v": 4294967296},
},
{
"v: 0.1\n",
map[string]interface{}{"v": 0.1},
},
{
"v: 0.99\n",
map[string]float32{"v": 0.99},
},
{
"v: -0.1\n",
map[string]float64{"v": -0.1},
},
{
"v: 1.0\n",
map[string]float64{"v": 1.0},
},
{
"v: .inf\n",
map[string]interface{}{"v": math.Inf(0)},
},
{
"v: -.inf\n",
map[string]interface{}{"v": math.Inf(-1)},
},
{
"v: .nan\n",
map[string]interface{}{"v": math.NaN()},
},
{
"v: null\n",
map[string]interface{}{"v": nil},
},
{
"v: \"\"\n",
map[string]string{"v": ""},
},
{
"v:\n- A\n- B\n",
2019-10-21 01:28:48 +09:00
map[string][]string{"v": {"A", "B"}},
2019-10-19 18:28:36 +09:00
},
{
"a: -\n",
map[string]string{"a": "-"},
},
{
"123\n",
123,
},
{
"hello: world\n",
map[string]string{"hello": "world"},
},
{
"v:\n- A\n- 1\n- B:\n - 2\n - 3\n",
map[string]interface{}{
"v": []interface{}{
"A",
1,
map[string][]int{
2019-10-21 01:28:48 +09:00
"B": {2, 3},
2019-10-19 18:28:36 +09:00
},
},
},
},
{
"a:\n b: c\n",
map[string]interface{}{
"a": map[string]string{
"b": "c",
},
},
},
{
"t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n",
map[string]string{
"t2": "2018-01-09T10:40:47Z",
"t4": "2098-01-09T10:40:47Z",
},
},
{
"a:\n b: c\n d: e\n",
map[string]interface{}{
"a": map[string]string{
"b": "c",
"d": "e",
},
},
},
{
"a: 3s\n",
map[string]string{
"a": "3s",
},
},
{
"a: <foo>\n",
map[string]string{"a": "<foo>"},
},
{
"a: \"1:1\"\n",
map[string]string{"a": "1:1"},
},
{
"a: 1.2.3.4\n",
map[string]string{"a": "1.2.3.4"},
},
{
"a: \"b: c\"\n",
map[string]string{"a": "b: c"},
},
{
"a: \"Hello #comment\"\n",
map[string]string{"a": "Hello #comment"},
},
{
"a: 100.5\n",
map[string]interface{}{
"a": 100.5,
},
},
{
"a: \"\\\\0\"\n",
map[string]string{"a": "\\0"},
},
{
"a: 1\nb: 2\nc: 3\nd: 4\nsub:\n e: 5\n",
map[string]interface{}{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"sub": map[string]int{
"e": 5,
},
},
},
{
"a: b\nc: d\n",
struct {
A string
C string `yaml:"c"`
}{
"b", "d",
},
},
{
"a: 1\n",
struct {
A int
B int `yaml:"-"`
}{
1, 0,
},
},
}
for _, test := range tests {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
if err := enc.Encode(test.value); err != nil {
t.Fatalf("%+v", err)
}
if test.source != buf.String() {
t.Fatalf("expect = [%s], actual = [%s]", test.source, buf.String())
}
}
}
2019-10-19 22:01:36 +09:00
func TestEncodeWithAnchorAndAlias(t *testing.T) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
type T struct {
A int
B string
}
var v struct {
A *T `yaml:"a,anchor=c"`
B *T `yaml:"b,alias=c"`
}
v.A = &T{A: 1, B: "hello"}
v.B = v.A
if err := enc.Encode(v); err != nil {
t.Fatalf("%+v", err)
}
expect := "a: &c\n a: 1\n b: hello\nb: *c\n"
if expect != buf.String() {
t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String())
}
}
2019-10-20 13:05:03 +09:00
func TestEncodeWithAutoAlias(t *testing.T) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
type T struct {
I int
S string
}
var v struct {
A *T `yaml:"a,anchor=a"`
B *T `yaml:"b,anchor=b"`
C *T `yaml:"c,alias"`
D *T `yaml:"d,alias"`
}
v.A = &T{I: 1, S: "hello"}
v.B = &T{I: 2, S: "world"}
v.C = v.A
v.D = v.B
if err := enc.Encode(v); err != nil {
t.Fatalf("%+v", err)
}
expect := `a: &a
i: 1
s: hello
b: &b
i: 2
s: world
c: *a
d: *b
`
if expect != buf.String() {
t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String())
}
}
func TestEncodeWithImplicitAnchorAndAlias(t *testing.T) {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
type T struct {
I int
S string
}
var v struct {
A *T `yaml:"a,anchor"`
B *T `yaml:"b,anchor"`
C *T `yaml:"c,alias"`
D *T `yaml:"d,alias"`
}
v.A = &T{I: 1, S: "hello"}
v.B = &T{I: 2, S: "world"}
v.C = v.A
v.D = v.B
if err := enc.Encode(v); err != nil {
t.Fatalf("%+v", err)
}
expect := `a: &a
i: 1
s: hello
b: &b
i: 2
s: world
c: *a
d: *b
`
if expect != buf.String() {
t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String())
}
}
func TestEncodeWithMerge(t *testing.T) {
type Person struct {
*Person `yaml:",omitempty,inline,alias"`
Name string `yaml:",omitempty"`
Age int `yaml:",omitempty"`
}
defaultPerson := &Person{
Name: "John Smith",
Age: 20,
}
people := []*Person{
{
Person: defaultPerson,
Name: "Ken",
Age: 10,
},
{
Person: defaultPerson,
},
}
var doc struct {
Default *Person `yaml:"default,anchor"`
People []*Person `yaml:"people"`
}
doc.Default = defaultPerson
doc.People = people
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
if err := enc.Encode(doc); err != nil {
t.Fatalf("%+v", err)
}
expect := `default: &default
name: John Smith
age: 20
people:
- <<: *default
name: Ken
age: 10
- <<: *default
`
if expect != buf.String() {
t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String())
}
}
2019-10-23 21:00:00 +09:00
func Example_Marshal_ExplicitAnchorAlias() {
type T struct {
A int
B string
}
var v struct {
C *T `yaml:"c,anchor=x"`
D *T `yaml:"d,alias=x"`
}
v.C = &T{A: 1, B: "hello"}
v.D = v.C
bytes, err := yaml.Marshal(v)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
// OUTPUT:
//c: &x
// a: 1
// b: hello
//d: *x
}
func Example_Marshal_ImplicitAnchorAlias() {
type T struct {
I int
S string
}
var v struct {
A *T `yaml:"a,anchor"`
B *T `yaml:"b,anchor"`
C *T `yaml:"c,alias"`
D *T `yaml:"d,alias"`
}
v.A = &T{I: 1, S: "hello"}
v.B = &T{I: 2, S: "world"}
v.C = v.A // C has same pointer address to A
v.D = v.B // D has same pointer address to B
bytes, err := yaml.Marshal(v)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
// OUTPUT:
2019-10-23 21:05:41 +09:00
// a: &a
// i: 1
// s: hello
// b: &b
// i: 2
// s: world
// c: *a
// d: *b
2019-10-23 21:00:00 +09:00
}