dump_test.go 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. /*
  2. * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /*
  17. Test Summary:
  18. NOTE: For each test, a nil pointer, a single pointer and double pointer to the
  19. base test element are also tested to ensure proper indirection across all types.
  20. - Max int8, int16, int32, int64, int
  21. - Max uint8, uint16, uint32, uint64, uint
  22. - Boolean true and false
  23. - Standard complex64 and complex128
  24. - Array containing standard ints
  25. - Array containing type with custom formatter on pointer receiver only
  26. - Array containing interfaces
  27. - Array containing bytes
  28. - Slice containing standard float32 values
  29. - Slice containing type with custom formatter on pointer receiver only
  30. - Slice containing interfaces
  31. - Slice containing bytes
  32. - Nil slice
  33. - Standard string
  34. - Nil interface
  35. - Sub-interface
  36. - Map with string keys and int vals
  37. - Map with custom formatter type on pointer receiver only keys and vals
  38. - Map with interface keys and values
  39. - Map with nil interface value
  40. - Struct with primitives
  41. - Struct that contains another struct
  42. - Struct that contains custom type with Stringer pointer interface via both
  43. exported and unexported fields
  44. - Struct that contains embedded struct and field to same struct
  45. - Uintptr to 0 (null pointer)
  46. - Uintptr address of real variable
  47. - Unsafe.Pointer to 0 (null pointer)
  48. - Unsafe.Pointer to address of real variable
  49. - Nil channel
  50. - Standard int channel
  51. - Function with no params and no returns
  52. - Function with param and no returns
  53. - Function with multiple params and multiple returns
  54. - Struct that is circular through self referencing
  55. - Structs that are circular through cross referencing
  56. - Structs that are indirectly circular
  57. - Type that panics in its Stringer interface
  58. */
  59. package spew_test
  60. import (
  61. "bytes"
  62. "fmt"
  63. "testing"
  64. "unsafe"
  65. "github.com/davecgh/go-spew/spew"
  66. )
  67. // dumpTest is used to describe a test to be performed against the Dump method.
  68. type dumpTest struct {
  69. in interface{}
  70. wants []string
  71. }
  72. // dumpTests houses all of the tests to be performed against the Dump method.
  73. var dumpTests = make([]dumpTest, 0)
  74. // addDumpTest is a helper method to append the passed input and desired result
  75. // to dumpTests
  76. func addDumpTest(in interface{}, wants ...string) {
  77. test := dumpTest{in, wants}
  78. dumpTests = append(dumpTests, test)
  79. }
  80. func addIntDumpTests() {
  81. // Max int8.
  82. v := int8(127)
  83. nv := (*int8)(nil)
  84. pv := &v
  85. vAddr := fmt.Sprintf("%p", pv)
  86. pvAddr := fmt.Sprintf("%p", &pv)
  87. vt := "int8"
  88. vs := "127"
  89. addDumpTest(v, "("+vt+") "+vs+"\n")
  90. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  91. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  92. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  93. // Max int16.
  94. v2 := int16(32767)
  95. nv2 := (*int16)(nil)
  96. pv2 := &v2
  97. v2Addr := fmt.Sprintf("%p", pv2)
  98. pv2Addr := fmt.Sprintf("%p", &pv2)
  99. v2t := "int16"
  100. v2s := "32767"
  101. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  102. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  103. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  104. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  105. // Max int32.
  106. v3 := int32(2147483647)
  107. nv3 := (*int32)(nil)
  108. pv3 := &v3
  109. v3Addr := fmt.Sprintf("%p", pv3)
  110. pv3Addr := fmt.Sprintf("%p", &pv3)
  111. v3t := "int32"
  112. v3s := "2147483647"
  113. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  114. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  115. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  116. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  117. // Max int64.
  118. v4 := int64(9223372036854775807)
  119. nv4 := (*int64)(nil)
  120. pv4 := &v4
  121. v4Addr := fmt.Sprintf("%p", pv4)
  122. pv4Addr := fmt.Sprintf("%p", &pv4)
  123. v4t := "int64"
  124. v4s := "9223372036854775807"
  125. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  126. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  127. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  128. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  129. // Max int.
  130. v5 := int(2147483647)
  131. nv5 := (*int)(nil)
  132. pv5 := &v5
  133. v5Addr := fmt.Sprintf("%p", pv5)
  134. pv5Addr := fmt.Sprintf("%p", &pv5)
  135. v5t := "int"
  136. v5s := "2147483647"
  137. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  138. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  139. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  140. addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
  141. }
  142. func addUintDumpTests() {
  143. // Max uint8.
  144. v := uint8(255)
  145. nv := (*uint8)(nil)
  146. pv := &v
  147. vAddr := fmt.Sprintf("%p", pv)
  148. pvAddr := fmt.Sprintf("%p", &pv)
  149. vt := "uint8"
  150. vs := "255"
  151. addDumpTest(v, "("+vt+") "+vs+"\n")
  152. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  153. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  154. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  155. // Max uint16.
  156. v2 := uint16(65535)
  157. nv2 := (*uint16)(nil)
  158. pv2 := &v2
  159. v2Addr := fmt.Sprintf("%p", pv2)
  160. pv2Addr := fmt.Sprintf("%p", &pv2)
  161. v2t := "uint16"
  162. v2s := "65535"
  163. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  164. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  165. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  166. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  167. // Max uint32.
  168. v3 := uint32(4294967295)
  169. nv3 := (*uint32)(nil)
  170. pv3 := &v3
  171. v3Addr := fmt.Sprintf("%p", pv3)
  172. pv3Addr := fmt.Sprintf("%p", &pv3)
  173. v3t := "uint32"
  174. v3s := "4294967295"
  175. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  176. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  177. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  178. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  179. // Max uint64.
  180. v4 := uint64(18446744073709551615)
  181. nv4 := (*uint64)(nil)
  182. pv4 := &v4
  183. v4Addr := fmt.Sprintf("%p", pv4)
  184. pv4Addr := fmt.Sprintf("%p", &pv4)
  185. v4t := "uint64"
  186. v4s := "18446744073709551615"
  187. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  188. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  189. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  190. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  191. // Max uint.
  192. v5 := uint(4294967295)
  193. nv5 := (*uint)(nil)
  194. pv5 := &v5
  195. v5Addr := fmt.Sprintf("%p", pv5)
  196. pv5Addr := fmt.Sprintf("%p", &pv5)
  197. v5t := "uint"
  198. v5s := "4294967295"
  199. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  200. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  201. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  202. addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
  203. }
  204. func addBoolDumpTests() {
  205. // Boolean true.
  206. v := bool(true)
  207. nv := (*bool)(nil)
  208. pv := &v
  209. vAddr := fmt.Sprintf("%p", pv)
  210. pvAddr := fmt.Sprintf("%p", &pv)
  211. vt := "bool"
  212. vs := "true"
  213. addDumpTest(v, "("+vt+") "+vs+"\n")
  214. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  215. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  216. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  217. // Boolean false.
  218. v2 := bool(false)
  219. pv2 := &v2
  220. v2Addr := fmt.Sprintf("%p", pv2)
  221. pv2Addr := fmt.Sprintf("%p", &pv2)
  222. v2t := "bool"
  223. v2s := "false"
  224. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  225. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  226. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  227. }
  228. func addFloatDumpTests() {
  229. // Standard float32.
  230. v := float32(3.1415)
  231. nv := (*float32)(nil)
  232. pv := &v
  233. vAddr := fmt.Sprintf("%p", pv)
  234. pvAddr := fmt.Sprintf("%p", &pv)
  235. vt := "float32"
  236. vs := "3.1415"
  237. addDumpTest(v, "("+vt+") "+vs+"\n")
  238. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  239. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  240. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  241. // Standard float64.
  242. v2 := float64(3.1415926)
  243. nv2 := (*float64)(nil)
  244. pv2 := &v2
  245. v2Addr := fmt.Sprintf("%p", pv2)
  246. pv2Addr := fmt.Sprintf("%p", &pv2)
  247. v2t := "float64"
  248. v2s := "3.1415926"
  249. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  250. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  251. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  252. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  253. }
  254. func addComplexDumpTests() {
  255. // Standard complex64.
  256. v := complex(float32(6), -2)
  257. nv := (*complex64)(nil)
  258. pv := &v
  259. vAddr := fmt.Sprintf("%p", pv)
  260. pvAddr := fmt.Sprintf("%p", &pv)
  261. vt := "complex64"
  262. vs := "(6-2i)"
  263. addDumpTest(v, "("+vt+") "+vs+"\n")
  264. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  265. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  266. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  267. // Standard complex128.
  268. v2 := complex(float64(-6), 2)
  269. nv2 := (*complex128)(nil)
  270. pv2 := &v2
  271. v2Addr := fmt.Sprintf("%p", pv2)
  272. pv2Addr := fmt.Sprintf("%p", &pv2)
  273. v2t := "complex128"
  274. v2s := "(-6+2i)"
  275. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  276. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  277. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  278. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  279. }
  280. func addArrayDumpTests() {
  281. // Array containing standard ints.
  282. v := [3]int{1, 2, 3}
  283. vLen := fmt.Sprintf("%d", len(v))
  284. vCap := fmt.Sprintf("%d", cap(v))
  285. nv := (*[3]int)(nil)
  286. pv := &v
  287. vAddr := fmt.Sprintf("%p", pv)
  288. pvAddr := fmt.Sprintf("%p", &pv)
  289. vt := "int"
  290. vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 1,\n (" +
  291. vt + ") 2,\n (" + vt + ") 3\n}"
  292. addDumpTest(v, "([3]"+vt+") "+vs+"\n")
  293. addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
  294. addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  295. addDumpTest(nv, "(*[3]"+vt+")(<nil>)\n")
  296. // Array containing type with custom formatter on pointer receiver only.
  297. v2i0 := pstringer("1")
  298. v2i1 := pstringer("2")
  299. v2i2 := pstringer("3")
  300. v2 := [3]pstringer{v2i0, v2i1, v2i2}
  301. v2i0Len := fmt.Sprintf("%d", len(v2i0))
  302. v2i1Len := fmt.Sprintf("%d", len(v2i1))
  303. v2i2Len := fmt.Sprintf("%d", len(v2i2))
  304. v2Len := fmt.Sprintf("%d", len(v2))
  305. v2Cap := fmt.Sprintf("%d", cap(v2))
  306. nv2 := (*[3]pstringer)(nil)
  307. pv2 := &v2
  308. v2Addr := fmt.Sprintf("%p", pv2)
  309. pv2Addr := fmt.Sprintf("%p", &pv2)
  310. v2t := "spew_test.pstringer"
  311. v2sp := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
  312. ") (len=" + v2i0Len + ") stringer 1,\n (" + v2t +
  313. ") (len=" + v2i1Len + ") stringer 2,\n (" + v2t +
  314. ") (len=" + v2i2Len + ") " + "stringer 3\n}"
  315. v2s := v2sp
  316. if spew.UnsafeDisabled {
  317. v2s = "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
  318. ") (len=" + v2i0Len + ") \"1\",\n (" + v2t + ") (len=" +
  319. v2i1Len + ") \"2\",\n (" + v2t + ") (len=" + v2i2Len +
  320. ") " + "\"3\"\n}"
  321. }
  322. addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
  323. addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2sp+")\n")
  324. addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2sp+")\n")
  325. addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
  326. // Array containing interfaces.
  327. v3i0 := "one"
  328. v3 := [3]interface{}{v3i0, int(2), uint(3)}
  329. v3i0Len := fmt.Sprintf("%d", len(v3i0))
  330. v3Len := fmt.Sprintf("%d", len(v3))
  331. v3Cap := fmt.Sprintf("%d", cap(v3))
  332. nv3 := (*[3]interface{})(nil)
  333. pv3 := &v3
  334. v3Addr := fmt.Sprintf("%p", pv3)
  335. pv3Addr := fmt.Sprintf("%p", &pv3)
  336. v3t := "[3]interface {}"
  337. v3t2 := "string"
  338. v3t3 := "int"
  339. v3t4 := "uint"
  340. v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
  341. "(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
  342. v3t4 + ") 3\n}"
  343. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  344. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  345. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  346. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  347. // Array containing bytes.
  348. v4 := [34]byte{
  349. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  350. 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
  351. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  352. 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
  353. 0x31, 0x32,
  354. }
  355. v4Len := fmt.Sprintf("%d", len(v4))
  356. v4Cap := fmt.Sprintf("%d", cap(v4))
  357. nv4 := (*[34]byte)(nil)
  358. pv4 := &v4
  359. v4Addr := fmt.Sprintf("%p", pv4)
  360. pv4Addr := fmt.Sprintf("%p", &pv4)
  361. v4t := "[34]uint8"
  362. v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
  363. "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
  364. " |............... |\n" +
  365. " 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
  366. " |!\"#$%&'()*+,-./0|\n" +
  367. " 00000020 31 32 " +
  368. " |12|\n}"
  369. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  370. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  371. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  372. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  373. }
  374. func addSliceDumpTests() {
  375. // Slice containing standard float32 values.
  376. v := []float32{3.14, 6.28, 12.56}
  377. vLen := fmt.Sprintf("%d", len(v))
  378. vCap := fmt.Sprintf("%d", cap(v))
  379. nv := (*[]float32)(nil)
  380. pv := &v
  381. vAddr := fmt.Sprintf("%p", pv)
  382. pvAddr := fmt.Sprintf("%p", &pv)
  383. vt := "float32"
  384. vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 3.14,\n (" +
  385. vt + ") 6.28,\n (" + vt + ") 12.56\n}"
  386. addDumpTest(v, "([]"+vt+") "+vs+"\n")
  387. addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
  388. addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  389. addDumpTest(nv, "(*[]"+vt+")(<nil>)\n")
  390. // Slice containing type with custom formatter on pointer receiver only.
  391. v2i0 := pstringer("1")
  392. v2i1 := pstringer("2")
  393. v2i2 := pstringer("3")
  394. v2 := []pstringer{v2i0, v2i1, v2i2}
  395. v2i0Len := fmt.Sprintf("%d", len(v2i0))
  396. v2i1Len := fmt.Sprintf("%d", len(v2i1))
  397. v2i2Len := fmt.Sprintf("%d", len(v2i2))
  398. v2Len := fmt.Sprintf("%d", len(v2))
  399. v2Cap := fmt.Sprintf("%d", cap(v2))
  400. nv2 := (*[]pstringer)(nil)
  401. pv2 := &v2
  402. v2Addr := fmt.Sprintf("%p", pv2)
  403. pv2Addr := fmt.Sprintf("%p", &pv2)
  404. v2t := "spew_test.pstringer"
  405. v2s := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t + ") (len=" +
  406. v2i0Len + ") stringer 1,\n (" + v2t + ") (len=" + v2i1Len +
  407. ") stringer 2,\n (" + v2t + ") (len=" + v2i2Len + ") " +
  408. "stringer 3\n}"
  409. addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
  410. addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
  411. addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  412. addDumpTest(nv2, "(*[]"+v2t+")(<nil>)\n")
  413. // Slice containing interfaces.
  414. v3i0 := "one"
  415. v3 := []interface{}{v3i0, int(2), uint(3), nil}
  416. v3i0Len := fmt.Sprintf("%d", len(v3i0))
  417. v3Len := fmt.Sprintf("%d", len(v3))
  418. v3Cap := fmt.Sprintf("%d", cap(v3))
  419. nv3 := (*[]interface{})(nil)
  420. pv3 := &v3
  421. v3Addr := fmt.Sprintf("%p", pv3)
  422. pv3Addr := fmt.Sprintf("%p", &pv3)
  423. v3t := "[]interface {}"
  424. v3t2 := "string"
  425. v3t3 := "int"
  426. v3t4 := "uint"
  427. v3t5 := "interface {}"
  428. v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
  429. "(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
  430. v3t4 + ") 3,\n (" + v3t5 + ") <nil>\n}"
  431. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  432. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  433. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  434. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  435. // Slice containing bytes.
  436. v4 := []byte{
  437. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  438. 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
  439. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  440. 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
  441. 0x31, 0x32,
  442. }
  443. v4Len := fmt.Sprintf("%d", len(v4))
  444. v4Cap := fmt.Sprintf("%d", cap(v4))
  445. nv4 := (*[]byte)(nil)
  446. pv4 := &v4
  447. v4Addr := fmt.Sprintf("%p", pv4)
  448. pv4Addr := fmt.Sprintf("%p", &pv4)
  449. v4t := "[]uint8"
  450. v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
  451. "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
  452. " |............... |\n" +
  453. " 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
  454. " |!\"#$%&'()*+,-./0|\n" +
  455. " 00000020 31 32 " +
  456. " |12|\n}"
  457. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  458. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  459. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  460. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  461. // Nil slice.
  462. v5 := []int(nil)
  463. nv5 := (*[]int)(nil)
  464. pv5 := &v5
  465. v5Addr := fmt.Sprintf("%p", pv5)
  466. pv5Addr := fmt.Sprintf("%p", &pv5)
  467. v5t := "[]int"
  468. v5s := "<nil>"
  469. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  470. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  471. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  472. addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
  473. }
  474. func addStringDumpTests() {
  475. // Standard string.
  476. v := "test"
  477. vLen := fmt.Sprintf("%d", len(v))
  478. nv := (*string)(nil)
  479. pv := &v
  480. vAddr := fmt.Sprintf("%p", pv)
  481. pvAddr := fmt.Sprintf("%p", &pv)
  482. vt := "string"
  483. vs := "(len=" + vLen + ") \"test\""
  484. addDumpTest(v, "("+vt+") "+vs+"\n")
  485. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  486. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  487. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  488. }
  489. func addInterfaceDumpTests() {
  490. // Nil interface.
  491. var v interface{}
  492. nv := (*interface{})(nil)
  493. pv := &v
  494. vAddr := fmt.Sprintf("%p", pv)
  495. pvAddr := fmt.Sprintf("%p", &pv)
  496. vt := "interface {}"
  497. vs := "<nil>"
  498. addDumpTest(v, "("+vt+") "+vs+"\n")
  499. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  500. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  501. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  502. // Sub-interface.
  503. v2 := interface{}(uint16(65535))
  504. pv2 := &v2
  505. v2Addr := fmt.Sprintf("%p", pv2)
  506. pv2Addr := fmt.Sprintf("%p", &pv2)
  507. v2t := "uint16"
  508. v2s := "65535"
  509. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  510. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  511. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  512. }
  513. func addMapDumpTests() {
  514. // Map with string keys and int vals.
  515. k := "one"
  516. kk := "two"
  517. m := map[string]int{k: 1, kk: 2}
  518. klen := fmt.Sprintf("%d", len(k)) // not kLen to shut golint up
  519. kkLen := fmt.Sprintf("%d", len(kk))
  520. mLen := fmt.Sprintf("%d", len(m))
  521. nilMap := map[string]int(nil)
  522. nm := (*map[string]int)(nil)
  523. pm := &m
  524. mAddr := fmt.Sprintf("%p", pm)
  525. pmAddr := fmt.Sprintf("%p", &pm)
  526. mt := "map[string]int"
  527. mt1 := "string"
  528. mt2 := "int"
  529. ms := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + klen + ") " +
  530. "\"one\": (" + mt2 + ") 1,\n (" + mt1 + ") (len=" + kkLen +
  531. ") \"two\": (" + mt2 + ") 2\n}"
  532. ms2 := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + kkLen + ") " +
  533. "\"two\": (" + mt2 + ") 2,\n (" + mt1 + ") (len=" + klen +
  534. ") \"one\": (" + mt2 + ") 1\n}"
  535. addDumpTest(m, "("+mt+") "+ms+"\n", "("+mt+") "+ms2+"\n")
  536. addDumpTest(pm, "(*"+mt+")("+mAddr+")("+ms+")\n",
  537. "(*"+mt+")("+mAddr+")("+ms2+")\n")
  538. addDumpTest(&pm, "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms+")\n",
  539. "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms2+")\n")
  540. addDumpTest(nm, "(*"+mt+")(<nil>)\n")
  541. addDumpTest(nilMap, "("+mt+") <nil>\n")
  542. // Map with custom formatter type on pointer receiver only keys and vals.
  543. k2 := pstringer("one")
  544. v2 := pstringer("1")
  545. m2 := map[pstringer]pstringer{k2: v2}
  546. k2Len := fmt.Sprintf("%d", len(k2))
  547. v2Len := fmt.Sprintf("%d", len(v2))
  548. m2Len := fmt.Sprintf("%d", len(m2))
  549. nilMap2 := map[pstringer]pstringer(nil)
  550. nm2 := (*map[pstringer]pstringer)(nil)
  551. pm2 := &m2
  552. m2Addr := fmt.Sprintf("%p", pm2)
  553. pm2Addr := fmt.Sprintf("%p", &pm2)
  554. m2t := "map[spew_test.pstringer]spew_test.pstringer"
  555. m2t1 := "spew_test.pstringer"
  556. m2t2 := "spew_test.pstringer"
  557. m2s := "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len + ") " +
  558. "stringer one: (" + m2t2 + ") (len=" + v2Len + ") stringer 1\n}"
  559. if spew.UnsafeDisabled {
  560. m2s = "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len +
  561. ") " + "\"one\": (" + m2t2 + ") (len=" + v2Len +
  562. ") \"1\"\n}"
  563. }
  564. addDumpTest(m2, "("+m2t+") "+m2s+"\n")
  565. addDumpTest(pm2, "(*"+m2t+")("+m2Addr+")("+m2s+")\n")
  566. addDumpTest(&pm2, "(**"+m2t+")("+pm2Addr+"->"+m2Addr+")("+m2s+")\n")
  567. addDumpTest(nm2, "(*"+m2t+")(<nil>)\n")
  568. addDumpTest(nilMap2, "("+m2t+") <nil>\n")
  569. // Map with interface keys and values.
  570. k3 := "one"
  571. k3Len := fmt.Sprintf("%d", len(k3))
  572. m3 := map[interface{}]interface{}{k3: 1}
  573. m3Len := fmt.Sprintf("%d", len(m3))
  574. nilMap3 := map[interface{}]interface{}(nil)
  575. nm3 := (*map[interface{}]interface{})(nil)
  576. pm3 := &m3
  577. m3Addr := fmt.Sprintf("%p", pm3)
  578. pm3Addr := fmt.Sprintf("%p", &pm3)
  579. m3t := "map[interface {}]interface {}"
  580. m3t1 := "string"
  581. m3t2 := "int"
  582. m3s := "(len=" + m3Len + ") {\n (" + m3t1 + ") (len=" + k3Len + ") " +
  583. "\"one\": (" + m3t2 + ") 1\n}"
  584. addDumpTest(m3, "("+m3t+") "+m3s+"\n")
  585. addDumpTest(pm3, "(*"+m3t+")("+m3Addr+")("+m3s+")\n")
  586. addDumpTest(&pm3, "(**"+m3t+")("+pm3Addr+"->"+m3Addr+")("+m3s+")\n")
  587. addDumpTest(nm3, "(*"+m3t+")(<nil>)\n")
  588. addDumpTest(nilMap3, "("+m3t+") <nil>\n")
  589. // Map with nil interface value.
  590. k4 := "nil"
  591. k4Len := fmt.Sprintf("%d", len(k4))
  592. m4 := map[string]interface{}{k4: nil}
  593. m4Len := fmt.Sprintf("%d", len(m4))
  594. nilMap4 := map[string]interface{}(nil)
  595. nm4 := (*map[string]interface{})(nil)
  596. pm4 := &m4
  597. m4Addr := fmt.Sprintf("%p", pm4)
  598. pm4Addr := fmt.Sprintf("%p", &pm4)
  599. m4t := "map[string]interface {}"
  600. m4t1 := "string"
  601. m4t2 := "interface {}"
  602. m4s := "(len=" + m4Len + ") {\n (" + m4t1 + ") (len=" + k4Len + ")" +
  603. " \"nil\": (" + m4t2 + ") <nil>\n}"
  604. addDumpTest(m4, "("+m4t+") "+m4s+"\n")
  605. addDumpTest(pm4, "(*"+m4t+")("+m4Addr+")("+m4s+")\n")
  606. addDumpTest(&pm4, "(**"+m4t+")("+pm4Addr+"->"+m4Addr+")("+m4s+")\n")
  607. addDumpTest(nm4, "(*"+m4t+")(<nil>)\n")
  608. addDumpTest(nilMap4, "("+m4t+") <nil>\n")
  609. }
  610. func addStructDumpTests() {
  611. // Struct with primitives.
  612. type s1 struct {
  613. a int8
  614. b uint8
  615. }
  616. v := s1{127, 255}
  617. nv := (*s1)(nil)
  618. pv := &v
  619. vAddr := fmt.Sprintf("%p", pv)
  620. pvAddr := fmt.Sprintf("%p", &pv)
  621. vt := "spew_test.s1"
  622. vt2 := "int8"
  623. vt3 := "uint8"
  624. vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
  625. addDumpTest(v, "("+vt+") "+vs+"\n")
  626. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  627. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  628. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  629. // Struct that contains another struct.
  630. type s2 struct {
  631. s1 s1
  632. b bool
  633. }
  634. v2 := s2{s1{127, 255}, true}
  635. nv2 := (*s2)(nil)
  636. pv2 := &v2
  637. v2Addr := fmt.Sprintf("%p", pv2)
  638. pv2Addr := fmt.Sprintf("%p", &pv2)
  639. v2t := "spew_test.s2"
  640. v2t2 := "spew_test.s1"
  641. v2t3 := "int8"
  642. v2t4 := "uint8"
  643. v2t5 := "bool"
  644. v2s := "{\n s1: (" + v2t2 + ") {\n a: (" + v2t3 + ") 127,\n b: (" +
  645. v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
  646. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  647. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  648. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  649. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  650. // Struct that contains custom type with Stringer pointer interface via both
  651. // exported and unexported fields.
  652. type s3 struct {
  653. s pstringer
  654. S pstringer
  655. }
  656. v3 := s3{"test", "test2"}
  657. nv3 := (*s3)(nil)
  658. pv3 := &v3
  659. v3Addr := fmt.Sprintf("%p", pv3)
  660. pv3Addr := fmt.Sprintf("%p", &pv3)
  661. v3t := "spew_test.s3"
  662. v3t2 := "spew_test.pstringer"
  663. v3s := "{\n s: (" + v3t2 + ") (len=4) stringer test,\n S: (" + v3t2 +
  664. ") (len=5) stringer test2\n}"
  665. v3sp := v3s
  666. if spew.UnsafeDisabled {
  667. v3s = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
  668. v3t2 + ") (len=5) \"test2\"\n}"
  669. v3sp = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
  670. v3t2 + ") (len=5) stringer test2\n}"
  671. }
  672. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  673. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3sp+")\n")
  674. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3sp+")\n")
  675. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  676. // Struct that contains embedded struct and field to same struct.
  677. e := embed{"embedstr"}
  678. eLen := fmt.Sprintf("%d", len("embedstr"))
  679. v4 := embedwrap{embed: &e, e: &e}
  680. nv4 := (*embedwrap)(nil)
  681. pv4 := &v4
  682. eAddr := fmt.Sprintf("%p", &e)
  683. v4Addr := fmt.Sprintf("%p", pv4)
  684. pv4Addr := fmt.Sprintf("%p", &pv4)
  685. v4t := "spew_test.embedwrap"
  686. v4t2 := "spew_test.embed"
  687. v4t3 := "string"
  688. v4s := "{\n embed: (*" + v4t2 + ")(" + eAddr + ")({\n a: (" + v4t3 +
  689. ") (len=" + eLen + ") \"embedstr\"\n }),\n e: (*" + v4t2 +
  690. ")(" + eAddr + ")({\n a: (" + v4t3 + ") (len=" + eLen + ")" +
  691. " \"embedstr\"\n })\n}"
  692. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  693. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  694. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  695. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  696. }
  697. func addUintptrDumpTests() {
  698. // Null pointer.
  699. v := uintptr(0)
  700. pv := &v
  701. vAddr := fmt.Sprintf("%p", pv)
  702. pvAddr := fmt.Sprintf("%p", &pv)
  703. vt := "uintptr"
  704. vs := "<nil>"
  705. addDumpTest(v, "("+vt+") "+vs+"\n")
  706. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  707. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  708. // Address of real variable.
  709. i := 1
  710. v2 := uintptr(unsafe.Pointer(&i))
  711. nv2 := (*uintptr)(nil)
  712. pv2 := &v2
  713. v2Addr := fmt.Sprintf("%p", pv2)
  714. pv2Addr := fmt.Sprintf("%p", &pv2)
  715. v2t := "uintptr"
  716. v2s := fmt.Sprintf("%p", &i)
  717. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  718. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  719. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  720. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  721. }
  722. func addUnsafePointerDumpTests() {
  723. // Null pointer.
  724. v := unsafe.Pointer(uintptr(0))
  725. nv := (*unsafe.Pointer)(nil)
  726. pv := &v
  727. vAddr := fmt.Sprintf("%p", pv)
  728. pvAddr := fmt.Sprintf("%p", &pv)
  729. vt := "unsafe.Pointer"
  730. vs := "<nil>"
  731. addDumpTest(v, "("+vt+") "+vs+"\n")
  732. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  733. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  734. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  735. // Address of real variable.
  736. i := 1
  737. v2 := unsafe.Pointer(&i)
  738. pv2 := &v2
  739. v2Addr := fmt.Sprintf("%p", pv2)
  740. pv2Addr := fmt.Sprintf("%p", &pv2)
  741. v2t := "unsafe.Pointer"
  742. v2s := fmt.Sprintf("%p", &i)
  743. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  744. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  745. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  746. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  747. }
  748. func addChanDumpTests() {
  749. // Nil channel.
  750. var v chan int
  751. pv := &v
  752. nv := (*chan int)(nil)
  753. vAddr := fmt.Sprintf("%p", pv)
  754. pvAddr := fmt.Sprintf("%p", &pv)
  755. vt := "chan int"
  756. vs := "<nil>"
  757. addDumpTest(v, "("+vt+") "+vs+"\n")
  758. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  759. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  760. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  761. // Real channel.
  762. v2 := make(chan int)
  763. pv2 := &v2
  764. v2Addr := fmt.Sprintf("%p", pv2)
  765. pv2Addr := fmt.Sprintf("%p", &pv2)
  766. v2t := "chan int"
  767. v2s := fmt.Sprintf("%p", v2)
  768. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  769. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  770. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  771. }
  772. func addFuncDumpTests() {
  773. // Function with no params and no returns.
  774. v := addIntDumpTests
  775. nv := (*func())(nil)
  776. pv := &v
  777. vAddr := fmt.Sprintf("%p", pv)
  778. pvAddr := fmt.Sprintf("%p", &pv)
  779. vt := "func()"
  780. vs := fmt.Sprintf("%p", v)
  781. addDumpTest(v, "("+vt+") "+vs+"\n")
  782. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  783. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  784. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  785. // Function with param and no returns.
  786. v2 := TestDump
  787. nv2 := (*func(*testing.T))(nil)
  788. pv2 := &v2
  789. v2Addr := fmt.Sprintf("%p", pv2)
  790. pv2Addr := fmt.Sprintf("%p", &pv2)
  791. v2t := "func(*testing.T)"
  792. v2s := fmt.Sprintf("%p", v2)
  793. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  794. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  795. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  796. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  797. // Function with multiple params and multiple returns.
  798. var v3 = func(i int, s string) (b bool, err error) {
  799. return true, nil
  800. }
  801. nv3 := (*func(int, string) (bool, error))(nil)
  802. pv3 := &v3
  803. v3Addr := fmt.Sprintf("%p", pv3)
  804. pv3Addr := fmt.Sprintf("%p", &pv3)
  805. v3t := "func(int, string) (bool, error)"
  806. v3s := fmt.Sprintf("%p", v3)
  807. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  808. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  809. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  810. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  811. }
  812. func addCircularDumpTests() {
  813. // Struct that is circular through self referencing.
  814. type circular struct {
  815. c *circular
  816. }
  817. v := circular{nil}
  818. v.c = &v
  819. pv := &v
  820. vAddr := fmt.Sprintf("%p", pv)
  821. pvAddr := fmt.Sprintf("%p", &pv)
  822. vt := "spew_test.circular"
  823. vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n c: (*" + vt + ")(" +
  824. vAddr + ")(<already shown>)\n })\n}"
  825. vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
  826. addDumpTest(v, "("+vt+") "+vs+"\n")
  827. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
  828. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
  829. // Structs that are circular through cross referencing.
  830. v2 := xref1{nil}
  831. ts2 := xref2{&v2}
  832. v2.ps2 = &ts2
  833. pv2 := &v2
  834. ts2Addr := fmt.Sprintf("%p", &ts2)
  835. v2Addr := fmt.Sprintf("%p", pv2)
  836. pv2Addr := fmt.Sprintf("%p", &pv2)
  837. v2t := "spew_test.xref1"
  838. v2t2 := "spew_test.xref2"
  839. v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  840. ")(" + v2Addr + ")({\n ps2: (*" + v2t2 + ")(" + ts2Addr +
  841. ")(<already shown>)\n })\n })\n}"
  842. v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  843. ")(" + v2Addr + ")(<already shown>)\n })\n}"
  844. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  845. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
  846. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
  847. // Structs that are indirectly circular.
  848. v3 := indirCir1{nil}
  849. tic2 := indirCir2{nil}
  850. tic3 := indirCir3{&v3}
  851. tic2.ps3 = &tic3
  852. v3.ps2 = &tic2
  853. pv3 := &v3
  854. tic2Addr := fmt.Sprintf("%p", &tic2)
  855. tic3Addr := fmt.Sprintf("%p", &tic3)
  856. v3Addr := fmt.Sprintf("%p", pv3)
  857. pv3Addr := fmt.Sprintf("%p", &pv3)
  858. v3t := "spew_test.indirCir1"
  859. v3t2 := "spew_test.indirCir2"
  860. v3t3 := "spew_test.indirCir3"
  861. v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  862. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  863. ")({\n ps2: (*" + v3t2 + ")(" + tic2Addr +
  864. ")(<already shown>)\n })\n })\n })\n}"
  865. v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  866. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  867. ")(<already shown>)\n })\n })\n}"
  868. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  869. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
  870. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
  871. }
  872. func addPanicDumpTests() {
  873. // Type that panics in its Stringer interface.
  874. v := panicer(127)
  875. nv := (*panicer)(nil)
  876. pv := &v
  877. vAddr := fmt.Sprintf("%p", pv)
  878. pvAddr := fmt.Sprintf("%p", &pv)
  879. vt := "spew_test.panicer"
  880. vs := "(PANIC=test panic)127"
  881. addDumpTest(v, "("+vt+") "+vs+"\n")
  882. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  883. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  884. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  885. }
  886. func addErrorDumpTests() {
  887. // Type that has a custom Error interface.
  888. v := customError(127)
  889. nv := (*customError)(nil)
  890. pv := &v
  891. vAddr := fmt.Sprintf("%p", pv)
  892. pvAddr := fmt.Sprintf("%p", &pv)
  893. vt := "spew_test.customError"
  894. vs := "error: 127"
  895. addDumpTest(v, "("+vt+") "+vs+"\n")
  896. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  897. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  898. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  899. }
  900. // TestDump executes all of the tests described by dumpTests.
  901. func TestDump(t *testing.T) {
  902. // Setup tests.
  903. addIntDumpTests()
  904. addUintDumpTests()
  905. addBoolDumpTests()
  906. addFloatDumpTests()
  907. addComplexDumpTests()
  908. addArrayDumpTests()
  909. addSliceDumpTests()
  910. addStringDumpTests()
  911. addInterfaceDumpTests()
  912. addMapDumpTests()
  913. addStructDumpTests()
  914. addUintptrDumpTests()
  915. addUnsafePointerDumpTests()
  916. addChanDumpTests()
  917. addFuncDumpTests()
  918. addCircularDumpTests()
  919. addPanicDumpTests()
  920. addErrorDumpTests()
  921. addCgoDumpTests()
  922. t.Logf("Running %d tests", len(dumpTests))
  923. for i, test := range dumpTests {
  924. buf := new(bytes.Buffer)
  925. spew.Fdump(buf, test.in)
  926. s := buf.String()
  927. if testFailed(s, test.wants) {
  928. t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
  929. continue
  930. }
  931. }
  932. }
  933. func TestDumpSortedKeys(t *testing.T) {
  934. cfg := spew.ConfigState{SortKeys: true}
  935. s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"})
  936. expected := "(map[int]string) (len=3) {\n(int) 1: (string) (len=1) " +
  937. "\"1\",\n(int) 2: (string) (len=1) \"2\",\n(int) 3: (string) " +
  938. "(len=1) \"3\"\n" +
  939. "}\n"
  940. if s != expected {
  941. t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
  942. }
  943. s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2})
  944. expected = "(map[spew_test.stringer]int) (len=3) {\n" +
  945. "(spew_test.stringer) (len=1) stringer 1: (int) 1,\n" +
  946. "(spew_test.stringer) (len=1) stringer 2: (int) 2,\n" +
  947. "(spew_test.stringer) (len=1) stringer 3: (int) 3\n" +
  948. "}\n"
  949. if s != expected {
  950. t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
  951. }
  952. s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
  953. expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
  954. "(spew_test.pstringer) (len=1) stringer 1: (int) 1,\n" +
  955. "(spew_test.pstringer) (len=1) stringer 2: (int) 2,\n" +
  956. "(spew_test.pstringer) (len=1) stringer 3: (int) 3\n" +
  957. "}\n"
  958. if spew.UnsafeDisabled {
  959. expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
  960. "(spew_test.pstringer) (len=1) \"1\": (int) 1,\n" +
  961. "(spew_test.pstringer) (len=1) \"2\": (int) 2,\n" +
  962. "(spew_test.pstringer) (len=1) \"3\": (int) 3\n" +
  963. "}\n"
  964. }
  965. if s != expected {
  966. t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
  967. }
  968. s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
  969. expected = "(map[spew_test.customError]int) (len=3) {\n" +
  970. "(spew_test.customError) error: 1: (int) 1,\n" +
  971. "(spew_test.customError) error: 2: (int) 2,\n" +
  972. "(spew_test.customError) error: 3: (int) 3\n" +
  973. "}\n"
  974. if s != expected {
  975. t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
  976. }
  977. }