|
|
@@ -1115,6 +1115,37 @@ func (s *S) TestUnmarshalerTypeError(c *C) {
|
|
|
delete(unmarshalerResult, 4)
|
|
|
}()
|
|
|
|
|
|
+ type T struct {
|
|
|
+ Before int
|
|
|
+ After int
|
|
|
+ M map[string]*unmarshalerType
|
|
|
+ }
|
|
|
+ var v T
|
|
|
+ data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
|
|
|
+ err := yaml.Unmarshal([]byte(data), &v)
|
|
|
+ c.Assert(err, ErrorMatches, ""+
|
|
|
+ "yaml: unmarshal errors:\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `A` into int\n"+
|
|
|
+ " foo\n"+
|
|
|
+ " bar\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `B` into int")
|
|
|
+ c.Assert(v.M["abc"], NotNil)
|
|
|
+ c.Assert(v.M["def"], IsNil)
|
|
|
+ c.Assert(v.M["ghi"], NotNil)
|
|
|
+ c.Assert(v.M["jkl"], IsNil)
|
|
|
+
|
|
|
+ c.Assert(v.M["abc"].value, Equals, 1)
|
|
|
+ c.Assert(v.M["ghi"].value, Equals, 3)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *S) TestObsoleteUnmarshalerTypeError(c *C) {
|
|
|
+ unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
|
|
|
+ unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
|
|
|
+ defer func() {
|
|
|
+ delete(unmarshalerResult, 2)
|
|
|
+ delete(unmarshalerResult, 4)
|
|
|
+ }()
|
|
|
+
|
|
|
type T struct {
|
|
|
Before int
|
|
|
After int
|
|
|
@@ -1140,7 +1171,45 @@ func (s *S) TestUnmarshalerTypeError(c *C) {
|
|
|
|
|
|
type proxyTypeError struct{}
|
|
|
|
|
|
-func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
+func (v *proxyTypeError) UnmarshalYAML(node *yaml.Node) error {
|
|
|
+ var s string
|
|
|
+ var a int32
|
|
|
+ var b int64
|
|
|
+ if err := node.Decode(&s); err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ if s == "a" {
|
|
|
+ if err := node.Decode(&b); err == nil {
|
|
|
+ panic("should have failed")
|
|
|
+ }
|
|
|
+ return node.Decode(&a)
|
|
|
+ }
|
|
|
+ if err := node.Decode(&a); err == nil {
|
|
|
+ panic("should have failed")
|
|
|
+ }
|
|
|
+ return node.Decode(&b)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
|
|
|
+ type T struct {
|
|
|
+ Before int
|
|
|
+ After int
|
|
|
+ M map[string]*proxyTypeError
|
|
|
+ }
|
|
|
+ var v T
|
|
|
+ data := `{before: A, m: {abc: a, def: b}, after: B}`
|
|
|
+ err := yaml.Unmarshal([]byte(data), &v)
|
|
|
+ c.Assert(err, ErrorMatches, ""+
|
|
|
+ "yaml: unmarshal errors:\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `A` into int\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `a` into int32\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `b` into int64\n"+
|
|
|
+ " line 1: cannot unmarshal !!str `B` into int")
|
|
|
+}
|
|
|
+
|
|
|
+type obsoleteProxyTypeError struct{}
|
|
|
+
|
|
|
+func (v *obsoleteProxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
var s string
|
|
|
var a int32
|
|
|
var b int64
|
|
|
@@ -1159,11 +1228,11 @@ func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error
|
|
|
return unmarshal(&b)
|
|
|
}
|
|
|
|
|
|
-func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
|
|
|
+func (s *S) TestObsoleteUnmarshalerTypeErrorProxying(c *C) {
|
|
|
type T struct {
|
|
|
Before int
|
|
|
After int
|
|
|
- M map[string]*proxyTypeError
|
|
|
+ M map[string]*obsoleteProxyTypeError
|
|
|
}
|
|
|
var v T
|
|
|
data := `{before: A, m: {abc: a, def: b}, after: B}`
|
|
|
@@ -1176,11 +1245,11 @@ func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
|
|
|
" line 1: cannot unmarshal !!str `B` into int")
|
|
|
}
|
|
|
|
|
|
-type failingUnmarshaler struct{}
|
|
|
-
|
|
|
var failingErr = errors.New("failingErr")
|
|
|
|
|
|
-func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
+type failingUnmarshaler struct{}
|
|
|
+
|
|
|
+func (ft *failingUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
|
|
|
return failingErr
|
|
|
}
|
|
|
|
|
|
@@ -1189,18 +1258,29 @@ func (s *S) TestUnmarshalerError(c *C) {
|
|
|
c.Assert(err, Equals, failingErr)
|
|
|
}
|
|
|
|
|
|
+type obsoleteFailingUnmarshaler struct{}
|
|
|
+
|
|
|
+func (ft *obsoleteFailingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
+ return failingErr
|
|
|
+}
|
|
|
+
|
|
|
+func (s *S) TestObsoleteUnmarshalerError(c *C) {
|
|
|
+ err := yaml.Unmarshal([]byte("a: b"), &obsoleteFailingUnmarshaler{})
|
|
|
+ c.Assert(err, Equals, failingErr)
|
|
|
+}
|
|
|
+
|
|
|
type sliceUnmarshaler []int
|
|
|
|
|
|
-func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
+func (su *sliceUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
|
|
|
var slice []int
|
|
|
- err := unmarshal(&slice)
|
|
|
+ err := node.Decode(&slice)
|
|
|
if err == nil {
|
|
|
*su = slice
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
var intVal int
|
|
|
- err = unmarshal(&intVal)
|
|
|
+ err = node.Decode(&intVal)
|
|
|
if err == nil {
|
|
|
*su = []int{intVal}
|
|
|
return nil
|
|
|
@@ -1220,6 +1300,37 @@ func (s *S) TestUnmarshalerRetry(c *C) {
|
|
|
c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
|
|
|
}
|
|
|
|
|
|
+type obsoleteSliceUnmarshaler []int
|
|
|
+
|
|
|
+func (su *obsoleteSliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
+ var slice []int
|
|
|
+ err := unmarshal(&slice)
|
|
|
+ if err == nil {
|
|
|
+ *su = slice
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ var intVal int
|
|
|
+ err = unmarshal(&intVal)
|
|
|
+ if err == nil {
|
|
|
+ *su = []int{intVal}
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+func (s *S) TestObsoleteUnmarshalerRetry(c *C) {
|
|
|
+ var su obsoleteSliceUnmarshaler
|
|
|
+ err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
|
|
|
+ c.Assert(err, IsNil)
|
|
|
+ c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1, 2, 3}))
|
|
|
+
|
|
|
+ err = yaml.Unmarshal([]byte("1"), &su)
|
|
|
+ c.Assert(err, IsNil)
|
|
|
+ c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1}))
|
|
|
+}
|
|
|
+
|
|
|
// From http://yaml.org/type/merge.html
|
|
|
var mergeTests = `
|
|
|
anchors:
|