deepcopy_test.go 36 KB

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