1 package deepcopy
2
3 import (
4 "fmt"
5 "reflect"
6 "testing"
7 "time"
8 "unsafe"
9 )
10
11
12 func TestSimple(t *testing.T) {
13 Strings := []string{"a", "b", "c"}
14 cpyS := Copy(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 := Copy(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 := Copy(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 := Copy(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 := Copy(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 := Copy(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 := Copy(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
173
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 := Copy(test).(Basics)
215
216
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
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
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 := Copy(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 := Copy(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 := Copy(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
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 != 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 cc []int
814 dd map[string]string
815 }
816
817 func TestUnexportedFields(t *testing.T) {
818 u := &Unexported{
819 A: "A",
820 B: 42,
821 aa: "aa",
822 bb: 42,
823 cc: []int{1, 2, 3},
824 dd: map[string]string{"hello": "bonjour"},
825 }
826 cpy := Copy(u).(*Unexported)
827 if cpy == u {
828 t.Error("expected addresses to be different, they weren't")
829 return
830 }
831 if u.A != cpy.A {
832 t.Errorf("Unexported.A: got %s want %s", cpy.A, u.A)
833 }
834 if u.B != cpy.B {
835 t.Errorf("Unexported.A: got %d want %d", cpy.B, u.B)
836 }
837 if cpy.aa != "" {
838 t.Errorf("Unexported.aa: unexported field should not be set, it was set to %s", cpy.aa)
839 }
840 if cpy.bb != 0 {
841 t.Errorf("Unexported.bb: unexported field should not be set, it was set to %d", cpy.bb)
842 }
843 if cpy.cc != nil {
844 t.Errorf("Unexported.cc: unexported field should not be set, it was set to %#v", cpy.cc)
845 }
846 if cpy.dd != nil {
847 t.Errorf("Unexported.dd: unexported field should not be set, it was set to %#v", cpy.dd)
848 }
849 }
850
851
852
853 type T struct {
854 time.Time
855 }
856
857 func TestTimeCopy(t *testing.T) {
858 tests := []struct {
859 Y int
860 M time.Month
861 D int
862 h int
863 m int
864 s int
865 nsec int
866 TZ string
867 }{
868 {2016, time.July, 4, 23, 11, 33, 3000, "America/New_York"},
869 {2015, time.October, 31, 9, 44, 23, 45935, "UTC"},
870 {2014, time.May, 5, 22, 01, 50, 219300, "Europe/Prague"},
871 }
872
873 for i, test := range tests {
874 l, err := time.LoadLocation(test.TZ)
875 if err != nil {
876 t.Errorf("%d: unexpected error: %s", i, err)
877 continue
878 }
879 var x T
880 x.Time = time.Date(test.Y, test.M, test.D, test.h, test.m, test.s, test.nsec, l)
881 c := Copy(x).(T)
882 if fmt.Sprintf("%p", &c) == fmt.Sprintf("%p", &x) {
883 t.Errorf("%d: expected the copy to have a different address than the original value; they were the same: %p %p", i, &c, &x)
884 continue
885 }
886 if x.UnixNano() != c.UnixNano() {
887 t.Errorf("%d: nanotime: got %v; want %v", i, c.UnixNano(), x.UnixNano())
888 continue
889 }
890 if x.Location() != c.Location() {
891 t.Errorf("%d: location: got %q; want %q", i, c.Location(), x.Location())
892 }
893 }
894 }
895
896 func TestPointerToStruct(t *testing.T) {
897 type Foo struct {
898 Bar int
899 }
900
901 f := &Foo{Bar: 42}
902 cpy := Copy(f)
903 if f == cpy {
904 t.Errorf("expected copy to point to a different location: orig: %p; copy: %p", f, cpy)
905 }
906 if !reflect.DeepEqual(f, cpy) {
907 t.Errorf("expected the copy to be equal to the original (except for memory location); it wasn't: got %#v; want %#v", f, cpy)
908 }
909 }
910
911 func TestIssue9(t *testing.T) {
912
913 x := 42
914 testA := map[string]*int{
915 "a": nil,
916 "b": &x,
917 }
918 copyA := Copy(testA).(map[string]*int)
919 if unsafe.Pointer(&testA) == unsafe.Pointer(©A) {
920 t.Fatalf("expected the map pointers to be different: testA: %v\tcopyA: %v", unsafe.Pointer(&testA), unsafe.Pointer(©A))
921 }
922 if !reflect.DeepEqual(testA, copyA) {
923 t.Errorf("got %#v; want %#v", copyA, testA)
924 }
925 if testA["b"] == copyA["b"] {
926 t.Errorf("entries for 'b' pointed to the same address: %v; expected them to point to different addresses", testA["b"])
927 }
928
929
930 type Foo struct {
931 Alpha string
932 }
933
934 type Bar struct {
935 Beta string
936 Gamma int
937 Delta *Foo
938 }
939
940 type Biz struct {
941 Epsilon map[int]*Bar
942 }
943
944 testB := Biz{
945 Epsilon: map[int]*Bar{
946 0: &Bar{},
947 1: &Bar{
948 Beta: "don't panic",
949 Gamma: 42,
950 Delta: nil,
951 },
952 2: &Bar{
953 Beta: "sudo make me a sandwich.",
954 Gamma: 11,
955 Delta: &Foo{
956 Alpha: "okay.",
957 },
958 },
959 },
960 }
961
962 copyB := Copy(testB).(Biz)
963 if !reflect.DeepEqual(testB, copyB) {
964 t.Errorf("got %#v; want %#v", copyB, testB)
965 return
966 }
967
968
969 if unsafe.Pointer(&testB.Epsilon) == unsafe.Pointer(©B.Epsilon) {
970 t.Fatalf("expected the map pointers to be different; they weren't: testB: %v\tcopyB: %v", unsafe.Pointer(&testB.Epsilon), unsafe.Pointer(©B.Epsilon))
971 }
972
973 for k, v := range testB.Epsilon {
974 if v == nil && copyB.Epsilon[k] == nil {
975 continue
976 }
977 if v == nil && copyB.Epsilon[k] != nil {
978 t.Errorf("%d: expected copy of a nil entry to be nil; it wasn't: %#v", k, copyB.Epsilon[k])
979 continue
980 }
981 if v == copyB.Epsilon[k] {
982 t.Errorf("entries for '%d' pointed to the same address: %v; expected them to point to different addresses", k, v)
983 continue
984 }
985 if v.Beta != copyB.Epsilon[k].Beta {
986 t.Errorf("%d.Beta: got %q; want %q", k, copyB.Epsilon[k].Beta, v.Beta)
987 }
988 if v.Gamma != copyB.Epsilon[k].Gamma {
989 t.Errorf("%d.Gamma: got %d; want %d", k, copyB.Epsilon[k].Gamma, v.Gamma)
990 }
991 if v.Delta == nil && copyB.Epsilon[k].Delta == nil {
992 continue
993 }
994 if v.Delta == nil && copyB.Epsilon[k].Delta != nil {
995 t.Errorf("%d.Delta: got %#v; want nil", k, copyB.Epsilon[k].Delta)
996 }
997 if v.Delta == copyB.Epsilon[k].Delta {
998 t.Errorf("%d.Delta: expected the pointers to be different, they were the same: %v", k, v.Delta)
999 continue
1000 }
1001 if v.Delta.Alpha != copyB.Epsilon[k].Delta.Alpha {
1002 t.Errorf("%d.Delta.Foo: got %q; want %q", k, v.Delta.Alpha, copyB.Epsilon[k].Delta.Alpha)
1003 }
1004 }
1005
1006
1007 testC := map[*Foo][]string{
1008 &Foo{Alpha: "Henry Dorsett Case"}: []string{
1009 "Cutter",
1010 },
1011 &Foo{Alpha: "Molly Millions"}: []string{
1012 "Rose Kolodny",
1013 "Cat Mother",
1014 "Steppin' Razor",
1015 },
1016 }
1017
1018 copyC := Copy(testC).(map[*Foo][]string)
1019 if unsafe.Pointer(&testC) == unsafe.Pointer(©C) {
1020 t.Fatalf("expected the map pointers to be different; they weren't: testB: %v\tcopyB: %v", unsafe.Pointer(&testB.Epsilon), unsafe.Pointer(©B.Epsilon))
1021 }
1022
1023
1024 if len(testC) != len(copyC) {
1025 t.Fatalf("got len %d; want %d", len(copyC), len(testC))
1026 }
1027
1028
1029
1030 for k, v := range testC {
1031 for kk, vv := range copyC {
1032 if *kk == *k {
1033 if kk == k {
1034 t.Errorf("key pointers should be different: orig: %p; copy: %p", k, kk)
1035 }
1036
1037 if !reflect.DeepEqual(v, vv) {
1038 t.Errorf("expected slice contents to be the same; they weren't: orig: %v; copy: %v", v, vv)
1039 }
1040
1041 if (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data == (*reflect.SliceHeader)(unsafe.Pointer(&vv)).Data {
1042 t.Errorf("expected the SliceHeaders.Data to point to different locations; they didn't: %v", (*reflect.SliceHeader)(unsafe.Pointer(&v)).Data)
1043 }
1044 break
1045 }
1046 }
1047 }
1048
1049 type Bizz struct {
1050 *Foo
1051 }
1052
1053 testD := map[Bizz]string{
1054 Bizz{&Foo{"Neuromancer"}}: "Rio",
1055 Bizz{&Foo{"Wintermute"}}: "Berne",
1056 }
1057 copyD := Copy(testD).(map[Bizz]string)
1058 if len(copyD) != len(testD) {
1059 t.Fatalf("copy had %d elements; expected %d", len(copyD), len(testD))
1060 }
1061
1062 for k, v := range testD {
1063 var found bool
1064 for kk, vv := range copyD {
1065 if reflect.DeepEqual(k, kk) {
1066 found = true
1067
1068 if unsafe.Pointer(k.Foo) == unsafe.Pointer(kk.Foo) {
1069 t.Errorf("Expected Foo to point to different locations; they didn't: orig: %p; copy %p", k.Foo, kk.Foo)
1070 break
1071 }
1072 if *k.Foo != *kk.Foo {
1073 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)
1074 }
1075 if v != vv {
1076 t.Errorf("Expected the values to be the same; the weren't: got %v; want %v", vv, v)
1077 }
1078 }
1079 }
1080 if !found {
1081 t.Errorf("expected key %v to exist in the copy; it didn't", k)
1082 }
1083 }
1084 }
1085
1086 type I struct {
1087 A string
1088 }
1089
1090 func (i *I) DeepCopy() interface{} {
1091 return &I{A: "custom copy"}
1092 }
1093
1094 type NestI struct {
1095 I *I
1096 }
1097
1098 func TestInterface(t *testing.T) {
1099 i := &I{A: "A"}
1100 copied := Copy(i).(*I)
1101 if copied.A != "custom copy" {
1102 t.Errorf("expected value %v, but it's %v", "custom copy", copied.A)
1103 }
1104
1105 ni := &NestI{I: &I{A: "A"}}
1106 copiedNest := Copy(ni).(*NestI)
1107 if copiedNest.I.A != "custom copy" {
1108 t.Errorf("expected value %v, but it's %v", "custom copy", copiedNest.I.A)
1109 }
1110 }
1111
View as plain text