diff --git a/copier_converter_test.go b/copier_converter_test.go index 6d83ea1..a2605a3 100644 --- a/copier_converter_test.go +++ b/copier_converter_test.go @@ -1,7 +1,11 @@ package copier_test import ( + "database/sql/driver" + "encoding/json" "errors" + "fmt" + "reflect" "strconv" "testing" "time" @@ -218,3 +222,55 @@ func TestCopyWithConverterRaisingError(t *testing.T) { return } } + +type IntArray []int + +var fnIntArrayValueInvoked bool + +func (a IntArray) Value() (driver.Value, error) { + fnIntArrayValueInvoked = true + return json.Marshal(a) +} + +type Int int + +type From struct { + Data IntArray +} + +type To struct { + Data []Int +} + +func TestValuerConv(t *testing.T) { + // when the field of struct implement driver.Valuer and cannot convert to dest type directly, + // copier.set() will return a unexpected (true, nil) + + typ1 := reflect.TypeOf(IntArray{}) + typ2 := reflect.TypeOf([]Int{}) + + if typ1 == typ2 || typ1.ConvertibleTo(typ2) || typ1.AssignableTo(typ2) { + // in 1.22 and older, u can not convert typ1 to typ2 + t.Errorf("can not convert %v to %v direct", typ1, typ2) + } + + var ( + from = From{ + Data: IntArray{1, 2, 3}, + } + to To + ) + if err := copier.Copy(&to, from); err != nil { + panic(err) + } + + if !fnIntArrayValueInvoked { + t.Errorf("value method not invoked") + } + + if len(to.Data) != 3 || to.Data[0] != 1 || to.Data[1] != 2 || to.Data[2] != 3 { + t.Fatalf("copier failed from %#v to %#v", from, to) + } + + fmt.Printf("%#v", to) +}