deepcopy_test.go 33 KB

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