| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | package yaml_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2020-11-12 16:03:42 +09:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2019-10-23 21:00:00 +09:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 	"math" | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2019-11-07 21:14:36 +09:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/goccy/go-yaml" | 
					
						
							| 
									
										
										
										
											2020-01-09 13:33:10 +09:00
										 |  |  | 	"github.com/goccy/go-yaml/ast" | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 11:43:45 +09:00
										 |  |  | var zero = 0 | 
					
						
							|  |  |  | var emptyStr = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 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"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-02-16 16:10:19 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"hello: |\n  hello\n  world\n", | 
					
						
							|  |  |  | 			map[string]string{"hello": "hello\nworld\n"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"hello: |-\n  hello\n  world\n", | 
					
						
							|  |  |  | 			map[string]string{"hello": "hello\nworld"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"hello: |+\n  hello\n  world\n\n", | 
					
						
							|  |  |  | 			map[string]string{"hello": "hello\nworld\n\n"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"hello:\n  hello: |\n    hello\n    world\n", | 
					
						
							|  |  |  | 			map[string]map[string]string{"hello": {"hello": "hello\nworld\n"}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-02-17 21:14:54 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"hello: |\r  hello\r  world\n", | 
					
						
							|  |  |  | 			map[string]string{"hello": "hello\rworld\r"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"hello: |\r\n  hello\r\n  world\n", | 
					
						
							|  |  |  | 			map[string]string{"hello": "hello\r\nworld\r\n"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"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, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-02-14 17:28:54 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 1\nb: []\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A int | 
					
						
							|  |  |  | 				B []string | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				1, ([]string)(nil), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 1\nb: []\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A int | 
					
						
							|  |  |  | 				B []string | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				1, []string{}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-03-07 09:50:32 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A map[string]interface{} | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				map[string]interface{}{}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"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, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-02-22 11:43:45 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a: \"\"\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A string | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: null\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *string | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				nil, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: \"\"\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *string | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				&emptyStr, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: null\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *int | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				nil, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 0\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *int | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				&zero, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Conditional flag | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 1\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A int `yaml:"a,omitempty"` | 
					
						
							|  |  |  | 				B int `yaml:"b,omitempty"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{1, 0}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"{}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A int `yaml:"a,omitempty"` | 
					
						
							|  |  |  | 				B int `yaml:"b,omitempty"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{0, 0}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 21:58:05 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a:\n  y: \"\"\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *struct { | 
					
						
							|  |  |  | 					X string `yaml:"x,omitempty"` | 
					
						
							|  |  |  | 					Y string | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}{&struct { | 
					
						
							|  |  |  | 				X string `yaml:"x,omitempty"` | 
					
						
							|  |  |  | 				Y string | 
					
						
							|  |  |  | 			}{}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A *struct { | 
					
						
							|  |  |  | 					X string `yaml:"x,omitempty"` | 
					
						
							|  |  |  | 					Y string `yaml:"y,omitempty"` | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}{&struct { | 
					
						
							|  |  |  | 				X string `yaml:"x,omitempty"` | 
					
						
							|  |  |  | 				Y string `yaml:"y,omitempty"` | 
					
						
							|  |  |  | 			}{}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {x: 1}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A *struct{ X, y int } `yaml:"a,omitempty,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{&struct{ X, y int }{1, 2}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"{}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A *struct{ X, y int } `yaml:"a,omitempty,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{nil}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {x: 0}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A *struct{ X, y int } `yaml:"a,omitempty,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{&struct{ X, y int }{}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {x: 1}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A struct{ X, y int } `yaml:"a,omitempty,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{struct{ X, y int }{1, 2}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"{}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A struct{ X, y int } `yaml:"a,omitempty,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{struct{ X, y int }{0, 1}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 1.0\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A float64 `yaml:"a,omitempty"` | 
					
						
							|  |  |  | 				B float64 `yaml:"b,omitempty"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{1, 0}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-02-14 17:28:54 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"a: 1\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A int | 
					
						
							|  |  |  | 				B []string `yaml:"b,omitempty"` | 
					
						
							|  |  |  | 			}{ | 
					
						
							|  |  |  | 				1, []string{}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Flow flag | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: [1, 2]\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A []int `yaml:"a,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{[]int{1, 2}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {b: c, d: e}\n", | 
					
						
							|  |  |  | 			&struct { | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				A map[string]string `yaml:"a,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{map[string]string{"b": "c", "d": "e"}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"a: {b: c, d: e}\n", | 
					
						
							|  |  |  | 			struct { | 
					
						
							|  |  |  | 				A struct { | 
					
						
							|  |  |  | 					B, D string | 
					
						
							| 
									
										
										
										
											2019-11-13 12:14:49 +09:00
										 |  |  | 				} `yaml:"a,flow"` | 
					
						
							| 
									
										
										
										
											2019-10-31 13:08:11 +09:00
										 |  |  | 			}{struct{ B, D string }{"c", "e"}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-11-07 17:18:17 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Multi bytes | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-11-07 18:01:45 +09:00
										 |  |  | 			"v: あいうえお\nv2: かきくけこ\n", | 
					
						
							|  |  |  | 			map[string]string{"v": "あいうえお", "v2": "かきくけこ"}, | 
					
						
							| 
									
										
										
										
											2019-11-07 17:18:17 +09:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-11-07 21:14:36 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// time value | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"v: 0001-01-01T00:00:00Z\n", | 
					
						
							|  |  |  | 			map[string]time.Time{"v": time.Time{}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"v: 0001-01-01T00:00:00Z\n", | 
					
						
							|  |  |  | 			map[string]*time.Time{"v": &time.Time{}}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"v: null\n", | 
					
						
							|  |  |  | 			map[string]*time.Time{"v": nil}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-10-19 18:28:36 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 17:38:01 +09:00
										 |  |  | func TestEncodeStructIncludeMap(t *testing.T) { | 
					
						
							|  |  |  | 	type U struct { | 
					
						
							|  |  |  | 		M map[string]string | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	type T struct { | 
					
						
							|  |  |  | 		A U | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	bytes, err := yaml.Marshal(T{ | 
					
						
							|  |  |  | 		A: U{ | 
					
						
							|  |  |  | 			M: map[string]string{"x": "y"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := "a:\n  m:\n    x: y\n" | 
					
						
							|  |  |  | 	actual := string(bytes) | 
					
						
							|  |  |  | 	if actual != expect { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-20 13:31:29 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-20 21:47:06 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-28 22:13:03 +09:00
										 |  |  | func TestEncoder_Inline(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2019-10-28 21:37:12 +09:00
										 |  |  | 	type base struct { | 
					
						
							|  |  |  | 		A int | 
					
						
							|  |  |  | 		B string | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-28 22:13:03 +09:00
										 |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	enc := yaml.NewEncoder(&buf) | 
					
						
							|  |  |  | 	if err := enc.Encode(struct { | 
					
						
							| 
									
										
										
										
											2019-10-28 21:37:12 +09:00
										 |  |  | 		*base `yaml:",inline"` | 
					
						
							|  |  |  | 		C     bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		base: &base{ | 
					
						
							|  |  |  | 			A: 1, | 
					
						
							|  |  |  | 			B: "hello", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		C: true, | 
					
						
							| 
									
										
										
										
											2019-10-28 22:13:03 +09:00
										 |  |  | 	}); err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-28 21:37:12 +09:00
										 |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := ` | 
					
						
							|  |  |  | a: 1 | 
					
						
							|  |  |  | b: hello | 
					
						
							|  |  |  | c: true | 
					
						
							|  |  |  | ` | 
					
						
							| 
									
										
										
										
											2019-10-28 22:13:03 +09:00
										 |  |  | 	actual := "\n" + buf.String() | 
					
						
							| 
									
										
										
										
											2019-10-28 21:37:12 +09:00
										 |  |  | 	if expect != actual { | 
					
						
							|  |  |  | 		t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-28 22:25:00 +09:00
										 |  |  | func TestEncoder_InlineAndConflictKey(t *testing.T) { | 
					
						
							|  |  |  | 	type base struct { | 
					
						
							|  |  |  | 		A int | 
					
						
							|  |  |  | 		B string | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	enc := yaml.NewEncoder(&buf) | 
					
						
							|  |  |  | 	if err := enc.Encode(struct { | 
					
						
							|  |  |  | 		*base `yaml:",inline"` | 
					
						
							|  |  |  | 		A     int // conflict | 
					
						
							|  |  |  | 		C     bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		base: &base{ | 
					
						
							|  |  |  | 			A: 1, | 
					
						
							|  |  |  | 			B: "hello", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		A: 0, // default value | 
					
						
							|  |  |  | 		C: true, | 
					
						
							|  |  |  | 	}); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := ` | 
					
						
							|  |  |  | b: hello | 
					
						
							|  |  |  | a: 0 | 
					
						
							|  |  |  | c: true | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 	actual := "\n" + buf.String() | 
					
						
							|  |  |  | 	if expect != actual { | 
					
						
							|  |  |  | 		t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 13:29:43 +09:00
										 |  |  | func TestEncoder_Flow(t *testing.T) { | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	enc := yaml.NewEncoder(&buf, yaml.Flow(true)) | 
					
						
							|  |  |  | 	var v struct { | 
					
						
							|  |  |  | 		A int | 
					
						
							|  |  |  | 		B string | 
					
						
							|  |  |  | 		C struct { | 
					
						
							|  |  |  | 			D int | 
					
						
							|  |  |  | 			E string | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		F []int | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	v.A = 1 | 
					
						
							|  |  |  | 	v.B = "hello" | 
					
						
							|  |  |  | 	v.C.D = 3 | 
					
						
							|  |  |  | 	v.C.E = "world" | 
					
						
							|  |  |  | 	v.F = []int{1, 2} | 
					
						
							|  |  |  | 	if err := enc.Encode(v); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := ` | 
					
						
							|  |  |  | {a: 1, b: hello, c: {d: 3, e: world}, f: [1, 2]} | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 	actual := "\n" + buf.String() | 
					
						
							|  |  |  | 	if expect != actual { | 
					
						
							|  |  |  | 		t.Fatalf("flow style marshal error: expect=[%s] actual=[%s]", expect, actual) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 19:56:02 +09:00
										 |  |  | func TestEncoder_JSON(t *testing.T) { | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	enc := yaml.NewEncoder(&buf, yaml.JSON()) | 
					
						
							|  |  |  | 	type st struct { | 
					
						
							|  |  |  | 		I int8 | 
					
						
							|  |  |  | 		S string | 
					
						
							|  |  |  | 		F float32 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := enc.Encode(struct { | 
					
						
							|  |  |  | 		I      int | 
					
						
							|  |  |  | 		U      uint | 
					
						
							|  |  |  | 		S      string | 
					
						
							|  |  |  | 		F      float64 | 
					
						
							|  |  |  | 		Struct *st | 
					
						
							|  |  |  | 		Slice  []int | 
					
						
							|  |  |  | 		Map    map[string]interface{} | 
					
						
							|  |  |  | 		Time   time.Time | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		I: -10, | 
					
						
							|  |  |  | 		U: 10, | 
					
						
							|  |  |  | 		S: "hello", | 
					
						
							|  |  |  | 		F: 3.14, | 
					
						
							|  |  |  | 		Struct: &st{ | 
					
						
							|  |  |  | 			I: 2, | 
					
						
							|  |  |  | 			S: "world", | 
					
						
							|  |  |  | 			F: 1.23, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Slice: []int{1, 2, 3, 4, 5}, | 
					
						
							|  |  |  | 		Map: map[string]interface{}{ | 
					
						
							|  |  |  | 			"a": 1, | 
					
						
							|  |  |  | 			"b": 1.23, | 
					
						
							|  |  |  | 			"c": "json", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Time: time.Time{}, | 
					
						
							|  |  |  | 	}); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := ` | 
					
						
							|  |  |  | {"i": -10, "u": 10, "s": "hello", "f": 3.14, "struct": {"i": 2, "s": "world", "f": 1.23}, "slice": [1, 2, 3, 4, 5], "map": {"a": 1, "b": 1.23, "c": "json"}, "time": "0001-01-01T00:00:00Z"} | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 	actual := "\n" + buf.String() | 
					
						
							|  |  |  | 	if expect != actual { | 
					
						
							|  |  |  | 		t.Fatalf("JSON style marshal error: expect=[%s] actual=[%s]", expect, actual) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-09 13:33:10 +09:00
										 |  |  | func TestEncoder_MarshalAnchor(t *testing.T) { | 
					
						
							|  |  |  | 	type Host struct { | 
					
						
							|  |  |  | 		Hostname string | 
					
						
							|  |  |  | 		Username string | 
					
						
							|  |  |  | 		Password string | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	type HostDecl struct { | 
					
						
							|  |  |  | 		Host *Host `yaml:",anchor"` | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	type Queue struct { | 
					
						
							|  |  |  | 		Name  string `yaml:","` | 
					
						
							|  |  |  | 		*Host `yaml:",alias"` | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var doc struct { | 
					
						
							|  |  |  | 		Hosts  []*HostDecl `yaml:"hosts"` | 
					
						
							|  |  |  | 		Queues []*Queue    `yaml:"queues"` | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	host1 := &Host{ | 
					
						
							|  |  |  | 		Hostname: "host1.example.com", | 
					
						
							|  |  |  | 		Username: "userA", | 
					
						
							|  |  |  | 		Password: "pass1", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	host2 := &Host{ | 
					
						
							|  |  |  | 		Hostname: "host2.example.com", | 
					
						
							|  |  |  | 		Username: "userB", | 
					
						
							|  |  |  | 		Password: "pass2", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	doc.Hosts = []*HostDecl{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Host: host1, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Host: host2, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	doc.Queues = []*Queue{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Name: "queue", | 
					
						
							|  |  |  | 			Host: host1, | 
					
						
							|  |  |  | 		}, { | 
					
						
							|  |  |  | 			Name: "queue2", | 
					
						
							|  |  |  | 			Host: host2, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	hostIdx := 1 | 
					
						
							|  |  |  | 	opt := yaml.MarshalAnchor(func(anchor *ast.AnchorNode, value interface{}) error { | 
					
						
							|  |  |  | 		if _, ok := value.(*Host); ok { | 
					
						
							|  |  |  | 			nameNode := anchor.Name.(*ast.StringNode) | 
					
						
							|  |  |  | 			nameNode.Value = fmt.Sprintf("host%d", hostIdx) | 
					
						
							|  |  |  | 			hostIdx++ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	if err := yaml.NewEncoder(&buf, opt).Encode(doc); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expect := ` | 
					
						
							|  |  |  | hosts: | 
					
						
							|  |  |  | - host: &host1 | 
					
						
							|  |  |  |     hostname: host1.example.com | 
					
						
							|  |  |  |     username: userA | 
					
						
							|  |  |  |     password: pass1 | 
					
						
							|  |  |  | - host: &host2 | 
					
						
							|  |  |  |     hostname: host2.example.com | 
					
						
							|  |  |  |     username: userB | 
					
						
							|  |  |  |     password: pass2 | 
					
						
							|  |  |  | queues: | 
					
						
							|  |  |  | - name: queue | 
					
						
							|  |  |  |   host: *host1 | 
					
						
							|  |  |  | - name: queue2 | 
					
						
							|  |  |  |   host: *host2 | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 	if "\n"+buf.String() != expect { | 
					
						
							|  |  |  | 		t.Fatalf("unexpected output. %s", buf.String()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 19:00:49 +09:00
										 |  |  | type useJSONMarshalerTest struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t useJSONMarshalerTest) MarshalJSON() ([]byte, error) { | 
					
						
							|  |  |  | 	return []byte(`{"a":[1, 2, 3]}`), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestEncoder_UseJSONMarshaler(t *testing.T) { | 
					
						
							|  |  |  | 	got, err := yaml.MarshalWithOptions(useJSONMarshalerTest{}, yaml.UseJSONMarshaler()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected := ` | 
					
						
							|  |  |  | a: | 
					
						
							|  |  |  | - 1 | 
					
						
							|  |  |  | - 2 | 
					
						
							|  |  |  | - 3 | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 	if expected != "\n"+string(got) { | 
					
						
							|  |  |  | 		t.Fatalf("failed to use json marshaler. expected [%q] but got [%q]", expected, string(got)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | type tMarshal []string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *tMarshal) MarshalYAML() ([]byte, error) { | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	buf.WriteString("tags:\n") | 
					
						
							|  |  |  | 	for i, v := range *t { | 
					
						
							|  |  |  | 		if i == 0 { | 
					
						
							|  |  |  | 			fmt.Fprintf(&buf, "- %s\n", v) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			fmt.Fprintf(&buf, "  %s\n", v) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return buf.Bytes(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func Test_Marshaler(t *testing.T) { | 
					
						
							|  |  |  | 	const expected = `- hello-world | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// sanity check | 
					
						
							|  |  |  | 	var l []string | 
					
						
							|  |  |  | 	if err := yaml.Unmarshal([]byte(expected), &l); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to parse string: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf, err := yaml.Marshal(tMarshal{"hello-world"}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to marshal: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if string(buf) != expected { | 
					
						
							|  |  |  | 		t.Fatalf("expected '%s', got '%s'", expected, buf) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Logf("%s", buf) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 16:03:42 +09:00
										 |  |  | type marshalWithContext struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *marshalWithContext) MarshalYAML(ctx context.Context) ([]byte, error) { | 
					
						
							|  |  |  | 	v, ok := ctx.Value("k").(int) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("cannot get valid context") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if v != 1 { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("cannot get valid context") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return []byte("1"), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Test_MarshalerWithContext(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.WithValue(context.Background(), "k", 1) | 
					
						
							|  |  |  | 	bytes, err := yaml.MarshalWithContext(ctx, &marshalWithContext{}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("%+v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if string(bytes) != "1\n" { | 
					
						
							|  |  |  | 		t.Fatalf("failed marshal: %q", string(bytes)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | type SlowMarshaler struct { | 
					
						
							|  |  |  | 	A string | 
					
						
							|  |  |  | 	B int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type FastMarshaler struct { | 
					
						
							|  |  |  | 	A string | 
					
						
							|  |  |  | 	B int | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-12 02:50:51 +09:00
										 |  |  | type TextMarshaler int64 | 
					
						
							|  |  |  | type TextMarshalerContainer struct { | 
					
						
							|  |  |  | 	Field TextMarshaler `yaml:"field"` | 
					
						
							| 
									
										
										
										
											2020-02-16 16:10:19 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | func (v SlowMarshaler) MarshalYAML() ([]byte, error) { | 
					
						
							|  |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	buf.WriteString("tags:\n") | 
					
						
							|  |  |  | 	buf.WriteString("- slow-marshaler\n") | 
					
						
							|  |  |  | 	buf.WriteString("a: " + v.A + "\n") | 
					
						
							|  |  |  | 	buf.WriteString("b: " + strconv.FormatInt(int64(v.B), 10) + "\n") | 
					
						
							|  |  |  | 	return buf.Bytes(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (v FastMarshaler) MarshalYAML() (interface{}, error) { | 
					
						
							|  |  |  | 	return yaml.MapSlice{ | 
					
						
							|  |  |  | 		{"tags", []string{"fast-marshaler"}}, | 
					
						
							|  |  |  | 		{"a", v.A}, | 
					
						
							|  |  |  | 		{"b", v.B}, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 02:50:51 +09:00
										 |  |  | func (t TextMarshaler) MarshalText() ([]byte, error) { | 
					
						
							|  |  |  | 	return []byte(strconv.FormatInt(int64(t), 8)), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | func Example_MarshalYAML() { | 
					
						
							|  |  |  | 	var slow SlowMarshaler | 
					
						
							|  |  |  | 	slow.A = "Hello slow poke" | 
					
						
							|  |  |  | 	slow.B = 100 | 
					
						
							|  |  |  | 	buf, err := yaml.Marshal(slow) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fmt.Println(string(buf)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var fast FastMarshaler | 
					
						
							|  |  |  | 	fast.A = "Hello speed demon" | 
					
						
							|  |  |  | 	fast.B = 100 | 
					
						
							|  |  |  | 	buf, err = yaml.Marshal(fast) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-12 02:50:51 +09:00
										 |  |  | 	fmt.Println(string(buf)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	text := TextMarshalerContainer{ | 
					
						
							|  |  |  | 		Field: 11, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	buf, err = yaml.Marshal(text) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | 	fmt.Println(string(buf)) | 
					
						
							|  |  |  | 	// OUTPUT: | 
					
						
							|  |  |  | 	// tags: | 
					
						
							|  |  |  | 	// - slow-marshaler | 
					
						
							|  |  |  | 	// a: Hello slow poke | 
					
						
							|  |  |  | 	// b: 100 | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// tags: | 
					
						
							|  |  |  | 	// - fast-marshaler | 
					
						
							|  |  |  | 	// a: Hello speed demon | 
					
						
							|  |  |  | 	// b: 100 | 
					
						
							| 
									
										
										
										
											2020-01-12 02:50:51 +09:00
										 |  |  | 	// | 
					
						
							|  |  |  | 	// field: 13 | 
					
						
							| 
									
										
										
										
											2019-10-26 18:39:15 +09:00
										 |  |  | } |