github.com/vmware/govmomi@v0.43.0/vim25/xml/extras_test.go (about) 1 /* 2 Copyright (c) 2014 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package xml 18 19 import ( 20 "bytes" 21 "reflect" 22 "testing" 23 "time" 24 ) 25 26 type MyType struct { 27 Value string 28 } 29 30 var myTypes = map[string]reflect.Type{ 31 "MyType": reflect.TypeOf(MyType{}), 32 "ValueType": reflect.TypeOf(ValueType{}), 33 "PointerType": reflect.TypeOf(PointerType{}), 34 } 35 36 func MyTypes(name string) (reflect.Type, bool) { 37 t, ok := myTypes[name] 38 return t, ok 39 } 40 41 func TestMarshalWithEmptyInterface(t *testing.T) { 42 var r1, r2 struct { 43 XMLName Name `xml:"root"` 44 Values []interface{} `xml:"value,typeattr"` 45 } 46 47 var tests = []struct { 48 Value interface{} 49 }{ 50 {Value: bool(true)}, 51 {Value: int8(-8)}, 52 {Value: int16(-16)}, 53 {Value: int32(-32)}, 54 {Value: int64(-64)}, 55 {Value: uint8(8)}, 56 {Value: uint16(16)}, 57 {Value: uint32(32)}, 58 {Value: uint64(64)}, 59 {Value: float32(32.0)}, 60 {Value: float64(64.0)}, 61 {Value: string("string")}, 62 {Value: time.Now()}, 63 {Value: ParseTime("2009-10-04T01:35:58+00:00")}, 64 {Value: []byte("bytes")}, 65 {Value: MyType{Value: "v"}}, 66 } 67 68 for _, test := range tests { 69 r1.XMLName.Local = "root" 70 r1.Values = []interface{}{test.Value} 71 r2.XMLName = Name{} 72 r2.Values = nil 73 74 b, err := Marshal(r1) 75 if err != nil { 76 t.Fatalf("Marshal: %s", err) 77 } 78 79 dec := NewDecoder(bytes.NewReader(b)) 80 dec.TypeFunc = MyTypes 81 err = dec.Decode(&r2) 82 if err != nil { 83 t.Fatalf("Unmarshal: %s", err) 84 } 85 86 switch r1.Values[0].(type) { 87 case time.Time: 88 if !r1.Values[0].(time.Time).Equal(r2.Values[0].(time.Time)) { 89 t.Errorf("Expected: %#v, actual: %#v", r1, r2) 90 } 91 default: 92 if !reflect.DeepEqual(r1, r2) { 93 t.Errorf("Expected: %#v, actual: %#v", r1, r2) 94 } 95 } 96 } 97 } 98 99 type VIntf interface { 100 V() string 101 } 102 103 type ValueType struct { 104 Value string `xml:",chardata"` 105 } 106 107 type PointerType struct { 108 Value string `xml:",chardata"` 109 } 110 111 func (t ValueType) V() string { 112 return t.Value 113 } 114 115 func (t *PointerType) V() string { 116 return t.Value 117 } 118 119 func TestMarshalWithInterface(t *testing.T) { 120 var r1, r2 struct { 121 XMLName Name `xml:"root"` 122 Values []VIntf `xml:"value,typeattr"` 123 } 124 125 r1.XMLName.Local = "root" 126 r1.Values = []VIntf{ 127 ValueType{"v1"}, 128 &PointerType{"v2"}, 129 } 130 131 b, err := Marshal(r1) 132 if err != nil { 133 t.Fatalf("Marshal: %s", err) 134 } 135 136 dec := NewDecoder(bytes.NewReader(b)) 137 dec.TypeFunc = MyTypes 138 err = dec.Decode(&r2) 139 if err != nil { 140 t.Fatalf("Unmarshal: %s", err) 141 } 142 143 if !reflect.DeepEqual(r1, r2) { 144 t.Errorf("expected: %#v, actual: %#v", r1, r2) 145 } 146 } 147 148 type test3iface interface { 149 Value() string 150 } 151 152 type test3a struct { 153 V string `xml:",chardata"` 154 } 155 156 func (t test3a) Value() string { return t.V } 157 158 type test3b struct { 159 V string `xml:",chardata"` 160 } 161 162 func (t test3b) Value() string { return t.V } 163 164 func TestUnmarshalInterfaceWithoutTypeAttr(t *testing.T) { 165 var r struct { 166 XMLName Name `xml:"root"` 167 Values []test3iface `xml:"value,typeattr"` 168 } 169 170 b := ` 171 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 172 <value xsi:type="test3a">A</value> 173 <value>B</value> 174 </root> 175 ` 176 177 fn := func(name string) (reflect.Type, bool) { 178 switch name { 179 case "test3a": 180 return reflect.TypeOf(test3a{}), true 181 case "test3iface": 182 return reflect.TypeOf(test3b{}), true 183 default: 184 return nil, false 185 } 186 } 187 188 dec := NewDecoder(bytes.NewReader([]byte(b))) 189 dec.TypeFunc = fn 190 err := dec.Decode(&r) 191 if err != nil { 192 t.Fatalf("Unmarshal: %s", err) 193 } 194 195 if len(r.Values) != 2 { 196 t.Errorf("Expected 2 values") 197 } 198 199 exps := []struct { 200 Typ reflect.Type 201 Val string 202 }{ 203 { 204 Typ: reflect.TypeOf(test3a{}), 205 Val: "A", 206 }, 207 { 208 Typ: reflect.TypeOf(test3b{}), 209 Val: "B", 210 }, 211 } 212 213 for i, e := range exps { 214 if val := r.Values[i].Value(); val != e.Val { 215 t.Errorf("Expected: %s, got: %s", e.Val, val) 216 } 217 218 if typ := reflect.TypeOf(r.Values[i]); typ.Name() != e.Typ.Name() { 219 t.Errorf("Expected: %s, got: %s", e.Typ.Name(), typ.Name()) 220 } 221 } 222 }