dump_test.go 24 KB

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