github.com/jinzhu/copier@v0.4.0/copier_different_type_test.go (about) 1 package copier_test 2 3 import ( 4 "database/sql" 5 "testing" 6 "time" 7 8 "github.com/jinzhu/copier" 9 ) 10 11 type TypeStruct1 struct { 12 Field1 string 13 Field2 string 14 Field3 TypeStruct2 15 Field4 *TypeStruct2 16 Field5 []*TypeStruct2 17 Field6 []TypeStruct2 18 Field7 []*TypeStruct2 19 Field8 []TypeStruct2 20 Field9 []string 21 } 22 23 type TypeStruct2 struct { 24 Field1 int 25 Field2 string 26 Field3 []TypeStruct2 27 Field4 *TypeStruct2 28 Field5 *TypeStruct2 29 Field9 string 30 } 31 32 type TypeStruct3 struct { 33 Field1 interface{} 34 Field2 string 35 Field3 TypeStruct4 36 Field4 *TypeStruct4 37 Field5 []*TypeStruct4 38 Field6 []*TypeStruct4 39 Field7 []TypeStruct4 40 Field8 []TypeStruct4 41 } 42 43 type TypeStruct4 struct { 44 field1 int 45 Field2 string 46 } 47 48 func (t *TypeStruct4) Field1(i int) { 49 t.field1 = i 50 } 51 52 type TypeBaseStruct5 struct { 53 A bool 54 B byte 55 C float64 56 D int16 57 E int32 58 F int64 59 G time.Time 60 H string 61 } 62 63 type TypeSqlNullStruct6 struct { 64 A sql.NullBool `json:"a"` 65 B sql.NullByte `json:"b"` 66 C sql.NullFloat64 `json:"c"` 67 D sql.NullInt16 `json:"d"` 68 E sql.NullInt32 `json:"e"` 69 F sql.NullInt64 `json:"f"` 70 G sql.NullTime `json:"g"` 71 H sql.NullString `json:"h"` 72 } 73 74 func TestCopyDifferentFieldType(t *testing.T) { 75 ts := &TypeStruct1{ 76 Field1: "str1", 77 Field2: "str2", 78 } 79 ts2 := &TypeStruct2{} 80 81 copier.Copy(ts2, ts) 82 83 if ts2.Field2 != ts.Field2 || ts2.Field1 != 0 { 84 t.Errorf("Should be able to copy from ts to ts2") 85 } 86 } 87 88 func TestCopyDifferentTypeMethod(t *testing.T) { 89 ts := &TypeStruct1{ 90 Field1: "str1", 91 Field2: "str2", 92 } 93 ts4 := &TypeStruct4{} 94 95 copier.Copy(ts4, ts) 96 97 if ts4.Field2 != ts.Field2 || ts4.field1 != 0 { 98 t.Errorf("Should be able to copy from ts to ts4") 99 } 100 } 101 102 func TestAssignableType(t *testing.T) { 103 ts := &TypeStruct1{ 104 Field1: "str1", 105 Field2: "str2", 106 Field3: TypeStruct2{ 107 Field1: 666, 108 Field2: "str2", 109 }, 110 Field4: &TypeStruct2{ 111 Field1: 666, 112 Field2: "str2", 113 }, 114 Field5: []*TypeStruct2{ 115 { 116 Field1: 666, 117 Field2: "str2", 118 }, 119 }, 120 Field6: []TypeStruct2{ 121 { 122 Field1: 666, 123 Field2: "str2", 124 }, 125 }, 126 Field7: []*TypeStruct2{ 127 { 128 Field1: 666, 129 Field2: "str2", 130 }, 131 }, 132 } 133 134 ts3 := &TypeStruct3{} 135 136 copier.CopyWithOption(&ts3, &ts, copier.Option{CaseSensitive: true}) 137 138 if v, ok := ts3.Field1.(string); !ok { 139 t.Error("Assign to interface{} type did not succeed") 140 } else if v != "str1" { 141 t.Error("String haven't been copied correctly") 142 } 143 144 if ts3.Field2 != ts.Field2 { 145 t.Errorf("Field2 should be copied") 146 } 147 148 checkType2WithType4(ts.Field3, ts3.Field3, t, "Field3") 149 checkType2WithType4(*ts.Field4, *ts3.Field4, t, "Field4") 150 151 if len(ts3.Field5) != len(ts.Field5) { 152 t.Fatalf("fields not equal, got %v, expects: %v", len(ts3.Field5), len(ts.Field5)) 153 } 154 155 for idx, f := range ts.Field5 { 156 checkType2WithType4(*f, *(ts3.Field5[idx]), t, "Field5") 157 } 158 159 for idx, f := range ts.Field6 { 160 checkType2WithType4(f, *(ts3.Field6[idx]), t, "Field6") 161 } 162 163 for idx, f := range ts.Field7 { 164 checkType2WithType4(*f, ts3.Field7[idx], t, "Field7") 165 } 166 167 for idx, f := range ts.Field8 { 168 checkType2WithType4(f, ts3.Field8[idx], t, "Field8") 169 } 170 } 171 172 func checkType2WithType4(t2 TypeStruct2, t4 TypeStruct4, t *testing.T, testCase string) { 173 if t2.Field1 != t4.field1 || t2.Field2 != t4.Field2 { 174 t.Errorf("%v: type struct 4 and type struct 2 is not equal", testCase) 175 } 176 } 177 178 func TestCopyFromBaseToSqlNullWithOptionDeepCopy(t *testing.T) { 179 a := TypeBaseStruct5{ 180 A: true, 181 B: byte(2), 182 C: 5.5, 183 D: 1, 184 E: 2, 185 F: 3, 186 G: time.Now(), 187 H: "deep", 188 } 189 b := TypeSqlNullStruct6{} 190 191 err := copier.CopyWithOption(&b, a, copier.Option{DeepCopy: true}) 192 // 检查是否有错误 193 if err != nil { 194 t.Errorf("CopyStructWithOption() error = %v", err) 195 return 196 } 197 // 检查 b 结构体的字段是否符合预期 198 if !b.A.Valid || b.A.Bool != true { 199 t.Errorf("b.A = %v, want %v", b.A, true) 200 } 201 if !b.B.Valid || b.B.Byte != byte(2) { 202 t.Errorf("b.B = %v, want %v", b.B, byte(2)) 203 } 204 if !b.C.Valid || b.C.Float64 != 5.5 { 205 t.Errorf("b.C = %v, want %v", b.C, 5.5) 206 } 207 if !b.D.Valid || b.D.Int16 != 1 { 208 t.Errorf("b.D = %v, want %v", b.D, 1) 209 } 210 if !b.E.Valid || b.E.Int32 != 2 { 211 t.Errorf("b.E = %v, want %v", b.E, 2) 212 } 213 if !b.F.Valid || b.F.Int64 != 3 { 214 t.Errorf("b.F = %v, want %v", b.F, 3) 215 } 216 if !b.G.Valid || b.G.Time != a.G { 217 t.Errorf("b.G = %v, want %v", b.G, a.G) 218 } 219 if !b.H.Valid || b.H.String != "deep" { 220 t.Errorf("b.H = %v, want %v", b.H, "deep") 221 } 222 }