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  }