deepcopy_test.go 34 KB

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