|
1 | 1 | package copier_test
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
| 5 | + "database/sql/driver" |
| 6 | + "encoding/json" |
4 | 7 | "errors"
|
| 8 | + "reflect" |
5 | 9 | "strconv"
|
6 | 10 | "testing"
|
7 | 11 | "time"
|
@@ -218,3 +222,60 @@ func TestCopyWithConverterRaisingError(t *testing.T) {
|
218 | 222 | return
|
219 | 223 | }
|
220 | 224 | }
|
| 225 | + |
| 226 | +type IntArray []int |
| 227 | + |
| 228 | +func (a IntArray) Value() (driver.Value, error) { |
| 229 | + return json.Marshal(a) |
| 230 | +} |
| 231 | + |
| 232 | +type Int int |
| 233 | + |
| 234 | +type From struct { |
| 235 | + Data IntArray |
| 236 | +} |
| 237 | + |
| 238 | +type To struct { |
| 239 | + Data []byte |
| 240 | +} |
| 241 | + |
| 242 | +type FailedTo struct { |
| 243 | + Data []Int |
| 244 | +} |
| 245 | + |
| 246 | +func TestValuerConv(t *testing.T) { |
| 247 | + // when the field of struct implement driver.Valuer and cannot convert to dest type directly, |
| 248 | + // copier.set() will return a unexpected (true, nil) |
| 249 | + |
| 250 | + typ1 := reflect.TypeOf(IntArray{}) |
| 251 | + typ2 := reflect.TypeOf([]Int{}) |
| 252 | + |
| 253 | + if typ1 == typ2 || typ1.ConvertibleTo(typ2) || typ1.AssignableTo(typ2) { |
| 254 | + // in 1.22 and older, u can not convert typ1 to typ2 |
| 255 | + t.Errorf("can not convert %v to %v direct", typ1, typ2) |
| 256 | + } |
| 257 | + |
| 258 | + var ( |
| 259 | + from = From{ |
| 260 | + Data: IntArray{1, 2, 3}, |
| 261 | + } |
| 262 | + to To |
| 263 | + failedTo FailedTo |
| 264 | + ) |
| 265 | + if err := copier.Copy(&to, from); err != nil { |
| 266 | + t.Fatal(err) |
| 267 | + } |
| 268 | + if err := copier.Copy(&failedTo, from); err != nil { |
| 269 | + t.Fatal(err) |
| 270 | + } |
| 271 | + |
| 272 | + // valuer conv case |
| 273 | + if !bytes.Equal(to.Data, []byte(`[1,2,3]`)) { |
| 274 | + t.Errorf("can not convert %v to %v using valuer", typ1, typ2) |
| 275 | + } |
| 276 | + |
| 277 | + // fallback case when valuer conv failed |
| 278 | + if len(failedTo.Data) != 3 || failedTo.Data[0] != 1 || failedTo.Data[1] != 2 || failedTo.Data[2] != 3 { |
| 279 | + t.Errorf("copier failed from %#v to %#v", from, failedTo) |
| 280 | + } |
| 281 | +} |
0 commit comments