dump_test.go 22 KB

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