LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package sql | 5 package sql |
6 | 6 |
7 import ( | 7 import ( |
8 "database/sql/driver" | 8 "database/sql/driver" |
9 "fmt" | 9 "fmt" |
10 "reflect" | 10 "reflect" |
11 "testing" | 11 "testing" |
12 "time" | 12 "time" |
13 ) | 13 ) |
14 | 14 |
15 var someTime = time.Unix(123, 0) | 15 var someTime = time.Unix(123, 0) |
16 var answer int64 = 42 | 16 var answer int64 = 42 |
17 | 17 |
18 type conversionTest struct { | 18 type conversionTest struct { |
19 s, d interface{} // source and destination | 19 s, d interface{} // source and destination |
20 | 20 |
21 // following are used if they're non-zero | 21 // following are used if they're non-zero |
22 » wantint int64 | 22 » wantint int64 |
23 » wantuint uint64 | 23 » wantuint uint64 |
24 » wantstr string | 24 » wantstr string |
25 » wantf32 float32 | 25 » wantf32 float32 |
26 » wantf64 float64 | 26 » wantf64 float64 |
27 » wanttime time.Time | 27 » wanttime time.Time |
28 » wantbool bool // used if d is of type *bool | 28 » wantbool bool // used if d is of type *bool |
29 » wanterr string | 29 » wanterr string |
30 » wantptr *int64 // if non-nil, *d's pointed value must be equal to *want
ptr | 30 » wantiface interface{} |
31 » wantnil bool // if true, *d must be *int64(nil) | 31 » wantptr *int64 // if non-nil, *d's pointed value must be equal to *wan
tptr |
| 32 » wantnil bool // if true, *d must be *int64(nil) |
32 } | 33 } |
33 | 34 |
34 // Target variables for scanning into. | 35 // Target variables for scanning into. |
35 var ( | 36 var ( |
36 scanstr string | 37 scanstr string |
37 scanint int | 38 scanint int |
38 scanint8 int8 | 39 scanint8 int8 |
39 scanint16 int16 | 40 scanint16 int16 |
40 scanint32 int32 | 41 scanint32 int32 |
41 scanuint8 uint8 | 42 scanuint8 uint8 |
42 scanuint16 uint16 | 43 scanuint16 uint16 |
43 scanbool bool | 44 scanbool bool |
44 scanf32 float32 | 45 scanf32 float32 |
45 scanf64 float64 | 46 scanf64 float64 |
46 scantime time.Time | 47 scantime time.Time |
47 scanptr *int64 | 48 scanptr *int64 |
| 49 scaniface interface{} |
48 ) | 50 ) |
49 | 51 |
50 var conversionTests = []conversionTest{ | 52 var conversionTests = []conversionTest{ |
51 // Exact conversions (destination pointer type matches source type) | 53 // Exact conversions (destination pointer type matches source type) |
52 {s: "foo", d: &scanstr, wantstr: "foo"}, | 54 {s: "foo", d: &scanstr, wantstr: "foo"}, |
53 {s: 123, d: &scanint, wantint: 123}, | 55 {s: 123, d: &scanint, wantint: 123}, |
54 {s: someTime, d: &scantime, wanttime: someTime}, | 56 {s: someTime, d: &scantime, wanttime: someTime}, |
55 | 57 |
56 // To strings | 58 // To strings |
57 {s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"}, | 59 {s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"}, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // Floats | 98 // Floats |
97 {s: float64(1.5), d: &scanf64, wantf64: float64(1.5)}, | 99 {s: float64(1.5), d: &scanf64, wantf64: float64(1.5)}, |
98 {s: int64(1), d: &scanf64, wantf64: float64(1)}, | 100 {s: int64(1), d: &scanf64, wantf64: float64(1)}, |
99 {s: float64(1.5), d: &scanf32, wantf32: float32(1.5)}, | 101 {s: float64(1.5), d: &scanf32, wantf32: float32(1.5)}, |
100 {s: "1.5", d: &scanf32, wantf32: float32(1.5)}, | 102 {s: "1.5", d: &scanf32, wantf32: float32(1.5)}, |
101 {s: "1.5", d: &scanf64, wantf64: float64(1.5)}, | 103 {s: "1.5", d: &scanf64, wantf64: float64(1.5)}, |
102 | 104 |
103 // Pointers | 105 // Pointers |
104 {s: interface{}(nil), d: &scanptr, wantnil: true}, | 106 {s: interface{}(nil), d: &scanptr, wantnil: true}, |
105 {s: int64(42), d: &scanptr, wantptr: &answer}, | 107 {s: int64(42), d: &scanptr, wantptr: &answer}, |
| 108 |
| 109 // To interface{} |
| 110 {s: float64(1.5), d: &scaniface, wantiface: float64(1.5)}, |
| 111 {s: int64(1), d: &scaniface, wantiface: int64(1)}, |
| 112 {s: "str", d: &scaniface, wantiface: "str"}, |
| 113 {s: []byte("byteslice"), d: &scaniface, wantiface: []byte("byteslice")}, |
| 114 {s: true, d: &scaniface, wantiface: true}, |
| 115 {s: nil, d: &scaniface}, |
106 } | 116 } |
107 | 117 |
108 func intPtrValue(intptr interface{}) interface{} { | 118 func intPtrValue(intptr interface{}) interface{} { |
109 return reflect.Indirect(reflect.Indirect(reflect.ValueOf(intptr))).Int() | 119 return reflect.Indirect(reflect.Indirect(reflect.ValueOf(intptr))).Int() |
110 } | 120 } |
111 | 121 |
112 func intValue(intptr interface{}) int64 { | 122 func intValue(intptr interface{}) int64 { |
113 return reflect.Indirect(reflect.ValueOf(intptr)).Int() | 123 return reflect.Indirect(reflect.ValueOf(intptr)).Int() |
114 } | 124 } |
115 | 125 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 if ct.wantnil && *ct.d.(**int64) != nil { | 177 if ct.wantnil && *ct.d.(**int64) != nil { |
168 errf("want nil, got %v", intPtrValue(ct.d)) | 178 errf("want nil, got %v", intPtrValue(ct.d)) |
169 } | 179 } |
170 if ct.wantptr != nil { | 180 if ct.wantptr != nil { |
171 if *ct.d.(**int64) == nil { | 181 if *ct.d.(**int64) == nil { |
172 errf("want pointer to %v, got nil", *ct.wantptr) | 182 errf("want pointer to %v, got nil", *ct.wantptr) |
173 } else if *ct.wantptr != intPtrValue(ct.d) { | 183 } else if *ct.wantptr != intPtrValue(ct.d) { |
174 errf("want pointer to %v, got %v", *ct.wantptr,
intPtrValue(ct.d)) | 184 errf("want pointer to %v, got %v", *ct.wantptr,
intPtrValue(ct.d)) |
175 } | 185 } |
176 } | 186 } |
| 187 if ifptr, ok := ct.d.(*interface{}); ok { |
| 188 if !reflect.DeepEqual(ct.wantiface, scaniface) { |
| 189 errf("want interface %#v, got %#v", ct.wantiface
, scaniface) |
| 190 continue |
| 191 } |
| 192 if srcBytes, ok := ct.s.([]byte); ok { |
| 193 dstBytes := (*ifptr).([]byte) |
| 194 if &dstBytes[0] == &srcBytes[0] { |
| 195 errf("copy into interface{} didn't copy
[]byte data") |
| 196 } |
| 197 } |
| 198 } |
177 } | 199 } |
178 } | 200 } |
179 | 201 |
180 func TestNullString(t *testing.T) { | 202 func TestNullString(t *testing.T) { |
181 var ns NullString | 203 var ns NullString |
182 convertAssign(&ns, []byte("foo")) | 204 convertAssign(&ns, []byte("foo")) |
183 if !ns.Valid { | 205 if !ns.Valid { |
184 t.Errorf("expecting not null") | 206 t.Errorf("expecting not null") |
185 } | 207 } |
186 if ns.String != "foo" { | 208 if ns.String != "foo" { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 } | 241 } |
220 if tt.err != "" { | 242 if tt.err != "" { |
221 continue | 243 continue |
222 } | 244 } |
223 if !reflect.DeepEqual(out, tt.out) { | 245 if !reflect.DeepEqual(out, tt.out) { |
224 t.Errorf("test %d: %s(%T(%v)) = %v (%T); want %v (%T)", | 246 t.Errorf("test %d: %s(%T(%v)) = %v (%T); want %v (%T)", |
225 i, tt.c, tt.in, tt.in, out, out, tt.out, tt.out) | 247 i, tt.c, tt.in, tt.in, out, out, tt.out, tt.out) |
226 } | 248 } |
227 } | 249 } |
228 } | 250 } |
LEFT | RIGHT |