github.com/niubaoshu/goutils@v0.0.0-20180828035119-e8e576f66c2b/deepclone_test.go (about)

     1  package goutils
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  	"time"
     8  	"unsafe"
     9  )
    10  
    11  // just basic is this working stuff
    12  func TestSimple(t *testing.T) {
    13  	Strings := []string{"a", "b", "c"}
    14  	cpyS := DeepClone(Strings).([]string)
    15  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyS)).Data {
    16  		t.Error("[]string: expected SliceHeader data pointers to point to different locations, they didn't")
    17  		goto CopyBools
    18  	}
    19  	if len(cpyS) != len(Strings) {
    20  		t.Errorf("[]string: len was %d; want %d", len(cpyS), len(Strings))
    21  		goto CopyBools
    22  	}
    23  	for i, v := range Strings {
    24  		if v != cpyS[i] {
    25  			t.Errorf("[]string: got %v at index %d of the copy; want %v", cpyS[i], i, v)
    26  		}
    27  	}
    28  
    29  CopyBools:
    30  	Bools := []bool{true, true, false, false}
    31  	cpyB := DeepClone(Bools).([]bool)
    32  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyB)).Data {
    33  		t.Error("[]bool: expected SliceHeader data pointers to point to different locations, they didn't")
    34  		goto CopyBytes
    35  	}
    36  	if len(cpyB) != len(Bools) {
    37  		t.Errorf("[]bool: len was %d; want %d", len(cpyB), len(Bools))
    38  		goto CopyBytes
    39  	}
    40  	for i, v := range Bools {
    41  		if v != cpyB[i] {
    42  			t.Errorf("[]bool: got %v at index %d of the copy; want %v", cpyB[i], i, v)
    43  		}
    44  	}
    45  
    46  CopyBytes:
    47  	Bytes := []byte("hello")
    48  	cpyBt := DeepClone(Bytes).([]byte)
    49  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyBt)).Data {
    50  		t.Error("[]byte: expected SliceHeader data pointers to point to different locations, they didn't")
    51  		goto CopyInts
    52  	}
    53  	if len(cpyBt) != len(Bytes) {
    54  		t.Errorf("[]byte: len was %d; want %d", len(cpyBt), len(Bytes))
    55  		goto CopyInts
    56  	}
    57  	for i, v := range Bytes {
    58  		if v != cpyBt[i] {
    59  			t.Errorf("[]byte: got %v at index %d of the copy; want %v", cpyBt[i], i, v)
    60  		}
    61  	}
    62  
    63  CopyInts:
    64  	Ints := []int{42}
    65  	cpyI := DeepClone(Ints).([]int)
    66  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyI)).Data {
    67  		t.Error("[]int: expected SliceHeader data pointers to point to different locations, they didn't")
    68  		goto CopyUints
    69  	}
    70  	if len(cpyI) != len(Ints) {
    71  		t.Errorf("[]int: len was %d; want %d", len(cpyI), len(Ints))
    72  		goto CopyUints
    73  	}
    74  	for i, v := range Ints {
    75  		if v != cpyI[i] {
    76  			t.Errorf("[]int: got %v at index %d of the copy; want %v", cpyI[i], i, v)
    77  		}
    78  	}
    79  
    80  CopyUints:
    81  	Uints := []uint{1, 2, 3, 4, 5}
    82  	cpyU := DeepClone(Uints).([]uint)
    83  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyU)).Data {
    84  		t.Error("[]: expected SliceHeader data pointers to point to different locations, they didn't")
    85  		goto CopyFloat32s
    86  	}
    87  	if len(cpyU) != len(Uints) {
    88  		t.Errorf("[]uint: len was %d; want %d", len(cpyU), len(Uints))
    89  		goto CopyFloat32s
    90  	}
    91  	for i, v := range Uints {
    92  		if v != cpyU[i] {
    93  			t.Errorf("[]uint: got %v at index %d of the copy; want %v", cpyU[i], i, v)
    94  		}
    95  	}
    96  
    97  CopyFloat32s:
    98  	Float32s := []float32{3.14}
    99  	cpyF := DeepClone(Float32s).([]float32)
   100  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyF)).Data {
   101  		t.Error("[]float32: expected SliceHeader data pointers to point to different locations, they didn't")
   102  		goto CopyInterfaces
   103  	}
   104  	if len(cpyF) != len(Float32s) {
   105  		t.Errorf("[]float32: len was %d; want %d", len(cpyF), len(Float32s))
   106  		goto CopyInterfaces
   107  	}
   108  	for i, v := range Float32s {
   109  		if v != cpyF[i] {
   110  			t.Errorf("[]float32: got %v at index %d of the copy; want %v", cpyF[i], i, v)
   111  		}
   112  	}
   113  
   114  CopyInterfaces:
   115  	Interfaces := []interface{}{"a", 42, true, 4.32}
   116  	cpyIf := DeepClone(Interfaces).([]interface{})
   117  	if (*reflect.SliceHeader)(unsafe.Pointer(&Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyIf)).Data {
   118  		t.Error("[]interfaces: expected SliceHeader data pointers to point to different locations, they didn't")
   119  		return
   120  	}
   121  	if len(cpyIf) != len(Interfaces) {
   122  		t.Errorf("[]interface{}: len was %d; want %d", len(cpyIf), len(Interfaces))
   123  		return
   124  	}
   125  	for i, v := range Interfaces {
   126  		if v != cpyIf[i] {
   127  			t.Errorf("[]interface{}: got %v at index %d of the copy; want %v", cpyIf[i], i, v)
   128  		}
   129  	}
   130  }
   131  
   132  type Basics struct {
   133  	String      string
   134  	Strings     []string
   135  	StringArr   [4]string
   136  	Bool        bool
   137  	Bools       []bool
   138  	Byte        byte
   139  	Bytes       []byte
   140  	Int         int
   141  	Ints        []int
   142  	Int8        int8
   143  	Int8s       []int8
   144  	Int16       int16
   145  	Int16s      []int16
   146  	Int32       int32
   147  	Int32s      []int32
   148  	Int64       int64
   149  	Int64s      []int64
   150  	Uint        uint
   151  	Uints       []uint
   152  	Uint8       uint8
   153  	Uint8s      []uint8
   154  	Uint16      uint16
   155  	Uint16s     []uint16
   156  	Uint32      uint32
   157  	Uint32s     []uint32
   158  	Uint64      uint64
   159  	Uint64s     []uint64
   160  	Float32     float32
   161  	Float32s    []float32
   162  	Float64     float64
   163  	Float64s    []float64
   164  	Complex64   complex64
   165  	Complex64s  []complex64
   166  	Complex128  complex128
   167  	Complex128s []complex128
   168  	Interface   interface{}
   169  	Interfaces  []interface{}
   170  }
   171  
   172  // These tests test that all supported basic types are copied correctly.  This
   173  // is done by copying a struct with fields of most of the basic types as []T.
   174  func TestMostTypes(t *testing.T) {
   175  	test := Basics{
   176  		String:      "kimchi",
   177  		Strings:     []string{"uni", "ika"},
   178  		StringArr:   [4]string{"malort", "barenjager", "fernet", "salmiakki"},
   179  		Bool:        true,
   180  		Bools:       []bool{true, false, true},
   181  		Byte:        'z',
   182  		Bytes:       []byte("abc"),
   183  		Int:         42,
   184  		Ints:        []int{0, 1, 3, 4},
   185  		Int8:        8,
   186  		Int8s:       []int8{8, 9, 10},
   187  		Int16:       16,
   188  		Int16s:      []int16{16, 17, 18, 19},
   189  		Int32:       32,
   190  		Int32s:      []int32{32, 33},
   191  		Int64:       64,
   192  		Int64s:      []int64{64},
   193  		Uint:        420,
   194  		Uints:       []uint{11, 12, 13},
   195  		Uint8:       81,
   196  		Uint8s:      []uint8{81, 82},
   197  		Uint16:      160,
   198  		Uint16s:     []uint16{160, 161, 162, 163, 164},
   199  		Uint32:      320,
   200  		Uint32s:     []uint32{320, 321},
   201  		Uint64:      640,
   202  		Uint64s:     []uint64{6400, 6401, 6402, 6403},
   203  		Float32:     32.32,
   204  		Float32s:    []float32{32.32, 33},
   205  		Float64:     64.1,
   206  		Float64s:    []float64{64, 65, 66},
   207  		Complex64:   complex64(-64 + 12i),
   208  		Complex64s:  []complex64{complex64(-65 + 11i), complex64(66 + 10i)},
   209  		Complex128:  complex128(-128 + 12i),
   210  		Complex128s: []complex128{complex128(-128 + 11i), complex128(129 + 10i)},
   211  		Interfaces:  []interface{}{42, true, "pan-galactic"},
   212  	}
   213  
   214  	cpy := DeepClone(test).(Basics)
   215  
   216  	// see if they point to the same location
   217  	if fmt.Sprintf("%p", &cpy) == fmt.Sprintf("%p", &test) {
   218  		t.Error("address of copy was the same as original; they should be different")
   219  		return
   220  	}
   221  
   222  	// Go through each field and check to see it got copied properly
   223  	if cpy.String != test.String {
   224  		t.Errorf("String: got %v; want %v", cpy.String, test.String)
   225  	}
   226  
   227  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Strings)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Strings)).Data {
   228  		t.Error("Strings: address of copy was the same as original; they should be different")
   229  		goto StringArr
   230  	}
   231  
   232  	if len(cpy.Strings) != len(test.Strings) {
   233  		t.Errorf("Strings: len was %d; want %d", len(cpy.Strings), len(test.Strings))
   234  		goto StringArr
   235  	}
   236  	for i, v := range test.Strings {
   237  		if v != cpy.Strings[i] {
   238  			t.Errorf("Strings: got %v at index %d of the copy; want %v", cpy.Strings[i], i, v)
   239  		}
   240  	}
   241  
   242  StringArr:
   243  	if unsafe.Pointer(&test.StringArr) == unsafe.Pointer(&cpy.StringArr) {
   244  		t.Error("StringArr: address of copy was the same as original; they should be different")
   245  		goto Bools
   246  	}
   247  	for i, v := range test.StringArr {
   248  		if v != cpy.StringArr[i] {
   249  			t.Errorf("StringArr: got %v at index %d of the copy; want %v", cpy.StringArr[i], i, v)
   250  		}
   251  	}
   252  
   253  Bools:
   254  	if cpy.Bool != test.Bool {
   255  		t.Errorf("Bool: got %v; want %v", cpy.Bool, test.Bool)
   256  	}
   257  
   258  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Bools)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Bools)).Data {
   259  		t.Error("Bools: address of copy was the same as original; they should be different")
   260  		goto Bytes
   261  	}
   262  	if len(cpy.Bools) != len(test.Bools) {
   263  		t.Errorf("Bools: len was %d; want %d", len(cpy.Bools), len(test.Bools))
   264  		goto Bytes
   265  	}
   266  	for i, v := range test.Bools {
   267  		if v != cpy.Bools[i] {
   268  			t.Errorf("Bools: got %v at index %d of the copy; want %v", cpy.Bools[i], i, v)
   269  		}
   270  	}
   271  
   272  Bytes:
   273  	if cpy.Byte != test.Byte {
   274  		t.Errorf("Byte: got %v; want %v", cpy.Byte, test.Byte)
   275  	}
   276  
   277  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Bytes)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Bytes)).Data {
   278  		t.Error("Bytes: address of copy was the same as original; they should be different")
   279  		goto Ints
   280  	}
   281  	if len(cpy.Bytes) != len(test.Bytes) {
   282  		t.Errorf("Bytes: len was %d; want %d", len(cpy.Bytes), len(test.Bytes))
   283  		goto Ints
   284  	}
   285  	for i, v := range test.Bytes {
   286  		if v != cpy.Bytes[i] {
   287  			t.Errorf("Bytes: got %v at index %d of the copy; want %v", cpy.Bytes[i], i, v)
   288  		}
   289  	}
   290  
   291  Ints:
   292  	if cpy.Int != test.Int {
   293  		t.Errorf("Int: got %v; want %v", cpy.Int, test.Int)
   294  	}
   295  
   296  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Ints)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Ints)).Data {
   297  		t.Error("Ints: address of copy was the same as original; they should be different")
   298  		goto Int8s
   299  	}
   300  	if len(cpy.Ints) != len(test.Ints) {
   301  		t.Errorf("Ints: len was %d; want %d", len(cpy.Ints), len(test.Ints))
   302  		goto Int8s
   303  	}
   304  	for i, v := range test.Ints {
   305  		if v != cpy.Ints[i] {
   306  			t.Errorf("Ints: got %v at index %d of the copy; want %v", cpy.Ints[i], i, v)
   307  		}
   308  	}
   309  
   310  Int8s:
   311  	if cpy.Int8 != test.Int8 {
   312  		t.Errorf("Int8: got %v; want %v", cpy.Int8, test.Int8)
   313  	}
   314  
   315  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Int8s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Int8s)).Data {
   316  		t.Error("Int8s: address of copy was the same as original; they should be different")
   317  		goto Int16s
   318  	}
   319  	if len(cpy.Int8s) != len(test.Int8s) {
   320  		t.Errorf("Int8s: len was %d; want %d", len(cpy.Int8s), len(test.Int8s))
   321  		goto Int16s
   322  	}
   323  	for i, v := range test.Int8s {
   324  		if v != cpy.Int8s[i] {
   325  			t.Errorf("Int8s: got %v at index %d of the copy; want %v", cpy.Int8s[i], i, v)
   326  		}
   327  	}
   328  
   329  Int16s:
   330  	if cpy.Int16 != test.Int16 {
   331  		t.Errorf("Int16: got %v; want %v", cpy.Int16, test.Int16)
   332  	}
   333  
   334  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Int16s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Int16s)).Data {
   335  		t.Error("Int16s: address of copy was the same as original; they should be different")
   336  		goto Int32s
   337  	}
   338  	if len(cpy.Int16s) != len(test.Int16s) {
   339  		t.Errorf("Int16s: len was %d; want %d", len(cpy.Int16s), len(test.Int16s))
   340  		goto Int32s
   341  	}
   342  	for i, v := range test.Int16s {
   343  		if v != cpy.Int16s[i] {
   344  			t.Errorf("Int16s: got %v at index %d of the copy; want %v", cpy.Int16s[i], i, v)
   345  		}
   346  	}
   347  
   348  Int32s:
   349  	if cpy.Int32 != test.Int32 {
   350  		t.Errorf("Int32: got %v; want %v", cpy.Int32, test.Int32)
   351  	}
   352  
   353  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Int32s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Int32s)).Data {
   354  		t.Error("Int32s: address of copy was the same as original; they should be different")
   355  		goto Int64s
   356  	}
   357  	if len(cpy.Int32s) != len(test.Int32s) {
   358  		t.Errorf("Int32s: len was %d; want %d", len(cpy.Int32s), len(test.Int32s))
   359  		goto Int64s
   360  	}
   361  	for i, v := range test.Int32s {
   362  		if v != cpy.Int32s[i] {
   363  			t.Errorf("Int32s: got %v at index %d of the copy; want %v", cpy.Int32s[i], i, v)
   364  		}
   365  	}
   366  
   367  Int64s:
   368  	if cpy.Int64 != test.Int64 {
   369  		t.Errorf("Int64: got %v; want %v", cpy.Int64, test.Int64)
   370  	}
   371  
   372  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Int64s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Int64s)).Data {
   373  		t.Error("Int64s: address of copy was the same as original; they should be different")
   374  		goto Uints
   375  	}
   376  	if len(cpy.Int64s) != len(test.Int64s) {
   377  		t.Errorf("Int64s: len was %d; want %d", len(cpy.Int64s), len(test.Int64s))
   378  		goto Uints
   379  	}
   380  	for i, v := range test.Int64s {
   381  		if v != cpy.Int64s[i] {
   382  			t.Errorf("Int64s: got %v at index %d of the copy; want %v", cpy.Int64s[i], i, v)
   383  		}
   384  	}
   385  
   386  Uints:
   387  	if cpy.Uint != test.Uint {
   388  		t.Errorf("Uint: got %v; want %v", cpy.Uint, test.Uint)
   389  	}
   390  
   391  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Uints)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Uints)).Data {
   392  		t.Error("Uints: address of copy was the same as original; they should be different")
   393  		goto Uint8s
   394  	}
   395  	if len(cpy.Uints) != len(test.Uints) {
   396  		t.Errorf("Uints: len was %d; want %d", len(cpy.Uints), len(test.Uints))
   397  		goto Uint8s
   398  	}
   399  	for i, v := range test.Uints {
   400  		if v != cpy.Uints[i] {
   401  			t.Errorf("Uints: got %v at index %d of the copy; want %v", cpy.Uints[i], i, v)
   402  		}
   403  	}
   404  
   405  Uint8s:
   406  	if cpy.Uint8 != test.Uint8 {
   407  		t.Errorf("Uint8: got %v; want %v", cpy.Uint8, test.Uint8)
   408  	}
   409  
   410  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Uint8s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Uint8s)).Data {
   411  		t.Error("Uint8s: address of copy was the same as original; they should be different")
   412  		goto Uint16s
   413  	}
   414  	if len(cpy.Uint8s) != len(test.Uint8s) {
   415  		t.Errorf("Uint8s: len was %d; want %d", len(cpy.Uint8s), len(test.Uint8s))
   416  		goto Uint16s
   417  	}
   418  	for i, v := range test.Uint8s {
   419  		if v != cpy.Uint8s[i] {
   420  			t.Errorf("Uint8s: got %v at index %d of the copy; want %v", cpy.Uint8s[i], i, v)
   421  		}
   422  	}
   423  
   424  Uint16s:
   425  	if cpy.Uint16 != test.Uint16 {
   426  		t.Errorf("Uint16: got %v; want %v", cpy.Uint16, test.Uint16)
   427  	}
   428  
   429  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Uint16s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Uint16s)).Data {
   430  		t.Error("Uint16s: address of copy was the same as original; they should be different")
   431  		goto Uint32s
   432  	}
   433  	if len(cpy.Uint16s) != len(test.Uint16s) {
   434  		t.Errorf("Uint16s: len was %d; want %d", len(cpy.Uint16s), len(test.Uint16s))
   435  		goto Uint32s
   436  	}
   437  	for i, v := range test.Uint16s {
   438  		if v != cpy.Uint16s[i] {
   439  			t.Errorf("Uint16s: got %v at index %d of the copy; want %v", cpy.Uint16s[i], i, v)
   440  		}
   441  	}
   442  
   443  Uint32s:
   444  	if cpy.Uint32 != test.Uint32 {
   445  		t.Errorf("Uint32: got %v; want %v", cpy.Uint32, test.Uint32)
   446  	}
   447  
   448  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Uint32s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Uint32s)).Data {
   449  		t.Error("Uint32s: address of copy was the same as original; they should be different")
   450  		goto Uint64s
   451  	}
   452  	if len(cpy.Uint32s) != len(test.Uint32s) {
   453  		t.Errorf("Uint32s: len was %d; want %d", len(cpy.Uint32s), len(test.Uint32s))
   454  		goto Uint64s
   455  	}
   456  	for i, v := range test.Uint32s {
   457  		if v != cpy.Uint32s[i] {
   458  			t.Errorf("Uint32s: got %v at index %d of the copy; want %v", cpy.Uint32s[i], i, v)
   459  		}
   460  	}
   461  
   462  Uint64s:
   463  	if cpy.Uint64 != test.Uint64 {
   464  		t.Errorf("Uint64: got %v; want %v", cpy.Uint64, test.Uint64)
   465  	}
   466  
   467  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Uint64s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Uint64s)).Data {
   468  		t.Error("Uint64s: address of copy was the same as original; they should be different")
   469  		goto Float32s
   470  	}
   471  	if len(cpy.Uint64s) != len(test.Uint64s) {
   472  		t.Errorf("Uint64s: len was %d; want %d", len(cpy.Uint64s), len(test.Uint64s))
   473  		goto Float32s
   474  	}
   475  	for i, v := range test.Uint64s {
   476  		if v != cpy.Uint64s[i] {
   477  			t.Errorf("Uint64s: got %v at index %d of the copy; want %v", cpy.Uint64s[i], i, v)
   478  		}
   479  	}
   480  
   481  Float32s:
   482  	if cpy.Float32 != test.Float32 {
   483  		t.Errorf("Float32: got %v; want %v", cpy.Float32, test.Float32)
   484  	}
   485  
   486  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Float32s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Float32s)).Data {
   487  		t.Error("Float32s: address of copy was the same as original; they should be different")
   488  		goto Float64s
   489  	}
   490  	if len(cpy.Float32s) != len(test.Float32s) {
   491  		t.Errorf("Float32s: len was %d; want %d", len(cpy.Float32s), len(test.Float32s))
   492  		goto Float64s
   493  	}
   494  	for i, v := range test.Float32s {
   495  		if v != cpy.Float32s[i] {
   496  			t.Errorf("Float32s: got %v at index %d of the copy; want %v", cpy.Float32s[i], i, v)
   497  		}
   498  	}
   499  
   500  Float64s:
   501  	if cpy.Float64 != test.Float64 {
   502  		t.Errorf("Float64: got %v; want %v", cpy.Float64, test.Float64)
   503  	}
   504  
   505  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Float64s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Float64s)).Data {
   506  		t.Error("Float64s: address of copy was the same as original; they should be different")
   507  		goto Complex64s
   508  	}
   509  	if len(cpy.Float64s) != len(test.Float64s) {
   510  		t.Errorf("Float64s: len was %d; want %d", len(cpy.Float64s), len(test.Float64s))
   511  		goto Complex64s
   512  	}
   513  	for i, v := range test.Float64s {
   514  		if v != cpy.Float64s[i] {
   515  			t.Errorf("Float64s: got %v at index %d of the copy; want %v", cpy.Float64s[i], i, v)
   516  		}
   517  	}
   518  
   519  Complex64s:
   520  	if cpy.Complex64 != test.Complex64 {
   521  		t.Errorf("Complex64: got %v; want %v", cpy.Complex64, test.Complex64)
   522  	}
   523  
   524  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Complex64s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Complex64s)).Data {
   525  		t.Error("Complex64s: address of copy was the same as original; they should be different")
   526  		goto Complex128s
   527  	}
   528  	if len(cpy.Complex64s) != len(test.Complex64s) {
   529  		t.Errorf("Complex64s: len was %d; want %d", len(cpy.Complex64s), len(test.Complex64s))
   530  		goto Complex128s
   531  	}
   532  	for i, v := range test.Complex64s {
   533  		if v != cpy.Complex64s[i] {
   534  			t.Errorf("Complex64s: got %v at index %d of the copy; want %v", cpy.Complex64s[i], i, v)
   535  		}
   536  	}
   537  
   538  Complex128s:
   539  	if cpy.Complex128 != test.Complex128 {
   540  		t.Errorf("Complex128s: got %v; want %v", cpy.Complex128s, test.Complex128s)
   541  	}
   542  
   543  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Complex128s)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Complex128s)).Data {
   544  		t.Error("Complex128s: address of copy was the same as original; they should be different")
   545  		goto Interfaces
   546  	}
   547  	if len(cpy.Complex128s) != len(test.Complex128s) {
   548  		t.Errorf("Complex128s: len was %d; want %d", len(cpy.Complex128s), len(test.Complex128s))
   549  		goto Interfaces
   550  	}
   551  	for i, v := range test.Complex128s {
   552  		if v != cpy.Complex128s[i] {
   553  			t.Errorf("Complex128s: got %v at index %d of the copy; want %v", cpy.Complex128s[i], i, v)
   554  		}
   555  	}
   556  
   557  Interfaces:
   558  	if cpy.Interface != test.Interface {
   559  		t.Errorf("Interface: got %v; want %v", cpy.Interface, test.Interface)
   560  	}
   561  
   562  	if (*reflect.SliceHeader)(unsafe.Pointer(&test.Interfaces)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.Interfaces)).Data {
   563  		t.Error("Interfaces: address of copy was the same as original; they should be different")
   564  		return
   565  	}
   566  	if len(cpy.Interfaces) != len(test.Interfaces) {
   567  		t.Errorf("Interfaces: len was %d; want %d", len(cpy.Interfaces), len(test.Interfaces))
   568  		return
   569  	}
   570  	for i, v := range test.Interfaces {
   571  		if v != cpy.Interfaces[i] {
   572  			t.Errorf("Interfaces: got %v at index %d of the copy; want %v", cpy.Interfaces[i], i, v)
   573  		}
   574  	}
   575  }
   576  
   577  // not meant to be exhaustive
   578  func TestComplexSlices(t *testing.T) {
   579  	orig3Int := [][][]int{[][]int{[]int{1, 2, 3}, []int{11, 22, 33}}, [][]int{[]int{7, 8, 9}, []int{66, 77, 88, 99}}}
   580  	cpyI := DeepClone(orig3Int).([][][]int)
   581  	if (*reflect.SliceHeader)(unsafe.Pointer(&orig3Int)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyI)).Data {
   582  		t.Error("[][][]int: address of copy was the same as original; they should be different")
   583  		return
   584  	}
   585  	if len(orig3Int) != len(cpyI) {
   586  		t.Errorf("[][][]int: len of copy was %d; want %d", len(cpyI), len(orig3Int))
   587  		goto sliceMap
   588  	}
   589  	for i, v := range orig3Int {
   590  		if len(v) != len(cpyI[i]) {
   591  			t.Errorf("[][][]int: len of element %d was %d; want %d", i, len(cpyI[i]), len(v))
   592  			continue
   593  		}
   594  		for j, vv := range v {
   595  			if len(vv) != len(cpyI[i][j]) {
   596  				t.Errorf("[][][]int: len of element %d:%d was %d, want %d", i, j, len(cpyI[i][j]), len(vv))
   597  				continue
   598  			}
   599  			for k, vvv := range vv {
   600  				if vvv != cpyI[i][j][k] {
   601  					t.Errorf("[][][]int: element %d:%d:%d was %d, want %d", i, j, k, cpyI[i][j][k], vvv)
   602  				}
   603  			}
   604  		}
   605  
   606  	}
   607  
   608  sliceMap:
   609  	slMap := []map[int]string{map[int]string{0: "a", 1: "b"}, map[int]string{10: "k", 11: "l", 12: "m"}}
   610  	cpyM := DeepClone(slMap).([]map[int]string)
   611  	if (*reflect.SliceHeader)(unsafe.Pointer(&slMap)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpyM)).Data {
   612  		t.Error("[]map[int]string: address of copy was the same as original; they should be different")
   613  	}
   614  	if len(slMap) != len(cpyM) {
   615  		t.Errorf("[]map[int]string: len of copy was %d; want %d", len(cpyM), len(slMap))
   616  		goto done
   617  	}
   618  	for i, v := range slMap {
   619  		if len(v) != len(cpyM[i]) {
   620  			t.Errorf("[]map[int]string: len of element %d was %d; want %d", i, len(cpyM[i]), len(v))
   621  			continue
   622  		}
   623  		for k, vv := range v {
   624  			val, ok := cpyM[i][k]
   625  			if !ok {
   626  				t.Errorf("[]map[int]string: element %d was expected to have a value at key %d, it didn't", i, k)
   627  				continue
   628  			}
   629  			if val != vv {
   630  				t.Errorf("[]map[int]string: element %d, key %d: got %s, want %s", i, k, val, vv)
   631  			}
   632  		}
   633  	}
   634  done:
   635  }
   636  
   637  type A struct {
   638  	Int    int
   639  	String string
   640  	UintSl []uint
   641  	NilSl  []string
   642  	Map    map[string]int
   643  	MapB   map[string]*B
   644  	SliceB []B
   645  	B
   646  	T time.Time
   647  }
   648  
   649  type B struct {
   650  	Vals []string
   651  }
   652  
   653  var AStruct = A{
   654  	Int:    42,
   655  	String: "Konichiwa",
   656  	UintSl: []uint{0, 1, 2, 3},
   657  	Map:    map[string]int{"a": 1, "b": 2},
   658  	MapB: map[string]*B{
   659  		"hi":  &B{Vals: []string{"hello", "bonjour"}},
   660  		"bye": &B{Vals: []string{"good-bye", "au revoir"}},
   661  	},
   662  	SliceB: []B{
   663  		B{Vals: []string{"Ciao", "Aloha"}},
   664  	},
   665  	B: B{Vals: []string{"42"}},
   666  	T: time.Now(),
   667  }
   668  
   669  func TestStructA(t *testing.T) {
   670  	cpy := DeepClone(AStruct).(A)
   671  	if &cpy == &AStruct {
   672  		t.Error("expected copy to have a different address than the original; it was the same")
   673  		return
   674  	}
   675  	if cpy.Int != AStruct.Int {
   676  		t.Errorf("A.Int: got %v, want %v", cpy.Int, AStruct.Int)
   677  	}
   678  	if cpy.String != AStruct.String {
   679  		t.Errorf("A.String: got %v; want %v", cpy.String, AStruct.String)
   680  	}
   681  	if (*reflect.SliceHeader)(unsafe.Pointer(&cpy.UintSl)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&AStruct.UintSl)).Data {
   682  		t.Error("A.Uintsl: expected the copies address to be different; it wasn't")
   683  		goto NilSl
   684  	}
   685  	if len(cpy.UintSl) != len(AStruct.UintSl) {
   686  		t.Errorf("A.UintSl: got len of %d, want %d", len(cpy.UintSl), len(AStruct.UintSl))
   687  		goto NilSl
   688  	}
   689  	for i, v := range AStruct.UintSl {
   690  		if cpy.UintSl[i] != v {
   691  			t.Errorf("A.UintSl %d: got %d, want %d", i, cpy.UintSl[i], v)
   692  		}
   693  	}
   694  
   695  NilSl:
   696  	if cpy.NilSl != nil {
   697  		t.Error("A.NilSl: expected slice to be nil, it wasn't")
   698  	}
   699  
   700  	if *(*uintptr)(unsafe.Pointer(&cpy.Map)) == *(*uintptr)(unsafe.Pointer(&AStruct.Map)) {
   701  		t.Error("A.Map: expected the copy's address to be different; it wasn't")
   702  		goto AMapB
   703  	}
   704  	if len(cpy.Map) != len(AStruct.Map) {
   705  		t.Errorf("A.Map: got len of %d, want %d", len(cpy.Map), len(AStruct.Map))
   706  		goto AMapB
   707  	}
   708  	for k, v := range AStruct.Map {
   709  		val, ok := cpy.Map[k]
   710  		if !ok {
   711  			t.Errorf("A.Map: expected the key %s to exist in the copy, it didn't", k)
   712  			continue
   713  		}
   714  		if val != v {
   715  			t.Errorf("A.Map[%s]: got %d, want %d", k, val, v)
   716  		}
   717  	}
   718  
   719  AMapB:
   720  	if *(*uintptr)(unsafe.Pointer(&cpy.MapB)) == *(*uintptr)(unsafe.Pointer(&AStruct.MapB)) {
   721  		t.Error("A.MapB: expected the copy's address to be different; it wasn't")
   722  		goto ASliceB
   723  	}
   724  	if len(cpy.MapB) != len(AStruct.MapB) {
   725  		t.Errorf("A.MapB: got len of %d, want %d", len(cpy.MapB), len(AStruct.MapB))
   726  		goto ASliceB
   727  	}
   728  	for k, v := range AStruct.MapB {
   729  		val, ok := cpy.MapB[k]
   730  		if !ok {
   731  			t.Errorf("A.MapB: expected the key %s to exist in the copy, it didn't", k)
   732  			continue
   733  		}
   734  		if unsafe.Pointer(val) == unsafe.Pointer(v) {
   735  			t.Errorf("A.MapB[%s]: expected the addresses of the values to be different; they weren't", k)
   736  			continue
   737  		}
   738  		// the slice headers should point to different data
   739  		if (*reflect.SliceHeader)(unsafe.Pointer(&v.Vals)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&val.Vals)).Data {
   740  			t.Errorf("%s: expected B's SliceHeaders to point to different Data locations; they did not.", k)
   741  			continue
   742  		}
   743  		for i, vv := range v.Vals {
   744  			if vv != val.Vals[i] {
   745  				t.Errorf("A.MapB[%s].Vals[%d]: got %s want %s", k, i, vv, val.Vals[i])
   746  			}
   747  		}
   748  	}
   749  
   750  ASliceB:
   751  	if (*reflect.SliceHeader)(unsafe.Pointer(&AStruct.SliceB)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.SliceB)).Data {
   752  		t.Error("A.SliceB: expected the copy's address to be different; it wasn't")
   753  		goto B
   754  	}
   755  
   756  	if len(AStruct.SliceB) != len(cpy.SliceB) {
   757  		t.Errorf("A.SliceB: got length of %d; want %d", len(cpy.SliceB), len(AStruct.SliceB))
   758  		goto B
   759  	}
   760  
   761  	for i := range AStruct.SliceB {
   762  		if unsafe.Pointer(&AStruct.SliceB[i]) == unsafe.Pointer(&cpy.SliceB[i]) {
   763  			t.Errorf("A.SliceB[%d]: expected them to have different addresses, they didn't", i)
   764  			continue
   765  		}
   766  		if (*reflect.SliceHeader)(unsafe.Pointer(&AStruct.SliceB[i].Vals)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.SliceB[i].Vals)).Data {
   767  			t.Errorf("A.SliceB[%d]: expected B.Vals SliceHeader.Data to point to different locations; they did not", i)
   768  			continue
   769  		}
   770  		if len(AStruct.SliceB[i].Vals) != len(cpy.SliceB[i].Vals) {
   771  			t.Errorf("A.SliceB[%d]: expected B's vals to have the same length, they didn't", i)
   772  			continue
   773  		}
   774  		for j, val := range AStruct.SliceB[i].Vals {
   775  			if val != cpy.SliceB[i].Vals[j] {
   776  				t.Errorf("A.SliceB[%d].Vals[%d]: got %v; want %v", i, j, cpy.SliceB[i].Vals[j], val)
   777  			}
   778  		}
   779  	}
   780  B:
   781  	if unsafe.Pointer(&AStruct.B) == unsafe.Pointer(&cpy.B) {
   782  		t.Error("A.B: expected them to have different addresses, they didn't")
   783  		goto T
   784  	}
   785  	if (*reflect.SliceHeader)(unsafe.Pointer(&AStruct.B.Vals)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&cpy.B.Vals)).Data {
   786  		t.Error("A.B.Vals: expected the SliceHeaders.Data to point to different locations; they didn't")
   787  		goto T
   788  	}
   789  	if len(AStruct.B.Vals) != len(cpy.B.Vals) {
   790  		t.Error("A.B.Vals: expected their lengths to be the same, they weren't")
   791  		goto T
   792  	}
   793  	for i, v := range AStruct.B.Vals {
   794  		if v != cpy.B.Vals[i] {
   795  			t.Errorf("A.B.Vals[%d]: got %s want %s", i, cpy.B.Vals[i], v)
   796  		}
   797  	}
   798  T:
   799  	if fmt.Sprintf("%p", &AStruct.T) == fmt.Sprintf("%p", &cpy.T) {
   800  		t.Error("A.T: expected them to have different addresses, they didn't")
   801  		return
   802  	}
   803  	if !AStruct.T.Equal(cpy.T) {
   804  		t.Errorf("A.T: got %v, want %v", cpy.T, AStruct.T)
   805  	}
   806  }
   807  
   808  type Unexported struct {
   809  	A  string
   810  	B  int
   811  	aa string
   812  	bb int
   813  }
   814  
   815  func TestUnexportedFields(t *testing.T) {
   816  	u := &Unexported{
   817  		A:  "A",
   818  		B:  42,
   819  		aa: "aa",
   820  		bb: 42,
   821  	}
   822  	cpy := DeepClone(u).(*Unexported)
   823  	if cpy == u {
   824  		t.Error("expected addresses to be different, they weren't")
   825  		return
   826  	}
   827  	if u.A != cpy.A {
   828  		t.Errorf("Unexported.A: got %s want %s", cpy.A, u.A)
   829  	}
   830  	if u.B != cpy.B {
   831  		t.Errorf("Unexported.A: got %d want %d", cpy.B, u.B)
   832  	}
   833  	if cpy.aa != u.aa {
   834  		t.Errorf("Unexported.aa: got %s want %s ", cpy.aa, u.aa)
   835  	}
   836  	if cpy.bb != u.bb {
   837  		t.Errorf("Unexported.bb: got %d want %d", cpy.bb, u.bb)
   838  	}
   839  }
   840  
   841  // Note: this test will fail until https://github.com/golang/go/issues/15716 is
   842  // fixed and the version it is part of gets released.
   843  type T struct {
   844  	time.Time
   845  }
   846  
   847  func TestTimeDeepClone(t *testing.T) {
   848  	tests := []struct {
   849  		Y    int
   850  		M    time.Month
   851  		D    int
   852  		h    int
   853  		m    int
   854  		s    int
   855  		nsec int
   856  		TZ   string
   857  	}{
   858  		{2016, time.July, 4, 23, 11, 33, 3000, "America/New_York"},
   859  		{2015, time.October, 31, 9, 44, 23, 45935, "UTC"},
   860  		{2014, time.May, 5, 22, 01, 50, 219300, "Europe/Prague"},
   861  	}
   862  
   863  	for i, test := range tests {
   864  		l, err := time.LoadLocation(test.TZ)
   865  		if err != nil {
   866  			t.Errorf("%d: unexpected error: %s", i, err)
   867  			continue
   868  		}
   869  		var x T
   870  		x.Time = time.Date(test.Y, test.M, test.D, test.h, test.m, test.s, test.nsec, l)
   871  		c := DeepClone(x).(T)
   872  
   873  		if !x.Time.Equal(c.Time) {
   874  			t.Errorf("%d: time: got %v; want %v", i, &c, &x)
   875  			continue
   876  		}
   877  
   878  		if fmt.Sprintf("%p", &c) == fmt.Sprintf("%p", &x) {
   879  			t.Errorf("%d: expected the copy to have a different address than the original value; they were the same: %p %p", i, &c, &x)
   880  			continue
   881  		}
   882  		if x.UnixNano() != c.UnixNano() {
   883  			t.Errorf("%d: nanotime: got %v; want %v", i, c.UnixNano(), x.UnixNano())
   884  			continue
   885  		}
   886  		if x.Location().String() != c.Location().String() {
   887  			t.Errorf("%d: location: got %q; want %q", i, c.Location(), x.Location())
   888  		}
   889  	}
   890  }
   891  
   892  func TestPointerToStruct(t *testing.T) {
   893  	type Foo struct {
   894  		Bar int
   895  	}
   896  
   897  	f := &Foo{Bar: 42}
   898  	cpy := DeepClone(f)
   899  	if f == cpy {
   900  		t.Errorf("expected copy to point to a different location: orig: %p; copy: %p", f, cpy)
   901  	}
   902  	if !reflect.DeepEqual(f, cpy) {
   903  		t.Errorf("expected the copy to be equal to the original (except for memory location); it wasn't: got %#v; want %#v", f, cpy)
   904  	}
   905  }
   906  
   907  func TestIssue9(t *testing.T) {
   908  	// simple pointer copy
   909  	x := 42
   910  	testA := map[string]*int{
   911  		"a": nil,
   912  		"b": &x,
   913  	}
   914  	copyA := DeepClone(testA).(map[string]*int)
   915  	if unsafe.Pointer(&testA) == unsafe.Pointer(&copyA) {
   916  		t.Fatalf("expected the map pointers to be different: testA: %v\tcopyA: %v", unsafe.Pointer(&testA), unsafe.Pointer(&copyA))
   917  	}
   918  	if !reflect.DeepEqual(testA, copyA) {
   919  		t.Errorf("got %#v; want %#v", copyA, testA)
   920  	}
   921  	if testA["b"] == copyA["b"] {
   922  		t.Errorf("entries for 'b' pointed to the same address: %v; expected them to point to different addresses", testA["b"])
   923  	}
   924  
   925  	// map copy
   926  	type Foo struct {
   927  		Alpha string
   928  	}
   929  
   930  	type Bar struct {
   931  		Beta  string
   932  		Gamma int
   933  		Delta *Foo
   934  	}
   935  
   936  	type Biz struct {
   937  		Epsilon map[int]*Bar
   938  	}
   939  
   940  	testB := Biz{
   941  		Epsilon: map[int]*Bar{
   942  			0: &Bar{},
   943  			1: &Bar{
   944  				Beta:  "don't panic",
   945  				Gamma: 42,
   946  				Delta: nil,
   947  			},
   948  			2: &Bar{
   949  				Beta:  "sudo make me a sandwich.",
   950  				Gamma: 11,
   951  				Delta: &Foo{
   952  					Alpha: "okay.",
   953  				},
   954  			},
   955  		},
   956  	}
   957  
   958  	copyB := DeepClone(testB).(Biz)
   959  	if !reflect.DeepEqual(testB, copyB) {
   960  		t.Errorf("got %#v; want %#v", copyB, testB)
   961  		return
   962  	}
   963  
   964  	// check that the maps point to different locations
   965  	if unsafe.Pointer(&testB.Epsilon) == unsafe.Pointer(&copyB.Epsilon) {
   966  		t.Fatalf("expected the map pointers to be different; they weren't: testB: %v\tcopyB: %v", unsafe.Pointer(&testB.Epsilon), unsafe.Pointer(&copyB.Epsilon))
   967  	}
   968  
   969  	for k, v := range testB.Epsilon {
   970  		if v == nil && copyB.Epsilon[k] == nil {
   971  			continue
   972  		}
   973  		if v == nil && copyB.Epsilon[k] != nil {
   974  			t.Errorf("%d: expected copy of a nil entry to be nil; it wasn't: %#v", copyB.Epsilon[k])
   975  			continue
   976  		}
   977  		if v == copyB.Epsilon[k] {
   978  			t.Errorf("entries for '%d' pointed to the same address: %v; expected them to point to different addresses", v)
   979  			continue
   980  		}
   981  		if v.Beta != copyB.Epsilon[k].Beta {
   982  			t.Errorf("%d.Beta: got %q; want %q", copyB.Epsilon[k].Beta, v.Beta)
   983  		}
   984  		if v.Gamma != copyB.Epsilon[k].Gamma {
   985  			t.Errorf("%d.Gamma: got %d; want %d", copyB.Epsilon[k].Gamma, v.Gamma)
   986  		}
   987  		if v.Delta == nil && copyB.Epsilon[k].Delta == nil {
   988  			continue
   989  		}
   990  		if v.Delta == nil && copyB.Epsilon[k].Delta != nil {
   991  			t.Errorf("%d.Delta: got %#v; want nil", copyB.Epsilon[k].Delta)
   992  		}
   993  		if v.Delta == copyB.Epsilon[k].Delta {
   994  			t.Errorf("%d.Delta: expected the pointers to be different, they were the same: %v", k, v.Delta)
   995  			continue
   996  		}
   997  		if v.Delta.Alpha != copyB.Epsilon[k].Delta.Alpha {
   998  			t.Errorf("%d.Delta.Foo: got %q; want %q", v.Delta.Alpha, copyB.Epsilon[k].Delta.Alpha)
   999  		}
  1000  	}
  1001  
  1002  	// test that map keys are deep copied
  1003  	testC := map[*Foo][]string{
  1004  		&Foo{Alpha: "Henry Dorsett Case"}: []string{
  1005  			"Cutter",
  1006  		},
  1007  		&Foo{Alpha: "Molly Millions"}: []string{
  1008  			"Rose Kolodny",
  1009  			"Cat Mother",
  1010  			"Steppin' Razor",
  1011  		},
  1012  	}
  1013  
  1014  	copyC := DeepClone(testC).(map[*Foo][]string)
  1015  	if unsafe.Pointer(&testC) == unsafe.Pointer(&copyC) {
  1016  		t.Fatalf("expected the map pointers to be different; they weren't: testB: %v\tcopyB: %v", unsafe.Pointer(&testB.Epsilon), unsafe.Pointer(&copyB.Epsilon))
  1017  	}
  1018  
  1019  	// make sure the lengths are the same
  1020  	if len(testC) != len(copyC) {
  1021  		t.Fatalf("got len %d; want %d", len(copyC), len(testC))
  1022  	}
  1023  
  1024  	// check that everything was deep copied: since the key is a pointer, we check to
  1025  	// see if the pointers are different but the values being pointed to are the same.
  1026  	for k, v := range testC {
  1027  		for kk, vv := range copyC {
  1028  			if *kk == *k {
  1029  				if kk == k {
  1030  					t.Errorf("key pointers should be different: orig: %p; copy: %p", k, kk)
  1031  				}
  1032  				// check that the slices are the same but different
  1033  				if !reflect.DeepEqual(v, vv) {
  1034  					t.Errorf("expected slice contents to be the same; they weren't: orig: %v; copy: %v", v, vv)
  1035  				}
  1036  
  1037  				if (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&vv)).Data {
  1038  					t.Error("expected the SliceHeaders.Data to point to different locations; they didn't: %v", (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data)
  1039  				}
  1040  				break
  1041  			}
  1042  		}
  1043  	}
  1044  
  1045  	type Bizz struct {
  1046  		*Foo
  1047  	}
  1048  
  1049  	testD := map[Bizz]string{
  1050  		Bizz{&Foo{"Neuromancer"}}: "Rio",
  1051  		Bizz{&Foo{"Wintermute"}}:  "Berne",
  1052  	}
  1053  	copyD := DeepClone(testD).(map[Bizz]string)
  1054  	if len(copyD) != len(testD) {
  1055  		t.Fatalf("copy had %d elements; expected %d", len(copyD), len(testD))
  1056  	}
  1057  
  1058  	for k, v := range testD {
  1059  		var found bool
  1060  		for kk, vv := range copyD {
  1061  			if reflect.DeepEqual(k, kk) {
  1062  				found = true
  1063  				// check that Foo points to different locations
  1064  				if unsafe.Pointer(k.Foo) == unsafe.Pointer(kk.Foo) {
  1065  					t.Errorf("Expected Foo to point to different locations; they didn't: orig: %p; copy %p", k.Foo, kk.Foo)
  1066  					break
  1067  				}
  1068  				if *k.Foo != *kk.Foo {
  1069  					t.Errorf("Expected copy of the key's Foo field to have the same value as the original, it wasn't: orig: %#v; copy: %#v", k.Foo, kk.Foo)
  1070  				}
  1071  				if v != vv {
  1072  					t.Errorf("Expected the values to be the same; the weren't: got %v; want %v", vv, v)
  1073  				}
  1074  			}
  1075  		}
  1076  		if !found {
  1077  			t.Errorf("expected key %v to exist in the copy; it didn't", k)
  1078  		}
  1079  	}
  1080  }