1
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 }
288
View as plain text