dump_test.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. /*
  2. * Copyright (c) 2013 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. - Slice containing standard float32 values
  28. - Slice containing type with custom formatter on pointer receiver only
  29. - Slice containing interfaces
  30. - Standard string
  31. - Nil interface
  32. - Sub-interface
  33. - Map with string keys and int vals
  34. - Map with custom formatter type on pointer receiver only keys and vals
  35. - Map with interface keys and values
  36. - Struct with primitives
  37. - Struct that contains another struct
  38. - Struct that contains custom type with Stringer pointer interface via both
  39. exported and unexported fields
  40. - Struct that contains embedded struct and field to same struct
  41. - Uintptr to 0 (null pointer)
  42. - Uintptr address of real variable
  43. - Unsafe.Pointer to 0 (null pointer)
  44. - Unsafe.Pointer to address of real variable
  45. - Nil channel
  46. - Standard int channel
  47. - Function with no params and no returns
  48. - Function with param and no returns
  49. - Function with multiple params and multiple returns
  50. - Struct that is circular through self referencing
  51. - Structs that are circular through cross referencing
  52. - Structs that are indirectly circular
  53. - Type that panics in its Stringer interface
  54. */
  55. package spew_test
  56. import (
  57. "bytes"
  58. "fmt"
  59. "github.com/davecgh/go-spew/spew"
  60. "testing"
  61. "unsafe"
  62. )
  63. // dumpTest is used to describe a test to be perfomed against the Dump method.
  64. type dumpTest struct {
  65. in interface{}
  66. wants []string
  67. }
  68. // dumpTests houses all of the tests to be performed against the Dump method.
  69. var dumpTests = make([]dumpTest, 0)
  70. // addDumpTest is a helper method to append the passed input and desired result
  71. // to dumpTests
  72. func addDumpTest(in interface{}, wants ...string) {
  73. test := dumpTest{in, wants}
  74. dumpTests = append(dumpTests, test)
  75. }
  76. func addIntDumpTests() {
  77. // Max int8.
  78. v := int8(127)
  79. nv := (*int8)(nil)
  80. pv := &v
  81. vAddr := fmt.Sprintf("%p", pv)
  82. pvAddr := fmt.Sprintf("%p", &pv)
  83. vt := "int8"
  84. vs := "127"
  85. addDumpTest(v, "("+vt+") "+vs+"\n")
  86. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  87. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  88. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  89. // Max int16.
  90. v2 := int16(32767)
  91. nv2 := (*int16)(nil)
  92. pv2 := &v2
  93. v2Addr := fmt.Sprintf("%p", pv2)
  94. pv2Addr := fmt.Sprintf("%p", &pv2)
  95. v2t := "int16"
  96. v2s := "32767"
  97. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  98. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  99. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  100. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  101. // Max int32.
  102. v3 := int32(2147483647)
  103. nv3 := (*int32)(nil)
  104. pv3 := &v3
  105. v3Addr := fmt.Sprintf("%p", pv3)
  106. pv3Addr := fmt.Sprintf("%p", &pv3)
  107. v3t := "int32"
  108. v3s := "2147483647"
  109. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  110. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  111. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  112. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  113. // Max int64.
  114. v4 := int64(9223372036854775807)
  115. nv4 := (*int64)(nil)
  116. pv4 := &v4
  117. v4Addr := fmt.Sprintf("%p", pv4)
  118. pv4Addr := fmt.Sprintf("%p", &pv4)
  119. v4t := "int64"
  120. v4s := "9223372036854775807"
  121. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  122. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  123. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  124. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  125. // Max int.
  126. v5 := int(2147483647)
  127. nv5 := (*int)(nil)
  128. pv5 := &v5
  129. v5Addr := fmt.Sprintf("%p", pv5)
  130. pv5Addr := fmt.Sprintf("%p", &pv5)
  131. v5t := "int"
  132. v5s := "2147483647"
  133. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  134. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  135. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  136. addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
  137. }
  138. func addUintDumpTests() {
  139. // Max uint8.
  140. v := uint8(255)
  141. nv := (*uint8)(nil)
  142. pv := &v
  143. vAddr := fmt.Sprintf("%p", pv)
  144. pvAddr := fmt.Sprintf("%p", &pv)
  145. vt := "uint8"
  146. vs := "255"
  147. addDumpTest(v, "("+vt+") "+vs+"\n")
  148. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  149. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  150. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  151. // Max uint16.
  152. v2 := uint16(65535)
  153. nv2 := (*uint16)(nil)
  154. pv2 := &v2
  155. v2Addr := fmt.Sprintf("%p", pv2)
  156. pv2Addr := fmt.Sprintf("%p", &pv2)
  157. v2t := "uint16"
  158. v2s := "65535"
  159. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  160. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  161. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  162. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  163. // Max uint32.
  164. v3 := uint32(4294967295)
  165. nv3 := (*uint32)(nil)
  166. pv3 := &v3
  167. v3Addr := fmt.Sprintf("%p", pv3)
  168. pv3Addr := fmt.Sprintf("%p", &pv3)
  169. v3t := "uint32"
  170. v3s := "4294967295"
  171. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  172. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  173. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  174. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  175. // Max uint64.
  176. v4 := uint64(18446744073709551615)
  177. nv4 := (*uint64)(nil)
  178. pv4 := &v4
  179. v4Addr := fmt.Sprintf("%p", pv4)
  180. pv4Addr := fmt.Sprintf("%p", &pv4)
  181. v4t := "uint64"
  182. v4s := "18446744073709551615"
  183. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  184. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  185. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  186. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  187. // Max uint.
  188. v5 := uint(4294967295)
  189. nv5 := (*uint)(nil)
  190. pv5 := &v5
  191. v5Addr := fmt.Sprintf("%p", pv5)
  192. pv5Addr := fmt.Sprintf("%p", &pv5)
  193. v5t := "uint"
  194. v5s := "4294967295"
  195. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  196. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  197. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  198. addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
  199. }
  200. func addBoolDumpTests() {
  201. // Boolean true.
  202. v := bool(true)
  203. nv := (*bool)(nil)
  204. pv := &v
  205. vAddr := fmt.Sprintf("%p", pv)
  206. pvAddr := fmt.Sprintf("%p", &pv)
  207. vt := "bool"
  208. vs := "true"
  209. addDumpTest(v, "("+vt+") "+vs+"\n")
  210. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  211. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  212. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  213. // Boolean false.
  214. v2 := bool(false)
  215. pv2 := &v2
  216. v2Addr := fmt.Sprintf("%p", pv2)
  217. pv2Addr := fmt.Sprintf("%p", &pv2)
  218. v2t := "bool"
  219. v2s := "false"
  220. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  221. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  222. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  223. }
  224. func addFloatDumpTests() {
  225. // Standard float32.
  226. v := float32(3.1415)
  227. nv := (*float32)(nil)
  228. pv := &v
  229. vAddr := fmt.Sprintf("%p", pv)
  230. pvAddr := fmt.Sprintf("%p", &pv)
  231. vt := "float32"
  232. vs := "3.1415"
  233. addDumpTest(v, "("+vt+") "+vs+"\n")
  234. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  235. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  236. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  237. // Standard float64.
  238. v2 := float64(3.1415926)
  239. nv2 := (*float64)(nil)
  240. pv2 := &v2
  241. v2Addr := fmt.Sprintf("%p", pv2)
  242. pv2Addr := fmt.Sprintf("%p", &pv2)
  243. v2t := "float64"
  244. v2s := "3.1415926"
  245. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  246. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  247. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  248. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  249. }
  250. func addComplexDumpTests() {
  251. // Standard complex64.
  252. v := complex(float32(6), -2)
  253. nv := (*complex64)(nil)
  254. pv := &v
  255. vAddr := fmt.Sprintf("%p", pv)
  256. pvAddr := fmt.Sprintf("%p", &pv)
  257. vt := "complex64"
  258. vs := "(6-2i)"
  259. addDumpTest(v, "("+vt+") "+vs+"\n")
  260. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  261. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  262. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  263. // Standard complex128.
  264. v2 := complex(float64(-6), 2)
  265. nv2 := (*complex128)(nil)
  266. pv2 := &v2
  267. v2Addr := fmt.Sprintf("%p", pv2)
  268. pv2Addr := fmt.Sprintf("%p", &pv2)
  269. v2t := "complex128"
  270. v2s := "(-6+2i)"
  271. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  272. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  273. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  274. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  275. }
  276. func addArrayDumpTests() {
  277. // Array containing standard ints.
  278. v := [3]int{1, 2, 3}
  279. nv := (*[3]int)(nil)
  280. pv := &v
  281. vAddr := fmt.Sprintf("%p", pv)
  282. pvAddr := fmt.Sprintf("%p", &pv)
  283. vt := "int"
  284. vs := "{\n (" + vt + ") 1,\n (" + vt + ") 2,\n (" + vt + ") 3\n}"
  285. addDumpTest(v, "([3]"+vt+") "+vs+"\n")
  286. addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
  287. addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  288. addDumpTest(nv, "(*[3]"+vt+")(<nil>)\n")
  289. // Array containing type with custom formatter on pointer receiver only.
  290. v2 := [3]pstringer{"1", "2", "3"}
  291. nv2 := (*[3]pstringer)(nil)
  292. pv2 := &v2
  293. v2Addr := fmt.Sprintf("%p", pv2)
  294. pv2Addr := fmt.Sprintf("%p", &pv2)
  295. v2t := "spew_test.pstringer"
  296. v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
  297. v2t + ") stringer 3\n}"
  298. addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
  299. addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2s+")\n")
  300. addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  301. addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
  302. // Array containing interfaces.
  303. v3 := [3]interface{}{"one", int(2), uint(3)}
  304. nv3 := (*[3]interface{})(nil)
  305. pv3 := &v3
  306. v3Addr := fmt.Sprintf("%p", pv3)
  307. pv3Addr := fmt.Sprintf("%p", &pv3)
  308. v3t := "[3]interface {}"
  309. v3t2 := "string"
  310. v3t3 := "int"
  311. v3t4 := "uint"
  312. v3s := "{\n (" + v3t2 + ") \"one\",\n (" + v3t3 + ") 2,\n (" + v3t4 +
  313. ") 3\n}"
  314. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  315. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  316. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  317. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  318. }
  319. func addSliceDumpTests() {
  320. // Slice containing standard float32 values.
  321. v := []float32{3.14, 6.28, 12.56}
  322. nv := (*[]float32)(nil)
  323. pv := &v
  324. vAddr := fmt.Sprintf("%p", pv)
  325. pvAddr := fmt.Sprintf("%p", &pv)
  326. vt := "float32"
  327. vs := "{\n (" + vt + ") 3.14,\n (" + vt + ") 6.28,\n (" + vt + ") 12.56\n}"
  328. addDumpTest(v, "([]"+vt+") "+vs+"\n")
  329. addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
  330. addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  331. addDumpTest(nv, "(*[]"+vt+")(<nil>)\n")
  332. // Slice containing type with custom formatter on pointer receiver only.
  333. v2 := []pstringer{"1", "2", "3"}
  334. nv2 := (*[]pstringer)(nil)
  335. pv2 := &v2
  336. v2Addr := fmt.Sprintf("%p", pv2)
  337. pv2Addr := fmt.Sprintf("%p", &pv2)
  338. v2t := "spew_test.pstringer"
  339. v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
  340. v2t + ") stringer 3\n}"
  341. addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
  342. addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
  343. addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  344. addDumpTest(nv2, "(*[]"+v2t+")(<nil>)\n")
  345. // Slice containing interfaces.
  346. v3 := []interface{}{"one", int(2), uint(3)}
  347. nv3 := (*[]interface{})(nil)
  348. pv3 := &v3
  349. v3Addr := fmt.Sprintf("%p", pv3)
  350. pv3Addr := fmt.Sprintf("%p", &pv3)
  351. v3t := "[]interface {}"
  352. v3t2 := "string"
  353. v3t3 := "int"
  354. v3t4 := "uint"
  355. v3s := "{\n (" + v3t2 + ") \"one\",\n (" + v3t3 + ") 2,\n (" + v3t4 +
  356. ") 3\n}"
  357. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  358. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  359. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  360. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  361. }
  362. func addStringDumpTests() {
  363. // Standard string.
  364. v := "test"
  365. nv := (*string)(nil)
  366. pv := &v
  367. vAddr := fmt.Sprintf("%p", pv)
  368. pvAddr := fmt.Sprintf("%p", &pv)
  369. vt := "string"
  370. vs := "\"test\""
  371. addDumpTest(v, "("+vt+") "+vs+"\n")
  372. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  373. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  374. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  375. }
  376. func addInterfaceDumpTests() {
  377. // Nil interface.
  378. var v interface{}
  379. nv := (*interface{})(nil)
  380. pv := &v
  381. vAddr := fmt.Sprintf("%p", pv)
  382. pvAddr := fmt.Sprintf("%p", &pv)
  383. vt := "interface {}"
  384. vs := "<nil>"
  385. addDumpTest(v, "("+vt+") "+vs+"\n")
  386. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  387. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  388. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  389. // Sub-interface.
  390. v2 := interface{}(uint16(65535))
  391. pv2 := &v2
  392. v2Addr := fmt.Sprintf("%p", pv2)
  393. pv2Addr := fmt.Sprintf("%p", &pv2)
  394. v2t := "uint16"
  395. v2s := "65535"
  396. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  397. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  398. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  399. }
  400. func addMapDumpTests() {
  401. // Map with string keys and int vals.
  402. v := map[string]int{"one": 1, "two": 2}
  403. nv := (*map[string]int)(nil)
  404. pv := &v
  405. vAddr := fmt.Sprintf("%p", pv)
  406. pvAddr := fmt.Sprintf("%p", &pv)
  407. vt := "map[string]int"
  408. vt1 := "string"
  409. vt2 := "int"
  410. vs := "{\n (" + vt1 + ") \"one\": (" + vt2 + ") 1,\n (" + vt1 +
  411. ") \"two\": (" + vt2 + ") 2\n}"
  412. vs2 := "{\n (" + vt1 + ") \"two\": (" + vt2 + ") 2,\n (" + vt1 +
  413. ") \"one\": (" + vt2 + ") 1\n}"
  414. addDumpTest(v, "("+vt+") "+vs+"\n", "("+vt+") "+vs2+"\n")
  415. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n",
  416. "(*"+vt+")("+vAddr+")("+vs2+")\n")
  417. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n",
  418. "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
  419. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  420. // Map with custom formatter type on pointer receiver only keys and vals.
  421. v2 := map[pstringer]pstringer{"one": "1"}
  422. nv2 := (*map[pstringer]pstringer)(nil)
  423. pv2 := &v2
  424. v2Addr := fmt.Sprintf("%p", pv2)
  425. pv2Addr := fmt.Sprintf("%p", &pv2)
  426. v2t := "map[spew_test.pstringer]spew_test.pstringer"
  427. v2t1 := "spew_test.pstringer"
  428. v2t2 := "spew_test.pstringer"
  429. v2s := "{\n (" + v2t1 + ") stringer one: (" + v2t2 + ") stringer 1\n}"
  430. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  431. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  432. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  433. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  434. // Map with interface keys and values.
  435. v3 := map[interface{}]interface{}{"one": 1}
  436. nv3 := (*map[interface{}]interface{})(nil)
  437. pv3 := &v3
  438. v3Addr := fmt.Sprintf("%p", pv3)
  439. pv3Addr := fmt.Sprintf("%p", &pv3)
  440. v3t := "map[interface {}]interface {}"
  441. v3t1 := "string"
  442. v3t2 := "int"
  443. v3s := "{\n (" + v3t1 + ") \"one\": (" + v3t2 + ") 1\n}"
  444. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  445. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  446. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  447. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  448. }
  449. func addStructDumpTests() {
  450. // Struct with primitives.
  451. type s1 struct {
  452. a int8
  453. b uint8
  454. }
  455. v := s1{127, 255}
  456. nv := (*s1)(nil)
  457. pv := &v
  458. vAddr := fmt.Sprintf("%p", pv)
  459. pvAddr := fmt.Sprintf("%p", &pv)
  460. vt := "spew_test.s1"
  461. vt2 := "int8"
  462. vt3 := "uint8"
  463. vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
  464. addDumpTest(v, "("+vt+") "+vs+"\n")
  465. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  466. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  467. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  468. // Struct that contains another struct.
  469. type s2 struct {
  470. s1 s1
  471. b bool
  472. }
  473. v2 := s2{s1{127, 255}, true}
  474. nv2 := (*s2)(nil)
  475. pv2 := &v2
  476. v2Addr := fmt.Sprintf("%p", pv2)
  477. pv2Addr := fmt.Sprintf("%p", &pv2)
  478. v2t := "spew_test.s2"
  479. v2t2 := "spew_test.s1"
  480. v2t3 := "int8"
  481. v2t4 := "uint8"
  482. v2t5 := "bool"
  483. v2s := "{\n s1: (" + v2t2 + ") {\n a: (" + v2t3 + ") 127,\n b: (" +
  484. v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
  485. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  486. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  487. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  488. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  489. // Struct that contains custom type with Stringer pointer interface via both
  490. // exported and unexported fields.
  491. type s3 struct {
  492. s pstringer
  493. S pstringer
  494. }
  495. v3 := s3{"test", "test2"}
  496. nv3 := (*s3)(nil)
  497. pv3 := &v3
  498. v3Addr := fmt.Sprintf("%p", pv3)
  499. pv3Addr := fmt.Sprintf("%p", &pv3)
  500. v3t := "spew_test.s3"
  501. v3t2 := "spew_test.pstringer"
  502. v3s := "{\n s: (" + v3t2 + ") stringer test,\n S: (" + v3t2 +
  503. ") stringer test2\n}"
  504. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  505. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  506. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  507. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  508. // Struct that contains embedded struct and field to same struct.
  509. e := embed{"embedstr"}
  510. v4 := embedwrap{embed: &e, e: &e}
  511. nv4 := (*embedwrap)(nil)
  512. pv4 := &v4
  513. eAddr := fmt.Sprintf("%p", &e)
  514. v4Addr := fmt.Sprintf("%p", pv4)
  515. pv4Addr := fmt.Sprintf("%p", &pv4)
  516. v4t := "spew_test.embedwrap"
  517. v4t2 := "spew_test.embed"
  518. v4t3 := "string"
  519. v4s := "{\n embed: (*" + v4t2 + ")(" + eAddr + ")({\n a: (" + v4t3 +
  520. ") \"embedstr\"\n }),\n e: (*" + v4t2 + ")(" + eAddr + ")({\n" +
  521. " a: (" + v4t3 + ") \"embedstr\"\n })\n}"
  522. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  523. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  524. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  525. addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
  526. }
  527. func addUintptrDumpTests() {
  528. // Null pointer.
  529. v := uintptr(0)
  530. pv := &v
  531. vAddr := fmt.Sprintf("%p", pv)
  532. pvAddr := fmt.Sprintf("%p", &pv)
  533. vt := "uintptr"
  534. vs := "<nil>"
  535. addDumpTest(v, "("+vt+") "+vs+"\n")
  536. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  537. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  538. // Address of real variable.
  539. i := 1
  540. v2 := uintptr(unsafe.Pointer(&i))
  541. nv2 := (*uintptr)(nil)
  542. pv2 := &v2
  543. v2Addr := fmt.Sprintf("%p", pv2)
  544. pv2Addr := fmt.Sprintf("%p", &pv2)
  545. v2t := "uintptr"
  546. v2s := fmt.Sprintf("%p", &i)
  547. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  548. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  549. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  550. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  551. }
  552. func addUnsafePointerDumpTests() {
  553. // Null pointer.
  554. v := unsafe.Pointer(uintptr(0))
  555. nv := (*unsafe.Pointer)(nil)
  556. pv := &v
  557. vAddr := fmt.Sprintf("%p", pv)
  558. pvAddr := fmt.Sprintf("%p", &pv)
  559. vt := "unsafe.Pointer"
  560. vs := "<nil>"
  561. addDumpTest(v, "("+vt+") "+vs+"\n")
  562. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  563. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  564. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  565. // Address of real variable.
  566. i := 1
  567. v2 := unsafe.Pointer(&i)
  568. pv2 := &v2
  569. v2Addr := fmt.Sprintf("%p", pv2)
  570. pv2Addr := fmt.Sprintf("%p", &pv2)
  571. v2t := "unsafe.Pointer"
  572. v2s := fmt.Sprintf("%p", &i)
  573. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  574. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  575. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  576. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  577. }
  578. func addChanDumpTests() {
  579. // Nil channel.
  580. var v chan int
  581. pv := &v
  582. nv := (*chan int)(nil)
  583. vAddr := fmt.Sprintf("%p", pv)
  584. pvAddr := fmt.Sprintf("%p", &pv)
  585. vt := "chan int"
  586. vs := "<nil>"
  587. addDumpTest(v, "("+vt+") "+vs+"\n")
  588. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  589. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  590. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  591. // Real channel.
  592. v2 := make(chan int)
  593. pv2 := &v2
  594. v2Addr := fmt.Sprintf("%p", pv2)
  595. pv2Addr := fmt.Sprintf("%p", &pv2)
  596. v2t := "chan int"
  597. v2s := fmt.Sprintf("%p", v2)
  598. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  599. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  600. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  601. }
  602. func addFuncDumpTests() {
  603. // Function with no params and no returns.
  604. v := addIntDumpTests
  605. nv := (*func())(nil)
  606. pv := &v
  607. vAddr := fmt.Sprintf("%p", pv)
  608. pvAddr := fmt.Sprintf("%p", &pv)
  609. vt := "func()"
  610. vs := fmt.Sprintf("%p", v)
  611. addDumpTest(v, "("+vt+") "+vs+"\n")
  612. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  613. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  614. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  615. // Function with param and no returns.
  616. v2 := TestDump
  617. nv2 := (*func(*testing.T))(nil)
  618. pv2 := &v2
  619. v2Addr := fmt.Sprintf("%p", pv2)
  620. pv2Addr := fmt.Sprintf("%p", &pv2)
  621. v2t := "func(*testing.T)"
  622. v2s := fmt.Sprintf("%p", v2)
  623. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  624. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  625. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  626. addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
  627. // Function with multiple params and multiple returns.
  628. var v3 = func(i int, s string) (b bool, err error) {
  629. return true, nil
  630. }
  631. nv3 := (*func(int, string) (bool, error))(nil)
  632. pv3 := &v3
  633. v3Addr := fmt.Sprintf("%p", pv3)
  634. pv3Addr := fmt.Sprintf("%p", &pv3)
  635. v3t := "func(int, string) (bool, error)"
  636. v3s := fmt.Sprintf("%p", v3)
  637. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  638. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  639. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  640. addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
  641. }
  642. func addCircularDumpTests() {
  643. // Struct that is circular through self referencing.
  644. type circular struct {
  645. c *circular
  646. }
  647. v := circular{nil}
  648. v.c = &v
  649. pv := &v
  650. vAddr := fmt.Sprintf("%p", pv)
  651. pvAddr := fmt.Sprintf("%p", &pv)
  652. vt := "spew_test.circular"
  653. vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n c: (*" + vt + ")(" +
  654. vAddr + ")(<already shown>)\n })\n}"
  655. vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
  656. addDumpTest(v, "("+vt+") "+vs+"\n")
  657. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
  658. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
  659. // Structs that are circular through cross referencing.
  660. v2 := xref1{nil}
  661. ts2 := xref2{&v2}
  662. v2.ps2 = &ts2
  663. pv2 := &v2
  664. ts2Addr := fmt.Sprintf("%p", &ts2)
  665. v2Addr := fmt.Sprintf("%p", pv2)
  666. pv2Addr := fmt.Sprintf("%p", &pv2)
  667. v2t := "spew_test.xref1"
  668. v2t2 := "spew_test.xref2"
  669. v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  670. ")(" + v2Addr + ")({\n ps2: (*" + v2t2 + ")(" + ts2Addr +
  671. ")(<already shown>)\n })\n })\n}"
  672. v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  673. ")(" + v2Addr + ")(<already shown>)\n })\n}"
  674. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  675. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
  676. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
  677. // Structs that are indirectly circular.
  678. v3 := indirCir1{nil}
  679. tic2 := indirCir2{nil}
  680. tic3 := indirCir3{&v3}
  681. tic2.ps3 = &tic3
  682. v3.ps2 = &tic2
  683. pv3 := &v3
  684. tic2Addr := fmt.Sprintf("%p", &tic2)
  685. tic3Addr := fmt.Sprintf("%p", &tic3)
  686. v3Addr := fmt.Sprintf("%p", pv3)
  687. pv3Addr := fmt.Sprintf("%p", &pv3)
  688. v3t := "spew_test.indirCir1"
  689. v3t2 := "spew_test.indirCir2"
  690. v3t3 := "spew_test.indirCir3"
  691. v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  692. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  693. ")({\n ps2: (*" + v3t2 + ")(" + tic2Addr +
  694. ")(<already shown>)\n })\n })\n })\n}"
  695. v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  696. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  697. ")(<already shown>)\n })\n })\n}"
  698. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  699. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
  700. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
  701. }
  702. func addPanicDumpTests() {
  703. // Type that panics in its Stringer interface.
  704. v := panicer(127)
  705. nv := (*panicer)(nil)
  706. pv := &v
  707. vAddr := fmt.Sprintf("%p", pv)
  708. pvAddr := fmt.Sprintf("%p", &pv)
  709. vt := "spew_test.panicer"
  710. vs := "(PANIC=test panic)127"
  711. addDumpTest(v, "("+vt+") "+vs+"\n")
  712. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  713. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  714. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  715. }
  716. func addErrorDumpTests() {
  717. // Type that has a custom Error interface.
  718. v := customError(127)
  719. nv := (*customError)(nil)
  720. pv := &v
  721. vAddr := fmt.Sprintf("%p", pv)
  722. pvAddr := fmt.Sprintf("%p", &pv)
  723. vt := "spew_test.customError"
  724. vs := "error: 127"
  725. addDumpTest(v, "("+vt+") "+vs+"\n")
  726. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  727. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  728. addDumpTest(nv, "(*"+vt+")(<nil>)\n")
  729. }
  730. // TestDump executes all of the tests described by dumpTests.
  731. func TestDump(t *testing.T) {
  732. // Setup tests.
  733. addIntDumpTests()
  734. addUintDumpTests()
  735. addBoolDumpTests()
  736. addFloatDumpTests()
  737. addComplexDumpTests()
  738. addArrayDumpTests()
  739. addSliceDumpTests()
  740. addStringDumpTests()
  741. addInterfaceDumpTests()
  742. addMapDumpTests()
  743. addStructDumpTests()
  744. addUintptrDumpTests()
  745. addUnsafePointerDumpTests()
  746. addChanDumpTests()
  747. addFuncDumpTests()
  748. addCircularDumpTests()
  749. addPanicDumpTests()
  750. addErrorDumpTests()
  751. t.Logf("Running %d tests", len(dumpTests))
  752. for i, test := range dumpTests {
  753. buf := new(bytes.Buffer)
  754. spew.Fdump(buf, test.in)
  755. s := buf.String()
  756. if testFailed(s, test.wants) {
  757. t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
  758. continue
  759. }
  760. }
  761. }