github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/conversion/converter_test.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors. 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 conversion 18 19 import ( 20 "fmt" 21 "reflect" 22 "strconv" 23 "testing" 24 ) 25 26 func TestConverter_byteSlice(t *testing.T) { 27 c := NewConverter(nil) 28 src := []byte{1, 2, 3} 29 dest := []byte{} 30 err := c.Convert(&src, &dest, nil) 31 if err != nil { 32 t.Fatalf("expected no error") 33 } 34 if e, a := src, dest; !reflect.DeepEqual(e, a) { 35 t.Errorf("expected %#v, got %#v", e, a) 36 } 37 } 38 39 func TestConverter_MismatchedTypes(t *testing.T) { 40 c := NewConverter(nil) 41 42 convertFn := func(in *[]string, out *int, s Scope) error { 43 if str, err := strconv.Atoi((*in)[0]); err != nil { 44 return err 45 } else { 46 *out = str 47 return nil 48 } 49 } 50 if err := c.RegisterUntypedConversionFunc( 51 (*[]string)(nil), (*int)(nil), 52 func(a, b interface{}, s Scope) error { 53 return convertFn(a.(*[]string), b.(*int), s) 54 }, 55 ); err != nil { 56 t.Fatalf("Unexpected error: %v", err) 57 } 58 59 src := []string{"5"} 60 var dest int 61 if err := c.Convert(&src, &dest, nil); err != nil { 62 t.Fatalf("unexpected error: %v", err) 63 } 64 if e, a := 5, dest; e != a { 65 t.Errorf("expected %#v, got %#v", e, a) 66 } 67 } 68 69 func TestConverter_CallsRegisteredFunctions(t *testing.T) { 70 type A struct { 71 Foo string 72 Baz int 73 } 74 type B struct { 75 Bar string 76 Baz int 77 } 78 type C struct{} 79 c := NewConverter(nil) 80 convertFn1 := func(in *A, out *B, s Scope) error { 81 out.Bar = in.Foo 82 out.Baz = in.Baz 83 return nil 84 } 85 if err := c.RegisterUntypedConversionFunc( 86 (*A)(nil), (*B)(nil), 87 func(a, b interface{}, s Scope) error { 88 return convertFn1(a.(*A), b.(*B), s) 89 }, 90 ); err != nil { 91 t.Fatalf("unexpected error %v", err) 92 } 93 convertFn2 := func(in *B, out *A, s Scope) error { 94 out.Foo = in.Bar 95 out.Baz = in.Baz 96 return nil 97 } 98 if err := c.RegisterUntypedConversionFunc( 99 (*B)(nil), (*A)(nil), 100 func(a, b interface{}, s Scope) error { 101 return convertFn2(a.(*B), b.(*A), s) 102 }, 103 ); err != nil { 104 t.Fatalf("unexpected error %v", err) 105 } 106 107 x := A{"hello, intrepid test reader!", 3} 108 y := B{} 109 110 if err := c.Convert(&x, &y, nil); err != nil { 111 t.Fatalf("unexpected error %v", err) 112 } 113 if e, a := x.Foo, y.Bar; e != a { 114 t.Errorf("expected %v, got %v", e, a) 115 } 116 if e, a := x.Baz, y.Baz; e != a { 117 t.Errorf("expected %v, got %v", e, a) 118 } 119 120 z := B{"all your test are belong to us", 42} 121 w := A{} 122 123 if err := c.Convert(&z, &w, nil); err != nil { 124 t.Fatalf("unexpected error %v", err) 125 } 126 if e, a := z.Bar, w.Foo; e != a { 127 t.Errorf("expected %v, got %v", e, a) 128 } 129 if e, a := z.Baz, w.Baz; e != a { 130 t.Errorf("expected %v, got %v", e, a) 131 } 132 133 convertFn3 := func(in *A, out *C, s Scope) error { 134 return fmt.Errorf("C can't store an A, silly") 135 } 136 if err := c.RegisterUntypedConversionFunc( 137 (*A)(nil), (*C)(nil), 138 func(a, b interface{}, s Scope) error { 139 return convertFn3(a.(*A), b.(*C), s) 140 }, 141 ); err != nil { 142 t.Fatalf("unexpected error %v", err) 143 } 144 if err := c.Convert(&A{}, &C{}, nil); err == nil { 145 t.Errorf("unexpected non-error") 146 } 147 } 148 149 func TestConverter_IgnoredConversion(t *testing.T) { 150 type A struct{} 151 type B struct{} 152 153 count := 0 154 c := NewConverter(nil) 155 convertFn := func(in *A, out *B, s Scope) error { 156 count++ 157 return nil 158 } 159 if err := c.RegisterUntypedConversionFunc( 160 (*A)(nil), (*B)(nil), 161 func(a, b interface{}, s Scope) error { 162 return convertFn(a.(*A), b.(*B), s) 163 }, 164 ); err != nil { 165 t.Fatalf("unexpected error %v", err) 166 } 167 if err := c.RegisterIgnoredConversion(&A{}, &B{}); err != nil { 168 t.Fatal(err) 169 } 170 a := A{} 171 b := B{} 172 if err := c.Convert(&a, &b, nil); err != nil { 173 t.Errorf("%v", err) 174 } 175 if count != 0 { 176 t.Errorf("unexpected number of conversion invocations") 177 } 178 } 179 180 func TestConverter_GeneratedConversionOverridden(t *testing.T) { 181 type A struct{} 182 type B struct{} 183 c := NewConverter(nil) 184 convertFn1 := func(in *A, out *B, s Scope) error { 185 return nil 186 } 187 if err := c.RegisterUntypedConversionFunc( 188 (*A)(nil), (*B)(nil), 189 func(a, b interface{}, s Scope) error { 190 return convertFn1(a.(*A), b.(*B), s) 191 }, 192 ); err != nil { 193 t.Fatalf("unexpected error %v", err) 194 } 195 convertFn2 := func(in *A, out *B, s Scope) error { 196 return fmt.Errorf("generated function should be overridden") 197 } 198 if err := c.RegisterGeneratedUntypedConversionFunc( 199 (*A)(nil), (*B)(nil), 200 func(a, b interface{}, s Scope) error { 201 return convertFn2(a.(*A), b.(*B), s) 202 }, 203 ); err != nil { 204 t.Fatalf("unexpected error %v", err) 205 } 206 207 a := A{} 208 b := B{} 209 if err := c.Convert(&a, &b, nil); err != nil { 210 t.Errorf("%v", err) 211 } 212 } 213 214 func TestConverter_WithConversionOverridden(t *testing.T) { 215 type A struct{} 216 type B struct{} 217 c := NewConverter(nil) 218 convertFn1 := func(in *A, out *B, s Scope) error { 219 return fmt.Errorf("conversion function should be overridden") 220 } 221 if err := c.RegisterUntypedConversionFunc( 222 (*A)(nil), (*B)(nil), 223 func(a, b interface{}, s Scope) error { 224 return convertFn1(a.(*A), b.(*B), s) 225 }, 226 ); err != nil { 227 t.Fatalf("unexpected error %v", err) 228 } 229 convertFn2 := func(in *A, out *B, s Scope) error { 230 return fmt.Errorf("generated function should be overridden") 231 } 232 if err := c.RegisterGeneratedUntypedConversionFunc( 233 (*A)(nil), (*B)(nil), 234 func(a, b interface{}, s Scope) error { 235 return convertFn2(a.(*A), b.(*B), s) 236 }, 237 ); err != nil { 238 t.Fatalf("unexpected error %v", err) 239 } 240 241 ext := NewConversionFuncs() 242 ext.AddUntyped( 243 (*A)(nil), (*B)(nil), 244 func(a, b interface{}, s Scope) error { 245 return nil 246 }, 247 ) 248 newc := c.WithConversions(ext) 249 250 a := A{} 251 b := B{} 252 if err := c.Convert(&a, &b, nil); err == nil || err.Error() != "conversion function should be overridden" { 253 t.Errorf("unexpected error: %v", err) 254 } 255 if err := newc.Convert(&a, &b, nil); err != nil { 256 t.Errorf("%v", err) 257 } 258 } 259 260 func TestConverter_meta(t *testing.T) { 261 type Foo struct{ A string } 262 type Bar struct{ A string } 263 c := NewConverter(nil) 264 checks := 0 265 convertFn1 := func(in *Foo, out *Bar, s Scope) error { 266 if s.Meta() == nil { 267 t.Errorf("Meta did not get passed!") 268 } 269 checks++ 270 out.A = in.A 271 return nil 272 } 273 if err := c.RegisterUntypedConversionFunc( 274 (*Foo)(nil), (*Bar)(nil), 275 func(a, b interface{}, s Scope) error { 276 return convertFn1(a.(*Foo), b.(*Bar), s) 277 }, 278 ); err != nil { 279 t.Fatalf("Unexpected error: %v", err) 280 } 281 if err := c.Convert(&Foo{}, &Bar{}, &Meta{}); err != nil { 282 t.Fatalf("Unexpected error: %v", err) 283 } 284 if checks != 1 { 285 t.Errorf("Registered functions did not get called.") 286 } 287 }