dump_test.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  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 addIntTests() {
  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 addUintTests() {
  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 addBoolTests() {
  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 addFloatTests() {
  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 addComplexTests() {
  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 addArrayTests() {
  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 addSliceTests() {
  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 addStringTests() {
  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 addNilInterfaceTests() {
  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 addMapTests() {
  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 addStructTests() {
  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 addUintptrTests() {
  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 addUnsafePointerTests() {
  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 addChanTests() {
  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 addFuncTests() {
  559. // Function with no params and no returns.
  560. v := addIntTests
  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 addCircularTests() {
  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. t.Logf("Running %d tests", len(dumpTests))
  661. for i, test := range dumpTests {
  662. buf := new(bytes.Buffer)
  663. spew.Fdump(buf, test.in)
  664. s := buf.String()
  665. if test.want != s {
  666. t.Errorf("Dump #%d\n got: %s want: %s", i, s, test.want)
  667. continue
  668. }
  669. }
  670. }
  671. // Setup tests.
  672. func init() {
  673. addIntTests()
  674. addUintTests()
  675. addBoolTests()
  676. addFloatTests()
  677. addComplexTests()
  678. addArrayTests()
  679. addSliceTests()
  680. addStringTests()
  681. addNilInterfaceTests()
  682. addMapTests()
  683. addStructTests()
  684. addUintptrTests()
  685. addUnsafePointerTests()
  686. addChanTests()
  687. addFuncTests()
  688. addCircularTests()
  689. }