dump_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  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 pointer and double pointer to the base test element
  19. 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. pv := &v
  101. vAddr := fmt.Sprintf("%p", pv)
  102. pvAddr := fmt.Sprintf("%p", &pv)
  103. vt := "int8"
  104. vs := "127"
  105. addDumpTest(v, "("+vt+") "+vs+"\n")
  106. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  107. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  108. // Max int16.
  109. v2 := int16(32767)
  110. pv2 := &v2
  111. v2Addr := fmt.Sprintf("%p", pv2)
  112. pv2Addr := fmt.Sprintf("%p", &pv2)
  113. v2t := "int16"
  114. v2s := "32767"
  115. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  116. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  117. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  118. // Max int32.
  119. v3 := int32(2147483647)
  120. pv3 := &v3
  121. v3Addr := fmt.Sprintf("%p", pv3)
  122. pv3Addr := fmt.Sprintf("%p", &pv3)
  123. v3t := "int32"
  124. v3s := "2147483647"
  125. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  126. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  127. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  128. // Max int64.
  129. v4 := int64(9223372036854775807)
  130. pv4 := &v4
  131. v4Addr := fmt.Sprintf("%p", pv4)
  132. pv4Addr := fmt.Sprintf("%p", &pv4)
  133. v4t := "int64"
  134. v4s := "9223372036854775807"
  135. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  136. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  137. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  138. // Max int.
  139. v5 := int(2147483647)
  140. pv5 := &v5
  141. v5Addr := fmt.Sprintf("%p", pv5)
  142. pv5Addr := fmt.Sprintf("%p", &pv5)
  143. v5t := "int"
  144. v5s := "2147483647"
  145. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  146. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  147. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  148. }
  149. func addUintTests() {
  150. // Max uint8.
  151. v := uint8(255)
  152. pv := &v
  153. vAddr := fmt.Sprintf("%p", pv)
  154. pvAddr := fmt.Sprintf("%p", &pv)
  155. vt := "uint8"
  156. vs := "255"
  157. addDumpTest(v, "("+vt+") "+vs+"\n")
  158. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  159. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  160. // Max uint16.
  161. v2 := uint16(65535)
  162. pv2 := &v2
  163. v2Addr := fmt.Sprintf("%p", pv2)
  164. pv2Addr := fmt.Sprintf("%p", &pv2)
  165. v2t := "uint16"
  166. v2s := "65535"
  167. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  168. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  169. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  170. // Max uint32.
  171. v3 := uint32(4294967295)
  172. pv3 := &v3
  173. v3Addr := fmt.Sprintf("%p", pv3)
  174. pv3Addr := fmt.Sprintf("%p", &pv3)
  175. v3t := "uint32"
  176. v3s := "4294967295"
  177. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  178. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  179. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  180. // Max uint64.
  181. v4 := uint64(18446744073709551615)
  182. pv4 := &v4
  183. v4Addr := fmt.Sprintf("%p", pv4)
  184. pv4Addr := fmt.Sprintf("%p", &pv4)
  185. v4t := "uint64"
  186. v4s := "18446744073709551615"
  187. addDumpTest(v4, "("+v4t+") "+v4s+"\n")
  188. addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
  189. addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
  190. // Max uint.
  191. v5 := uint(4294967295)
  192. pv5 := &v5
  193. v5Addr := fmt.Sprintf("%p", pv5)
  194. pv5Addr := fmt.Sprintf("%p", &pv5)
  195. v5t := "uint"
  196. v5s := "4294967295"
  197. addDumpTest(v5, "("+v5t+") "+v5s+"\n")
  198. addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
  199. addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
  200. }
  201. func addBoolTests() {
  202. // Boolean true.
  203. v := bool(true)
  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. // Boolean false.
  213. v2 := bool(false)
  214. pv2 := &v2
  215. v2Addr := fmt.Sprintf("%p", pv2)
  216. pv2Addr := fmt.Sprintf("%p", &pv2)
  217. v2t := "bool"
  218. v2s := "false"
  219. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  220. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  221. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  222. }
  223. func addFloatTests() {
  224. // Standard float32.
  225. v := float32(3.1415)
  226. pv := &v
  227. vAddr := fmt.Sprintf("%p", pv)
  228. pvAddr := fmt.Sprintf("%p", &pv)
  229. vt := "float32"
  230. vs := "3.1415"
  231. addDumpTest(v, "("+vt+") "+vs+"\n")
  232. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  233. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  234. // Standard float64.
  235. v2 := float64(3.1415926)
  236. pv2 := &v2
  237. v2Addr := fmt.Sprintf("%p", pv2)
  238. pv2Addr := fmt.Sprintf("%p", &pv2)
  239. v2t := "float64"
  240. v2s := "3.1415926"
  241. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  242. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  243. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  244. }
  245. func addComplexTests() {
  246. // Standard complex64.
  247. v := complex(float32(6), -2)
  248. pv := &v
  249. vAddr := fmt.Sprintf("%p", pv)
  250. pvAddr := fmt.Sprintf("%p", &pv)
  251. vt := "complex64"
  252. vs := "(6-2i)"
  253. addDumpTest(v, "("+vt+") "+vs+"\n")
  254. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  255. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  256. // Standard complex128.
  257. v2 := complex(float64(-6), 2)
  258. pv2 := &v2
  259. v2Addr := fmt.Sprintf("%p", pv2)
  260. pv2Addr := fmt.Sprintf("%p", &pv2)
  261. v2t := "complex128"
  262. v2s := "(-6+2i)"
  263. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  264. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  265. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  266. }
  267. func addArrayTests() {
  268. // Array containing standard ints.
  269. v := [3]int{1, 2, 3}
  270. pv := &v
  271. vAddr := fmt.Sprintf("%p", pv)
  272. pvAddr := fmt.Sprintf("%p", &pv)
  273. vt := "int"
  274. vs := "{\n (" + vt + ") 1,\n (" + vt + ") 2,\n (" + vt + ") 3\n}"
  275. addDumpTest(v, "([3]"+vt+") "+vs+"\n")
  276. addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
  277. addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  278. // Array containing type with custom formatter on pointer receiver only.
  279. v2 := [3]pstringer{"1", "2", "3"}
  280. pv2 := &v2
  281. v2Addr := fmt.Sprintf("%p", pv2)
  282. pv2Addr := fmt.Sprintf("%p", &pv2)
  283. v2t := "spew_test.pstringer"
  284. v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
  285. v2t + ") stringer 3\n}"
  286. addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
  287. addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2s+")\n")
  288. addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  289. }
  290. func addSliceTests() {
  291. // Slice containing standard float32 values.
  292. v := []float32{3.14, 6.28, 12.56}
  293. pv := &v
  294. vAddr := fmt.Sprintf("%p", pv)
  295. pvAddr := fmt.Sprintf("%p", &pv)
  296. vt := "float32"
  297. vs := "{\n (" + vt + ") 3.14,\n (" + vt + ") 6.28,\n (" + vt + ") 12.56\n}"
  298. addDumpTest(v, "([]"+vt+") "+vs+"\n")
  299. addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
  300. addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  301. // Slice containing type with custom formatter on pointer receiver only.
  302. v2 := []pstringer{"1", "2", "3"}
  303. pv2 := &v2
  304. v2Addr := fmt.Sprintf("%p", pv2)
  305. pv2Addr := fmt.Sprintf("%p", &pv2)
  306. v2t := "spew_test.pstringer"
  307. v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
  308. v2t + ") stringer 3\n}"
  309. addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
  310. addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
  311. addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  312. }
  313. func addStringTests() {
  314. // Standard string.
  315. v := "test"
  316. pv := &v
  317. vAddr := fmt.Sprintf("%p", pv)
  318. pvAddr := fmt.Sprintf("%p", &pv)
  319. vt := "string"
  320. vs := "\"test\""
  321. addDumpTest(v, "("+vt+") "+vs+"\n")
  322. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  323. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  324. }
  325. func addNilInterfaceTests() {
  326. // Nil interface.
  327. var v interface{}
  328. pv := &v
  329. vAddr := fmt.Sprintf("%p", pv)
  330. pvAddr := fmt.Sprintf("%p", &pv)
  331. vt := "interface {}"
  332. vs := "<nil>"
  333. addDumpTest(v, "("+vt+") "+vs+"\n")
  334. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  335. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  336. }
  337. func addMapTests() {
  338. // Map with string keys and int vals.
  339. v := map[string]int{"one": 1}
  340. pv := &v
  341. vAddr := fmt.Sprintf("%p", pv)
  342. pvAddr := fmt.Sprintf("%p", &pv)
  343. vt := "map[string]int"
  344. vt1 := "string"
  345. vt2 := "int"
  346. vs := "{\n (" + vt1 + ") \"one\": (" + vt2 + ") 1\n}"
  347. addDumpTest(v, "("+vt+") "+vs+"\n")
  348. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  349. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  350. // Map with custom formatter type on pointer receiver only keys and vals.
  351. v2 := map[pstringer]pstringer{"one": "1"}
  352. pv2 := &v2
  353. v2Addr := fmt.Sprintf("%p", pv2)
  354. pv2Addr := fmt.Sprintf("%p", &pv2)
  355. v2t := "map[spew_test.pstringer]spew_test.pstringer"
  356. v2t1 := "spew_test.pstringer"
  357. v2t2 := "spew_test.pstringer"
  358. v2s := "{\n (" + v2t1 + ") stringer one: (" + v2t2 + ") stringer 1\n}"
  359. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  360. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  361. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  362. // Map with interface keys and values.
  363. v3 := map[interface{}]interface{}{"one": 1}
  364. pv3 := &v3
  365. v3Addr := fmt.Sprintf("%p", pv3)
  366. pv3Addr := fmt.Sprintf("%p", &pv3)
  367. v3t := "map[interface {}]interface {}"
  368. v3t1 := "string"
  369. v3t2 := "int"
  370. v3s := "{\n (" + v3t1 + ") \"one\": (" + v3t2 + ") 1\n}"
  371. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  372. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  373. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  374. }
  375. func addStructTests() {
  376. // Struct with primitives.
  377. type s1 struct {
  378. a int8
  379. b uint8
  380. }
  381. v := s1{127, 255}
  382. pv := &v
  383. vAddr := fmt.Sprintf("%p", pv)
  384. pvAddr := fmt.Sprintf("%p", &pv)
  385. vt := "spew_test.s1"
  386. vt2 := "int8"
  387. vt3 := "uint8"
  388. vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
  389. addDumpTest(v, "("+vt+") "+vs+"\n")
  390. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  391. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  392. // Struct that contains another struct.
  393. type s2 struct {
  394. s1 s1
  395. b bool
  396. }
  397. v2 := s2{s1{127, 255}, true}
  398. pv2 := &v2
  399. v2Addr := fmt.Sprintf("%p", pv2)
  400. pv2Addr := fmt.Sprintf("%p", &pv2)
  401. v2t := "spew_test.s2"
  402. v2t2 := "spew_test.s1"
  403. v2t3 := "int8"
  404. v2t4 := "uint8"
  405. v2t5 := "bool"
  406. v2s := "{\n s1: (" + v2t2 + ") {\n a: (" + v2t3 + ") 127,\n b: (" +
  407. v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
  408. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  409. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  410. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  411. // Struct that contains custom type with Stringer pointer interface via both
  412. // exported and unexported fields.
  413. type s3 struct {
  414. s pstringer
  415. S pstringer
  416. }
  417. v3 := s3{"test", "test2"}
  418. pv3 := &v3
  419. v3Addr := fmt.Sprintf("%p", pv3)
  420. pv3Addr := fmt.Sprintf("%p", &pv3)
  421. v3t := "spew_test.s3"
  422. v3t2 := "spew_test.pstringer"
  423. v3s := "{\n s: (" + v3t2 + ") stringer test,\n S: (" + v3t2 +
  424. ") stringer test2\n}"
  425. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  426. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  427. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  428. }
  429. func addUintptrTests() {
  430. // Null pointer.
  431. v := uintptr(0)
  432. pv := &v
  433. vAddr := fmt.Sprintf("%p", pv)
  434. pvAddr := fmt.Sprintf("%p", &pv)
  435. vt := "uintptr"
  436. vs := "<nil>"
  437. addDumpTest(v, "("+vt+") "+vs+"\n")
  438. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  439. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  440. // Address of real variable.
  441. i := 1
  442. v2 := uintptr(unsafe.Pointer(&i))
  443. pv2 := &v2
  444. v2Addr := fmt.Sprintf("%p", pv2)
  445. pv2Addr := fmt.Sprintf("%p", &pv2)
  446. v2t := "uintptr"
  447. v2s := fmt.Sprintf("%p", &i)
  448. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  449. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  450. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  451. }
  452. func addUnsafePointerTests() {
  453. // Null pointer.
  454. v := unsafe.Pointer(uintptr(0))
  455. pv := &v
  456. vAddr := fmt.Sprintf("%p", pv)
  457. pvAddr := fmt.Sprintf("%p", &pv)
  458. vt := "unsafe.Pointer"
  459. vs := "<nil>"
  460. addDumpTest(v, "("+vt+") "+vs+"\n")
  461. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  462. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  463. // Address of real variable.
  464. i := 1
  465. v2 := unsafe.Pointer(&i)
  466. pv2 := &v2
  467. v2Addr := fmt.Sprintf("%p", pv2)
  468. pv2Addr := fmt.Sprintf("%p", &pv2)
  469. v2t := "unsafe.Pointer"
  470. v2s := fmt.Sprintf("%p", &i)
  471. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  472. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  473. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  474. }
  475. func addChanTests() {
  476. // Nil channel.
  477. var v chan int
  478. pv := &v
  479. vAddr := fmt.Sprintf("%p", pv)
  480. pvAddr := fmt.Sprintf("%p", &pv)
  481. vt := "chan int"
  482. vs := "<nil>"
  483. addDumpTest(v, "("+vt+") "+vs+"\n")
  484. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  485. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  486. // Real channel.
  487. v2 := make(chan int)
  488. pv2 := &v2
  489. v2Addr := fmt.Sprintf("%p", pv2)
  490. pv2Addr := fmt.Sprintf("%p", &pv2)
  491. v2t := "chan int"
  492. v2s := fmt.Sprintf("%p", v2)
  493. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  494. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  495. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  496. }
  497. func addFuncTests() {
  498. // Function with no params and no returns.
  499. v := addIntTests
  500. pv := &v
  501. vAddr := fmt.Sprintf("%p", pv)
  502. pvAddr := fmt.Sprintf("%p", &pv)
  503. vt := "func()"
  504. vs := fmt.Sprintf("%p", v)
  505. addDumpTest(v, "("+vt+") "+vs+"\n")
  506. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
  507. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
  508. // Function with param and no returns.
  509. v2 := TestDump
  510. pv2 := &v2
  511. v2Addr := fmt.Sprintf("%p", pv2)
  512. pv2Addr := fmt.Sprintf("%p", &pv2)
  513. v2t := "func(*testing.T)"
  514. v2s := fmt.Sprintf("%p", v2)
  515. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  516. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
  517. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
  518. // Function with multiple params and multiple returns.
  519. var v3 = func(i int, s string) (b bool, err error) {
  520. return true, nil
  521. }
  522. pv3 := &v3
  523. v3Addr := fmt.Sprintf("%p", pv3)
  524. pv3Addr := fmt.Sprintf("%p", &pv3)
  525. v3t := "func(int, string) (bool, error)"
  526. v3s := fmt.Sprintf("%p", v3)
  527. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  528. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
  529. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
  530. }
  531. func addCircularTests() {
  532. // Struct that is circular through self referencing.
  533. type circular struct {
  534. c *circular
  535. }
  536. v := circular{nil}
  537. v.c = &v
  538. pv := &v
  539. vAddr := fmt.Sprintf("%p", pv)
  540. pvAddr := fmt.Sprintf("%p", &pv)
  541. vt := "spew_test.circular"
  542. vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n c: (*" + vt + ")(" +
  543. vAddr + ")(<already shown>)\n })\n}"
  544. vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
  545. addDumpTest(v, "("+vt+") "+vs+"\n")
  546. addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
  547. addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
  548. // Structs that are circular through cross referencing.
  549. v2 := xref1{nil}
  550. ts2 := xref2{&v2}
  551. v2.ps2 = &ts2
  552. pv2 := &v2
  553. ts2Addr := fmt.Sprintf("%p", &ts2)
  554. v2Addr := fmt.Sprintf("%p", pv2)
  555. pv2Addr := fmt.Sprintf("%p", &pv2)
  556. v2t := "spew_test.xref1"
  557. v2t2 := "spew_test.xref2"
  558. v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  559. ")(" + v2Addr + ")({\n ps2: (*" + v2t2 + ")(" + ts2Addr +
  560. ")(<already shown>)\n })\n })\n}"
  561. v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
  562. ")(" + v2Addr + ")(<already shown>)\n })\n}"
  563. addDumpTest(v2, "("+v2t+") "+v2s+"\n")
  564. addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
  565. addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
  566. // Structs that are indirectly circular.
  567. v3 := indirCir1{nil}
  568. tic2 := indirCir2{nil}
  569. tic3 := indirCir3{&v3}
  570. tic2.ps3 = &tic3
  571. v3.ps2 = &tic2
  572. pv3 := &v3
  573. tic2Addr := fmt.Sprintf("%p", &tic2)
  574. tic3Addr := fmt.Sprintf("%p", &tic3)
  575. v3Addr := fmt.Sprintf("%p", pv3)
  576. pv3Addr := fmt.Sprintf("%p", &pv3)
  577. v3t := "spew_test.indirCir1"
  578. v3t2 := "spew_test.indirCir2"
  579. v3t3 := "spew_test.indirCir3"
  580. v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  581. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  582. ")({\n ps2: (*" + v3t2 + ")(" + tic2Addr +
  583. ")(<already shown>)\n })\n })\n })\n}"
  584. v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
  585. ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
  586. ")(<already shown>)\n })\n })\n}"
  587. addDumpTest(v3, "("+v3t+") "+v3s+"\n")
  588. addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
  589. addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
  590. }
  591. // TestDump executes all of the tests described by dumpTests.
  592. func TestDump(t *testing.T) {
  593. t.Logf("Running %d tests", len(dumpTests))
  594. for i, test := range dumpTests {
  595. buf := new(bytes.Buffer)
  596. spew.Fdump(buf, test.in)
  597. s := buf.String()
  598. if test.want != buf.String() {
  599. t.Errorf("Dump #%d\n got: %s want: %s", i, s, test.want)
  600. continue
  601. }
  602. }
  603. }
  604. // Setup tests.f
  605. func init() {
  606. addIntTests()
  607. addUintTests()
  608. addBoolTests()
  609. addFloatTests()
  610. addComplexTests()
  611. addArrayTests()
  612. addSliceTests()
  613. addStringTests()
  614. addNilInterfaceTests()
  615. addMapTests()
  616. addStructTests()
  617. addUintptrTests()
  618. addUnsafePointerTests()
  619. addChanTests()
  620. addFuncTests()
  621. addCircularTests()
  622. }