2 * Copyright (c) 2013 Dave Collins <dave@davec.name>
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.
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.
19 NOTE: For each test, a nil pointer, a single pointer and double pointer to the
20 base test element are also tested to ensure proper indirection across all types.
22 - Max int8, int16, int32, int64, int
23 - Max uint8, uint16, uint32, uint64, uint
24 - Boolean true and false
25 - Standard complex64 and complex128
26 - Array containing standard ints
27 - Array containing type with custom formatter on pointer receiver only
28 - Array containing interfaces
29 - Array containing bytes
30 - Slice containing standard float32 values
31 - Slice containing type with custom formatter on pointer receiver only
32 - Slice containing interfaces
33 - Slice containing bytes
38 - Map with string keys and int vals
39 - Map with custom formatter type on pointer receiver only keys and vals
40 - Map with interface keys and values
41 - Map with nil interface value
42 - Struct with primitives
43 - Struct that contains another struct
44 - Struct that contains custom type with Stringer pointer interface via both
45 exported and unexported fields
46 - Struct that contains embedded struct and field to same struct
47 - Uintptr to 0 (null pointer)
48 - Uintptr address of real variable
49 - Unsafe.Pointer to 0 (null pointer)
50 - Unsafe.Pointer to address of real variable
52 - Standard int channel
53 - Function with no params and no returns
54 - Function with param and no returns
55 - Function with multiple params and multiple returns
56 - Struct that is circular through self referencing
57 - Structs that are circular through cross referencing
58 - Structs that are indirectly circular
59 - Type that panics in its Stringer interface
70 "github.com/davecgh/go-spew/spew"
73 // dumpTest is used to describe a test to be perfomed against the Dump method.
74 type dumpTest struct {
79 // dumpTests houses all of the tests to be performed against the Dump method.
80 var dumpTests = make([]dumpTest, 0)
82 // addDumpTest is a helper method to append the passed input and desired result
84 func addDumpTest(in interface{}, wants ...string) {
85 test := dumpTest{in, wants}
86 dumpTests = append(dumpTests, test)
89 func addIntDumpTests() {
94 vAddr := fmt.Sprintf("%p", pv)
95 pvAddr := fmt.Sprintf("%p", &pv)
98 addDumpTest(v, "("+vt+") "+vs+"\n")
99 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
100 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
101 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
107 v2Addr := fmt.Sprintf("%p", pv2)
108 pv2Addr := fmt.Sprintf("%p", &pv2)
111 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
112 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
113 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
114 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
117 v3 := int32(2147483647)
120 v3Addr := fmt.Sprintf("%p", pv3)
121 pv3Addr := fmt.Sprintf("%p", &pv3)
124 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
125 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
126 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
127 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
130 v4 := int64(9223372036854775807)
133 v4Addr := fmt.Sprintf("%p", pv4)
134 pv4Addr := fmt.Sprintf("%p", &pv4)
136 v4s := "9223372036854775807"
137 addDumpTest(v4, "("+v4t+") "+v4s+"\n")
138 addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
139 addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
140 addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
143 v5 := int(2147483647)
146 v5Addr := fmt.Sprintf("%p", pv5)
147 pv5Addr := fmt.Sprintf("%p", &pv5)
150 addDumpTest(v5, "("+v5t+") "+v5s+"\n")
151 addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
152 addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
153 addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
156 func addUintDumpTests() {
161 vAddr := fmt.Sprintf("%p", pv)
162 pvAddr := fmt.Sprintf("%p", &pv)
165 addDumpTest(v, "("+vt+") "+vs+"\n")
166 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
167 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
168 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
172 nv2 := (*uint16)(nil)
174 v2Addr := fmt.Sprintf("%p", pv2)
175 pv2Addr := fmt.Sprintf("%p", &pv2)
178 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
179 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
180 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
181 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
184 v3 := uint32(4294967295)
185 nv3 := (*uint32)(nil)
187 v3Addr := fmt.Sprintf("%p", pv3)
188 pv3Addr := fmt.Sprintf("%p", &pv3)
191 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
192 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
193 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
194 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
197 v4 := uint64(18446744073709551615)
198 nv4 := (*uint64)(nil)
200 v4Addr := fmt.Sprintf("%p", pv4)
201 pv4Addr := fmt.Sprintf("%p", &pv4)
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")
210 v5 := uint(4294967295)
213 v5Addr := fmt.Sprintf("%p", pv5)
214 pv5Addr := fmt.Sprintf("%p", &pv5)
217 addDumpTest(v5, "("+v5t+") "+v5s+"\n")
218 addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
219 addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
220 addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
223 func addBoolDumpTests() {
228 vAddr := fmt.Sprintf("%p", pv)
229 pvAddr := fmt.Sprintf("%p", &pv)
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")
240 v2Addr := fmt.Sprintf("%p", pv2)
241 pv2Addr := fmt.Sprintf("%p", &pv2)
244 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
245 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
246 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
249 func addFloatDumpTests() {
252 nv := (*float32)(nil)
254 vAddr := fmt.Sprintf("%p", pv)
255 pvAddr := fmt.Sprintf("%p", &pv)
258 addDumpTest(v, "("+vt+") "+vs+"\n")
259 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
260 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
261 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
264 v2 := float64(3.1415926)
265 nv2 := (*float64)(nil)
267 v2Addr := fmt.Sprintf("%p", pv2)
268 pv2Addr := fmt.Sprintf("%p", &pv2)
271 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
272 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
273 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
274 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
277 func addComplexDumpTests() {
278 // Standard complex64.
279 v := complex(float32(6), -2)
280 nv := (*complex64)(nil)
282 vAddr := fmt.Sprintf("%p", pv)
283 pvAddr := fmt.Sprintf("%p", &pv)
286 addDumpTest(v, "("+vt+") "+vs+"\n")
287 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
288 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
289 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
291 // Standard complex128.
292 v2 := complex(float64(-6), 2)
293 nv2 := (*complex128)(nil)
295 v2Addr := fmt.Sprintf("%p", pv2)
296 pv2Addr := fmt.Sprintf("%p", &pv2)
299 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
300 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
301 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
302 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
305 func addArrayDumpTests() {
306 // Array containing standard ints.
308 vLen := fmt.Sprintf("%d", len(v))
309 vCap := fmt.Sprintf("%d", cap(v))
312 vAddr := fmt.Sprintf("%p", pv)
313 pvAddr := fmt.Sprintf("%p", &pv)
315 vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 1,\n (" +
316 vt + ") 2,\n (" + vt + ") 3\n}"
317 addDumpTest(v, "([3]"+vt+") "+vs+"\n")
318 addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
319 addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
320 addDumpTest(nv, "(*[3]"+vt+")(<nil>)\n")
322 // Array containing type with custom formatter on pointer receiver only.
323 v2i0 := pstringer("1")
324 v2i1 := pstringer("2")
325 v2i2 := pstringer("3")
326 v2 := [3]pstringer{v2i0, v2i1, v2i2}
327 v2i0Len := fmt.Sprintf("%d", len(v2i0))
328 v2i1Len := fmt.Sprintf("%d", len(v2i1))
329 v2i2Len := fmt.Sprintf("%d", len(v2i2))
330 v2Len := fmt.Sprintf("%d", len(v2))
331 v2Cap := fmt.Sprintf("%d", cap(v2))
332 nv2 := (*[3]pstringer)(nil)
334 v2Addr := fmt.Sprintf("%p", pv2)
335 pv2Addr := fmt.Sprintf("%p", &pv2)
336 v2t := "spew_test.pstringer"
337 v2sp := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
338 ") (len=" + v2i0Len + ") stringer 1,\n (" + v2t +
339 ") (len=" + v2i1Len + ") stringer 2,\n (" + v2t +
340 ") (len=" + v2i2Len + ") " + "stringer 3\n}"
342 if spew.UnsafeDisabled {
343 v2s = "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
344 ") (len=" + v2i0Len + ") \"1\",\n (" + v2t + ") (len=" +
345 v2i1Len + ") \"2\",\n (" + v2t + ") (len=" + v2i2Len +
348 addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
349 addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2sp+")\n")
350 addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2sp+")\n")
351 addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
353 // Array containing interfaces.
355 v3 := [3]interface{}{v3i0, int(2), uint(3)}
356 v3i0Len := fmt.Sprintf("%d", len(v3i0))
357 v3Len := fmt.Sprintf("%d", len(v3))
358 v3Cap := fmt.Sprintf("%d", cap(v3))
359 nv3 := (*[3]interface{})(nil)
361 v3Addr := fmt.Sprintf("%p", pv3)
362 pv3Addr := fmt.Sprintf("%p", &pv3)
363 v3t := "[3]interface {}"
367 v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
368 "(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
370 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
371 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
372 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
373 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
375 // Array containing bytes.
377 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
378 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
379 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
380 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
383 v4Len := fmt.Sprintf("%d", len(v4))
384 v4Cap := fmt.Sprintf("%d", cap(v4))
385 nv4 := (*[34]byte)(nil)
387 v4Addr := fmt.Sprintf("%p", pv4)
388 pv4Addr := fmt.Sprintf("%p", &pv4)
390 v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
391 "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
392 " |............... |\n" +
393 " 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
394 " |!\"#$%&'()*+,-./0|\n" +
397 addDumpTest(v4, "("+v4t+") "+v4s+"\n")
398 addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
399 addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
400 addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
403 func addSliceDumpTests() {
404 // Slice containing standard float32 values.
405 v := []float32{3.14, 6.28, 12.56}
406 vLen := fmt.Sprintf("%d", len(v))
407 vCap := fmt.Sprintf("%d", cap(v))
408 nv := (*[]float32)(nil)
410 vAddr := fmt.Sprintf("%p", pv)
411 pvAddr := fmt.Sprintf("%p", &pv)
413 vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 3.14,\n (" +
414 vt + ") 6.28,\n (" + vt + ") 12.56\n}"
415 addDumpTest(v, "([]"+vt+") "+vs+"\n")
416 addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
417 addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
418 addDumpTest(nv, "(*[]"+vt+")(<nil>)\n")
420 // Slice containing type with custom formatter on pointer receiver only.
421 v2i0 := pstringer("1")
422 v2i1 := pstringer("2")
423 v2i2 := pstringer("3")
424 v2 := []pstringer{v2i0, v2i1, v2i2}
425 v2i0Len := fmt.Sprintf("%d", len(v2i0))
426 v2i1Len := fmt.Sprintf("%d", len(v2i1))
427 v2i2Len := fmt.Sprintf("%d", len(v2i2))
428 v2Len := fmt.Sprintf("%d", len(v2))
429 v2Cap := fmt.Sprintf("%d", cap(v2))
430 nv2 := (*[]pstringer)(nil)
432 v2Addr := fmt.Sprintf("%p", pv2)
433 pv2Addr := fmt.Sprintf("%p", &pv2)
434 v2t := "spew_test.pstringer"
435 v2s := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t + ") (len=" +
436 v2i0Len + ") stringer 1,\n (" + v2t + ") (len=" + v2i1Len +
437 ") stringer 2,\n (" + v2t + ") (len=" + v2i2Len + ") " +
439 addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
440 addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
441 addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
442 addDumpTest(nv2, "(*[]"+v2t+")(<nil>)\n")
444 // Slice containing interfaces.
446 v3 := []interface{}{v3i0, int(2), uint(3), nil}
447 v3i0Len := fmt.Sprintf("%d", len(v3i0))
448 v3Len := fmt.Sprintf("%d", len(v3))
449 v3Cap := fmt.Sprintf("%d", cap(v3))
450 nv3 := (*[]interface{})(nil)
452 v3Addr := fmt.Sprintf("%p", pv3)
453 pv3Addr := fmt.Sprintf("%p", &pv3)
454 v3t := "[]interface {}"
458 v3t5 := "interface {}"
459 v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
460 "(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
461 v3t4 + ") 3,\n (" + v3t5 + ") <nil>\n}"
462 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
463 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
464 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
465 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
467 // Slice containing bytes.
469 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
470 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
471 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
472 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
475 v4Len := fmt.Sprintf("%d", len(v4))
476 v4Cap := fmt.Sprintf("%d", cap(v4))
477 nv4 := (*[]byte)(nil)
479 v4Addr := fmt.Sprintf("%p", pv4)
480 pv4Addr := fmt.Sprintf("%p", &pv4)
482 v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
483 "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
484 " |............... |\n" +
485 " 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
486 " |!\"#$%&'()*+,-./0|\n" +
489 addDumpTest(v4, "("+v4t+") "+v4s+"\n")
490 addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
491 addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
492 addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
498 v5Addr := fmt.Sprintf("%p", pv5)
499 pv5Addr := fmt.Sprintf("%p", &pv5)
502 addDumpTest(v5, "("+v5t+") "+v5s+"\n")
503 addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
504 addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
505 addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
508 func addStringDumpTests() {
511 vLen := fmt.Sprintf("%d", len(v))
514 vAddr := fmt.Sprintf("%p", pv)
515 pvAddr := fmt.Sprintf("%p", &pv)
517 vs := "(len=" + vLen + ") \"test\""
518 addDumpTest(v, "("+vt+") "+vs+"\n")
519 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
520 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
521 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
524 func addInterfaceDumpTests() {
527 nv := (*interface{})(nil)
529 vAddr := fmt.Sprintf("%p", pv)
530 pvAddr := fmt.Sprintf("%p", &pv)
533 addDumpTest(v, "("+vt+") "+vs+"\n")
534 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
535 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
536 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
539 v2 := interface{}(uint16(65535))
541 v2Addr := fmt.Sprintf("%p", pv2)
542 pv2Addr := fmt.Sprintf("%p", &pv2)
545 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
546 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
547 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
550 func addMapDumpTests() {
551 // Map with string keys and int vals.
554 m := map[string]int{k: 1, kk: 2}
555 klen := fmt.Sprintf("%d", len(k)) // not kLen to shut golint up
556 kkLen := fmt.Sprintf("%d", len(kk))
557 mLen := fmt.Sprintf("%d", len(m))
558 nilMap := map[string]int(nil)
559 nm := (*map[string]int)(nil)
561 mAddr := fmt.Sprintf("%p", pm)
562 pmAddr := fmt.Sprintf("%p", &pm)
563 mt := "map[string]int"
566 ms := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + klen + ") " +
567 "\"one\": (" + mt2 + ") 1,\n (" + mt1 + ") (len=" + kkLen +
568 ") \"two\": (" + mt2 + ") 2\n}"
569 ms2 := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + kkLen + ") " +
570 "\"two\": (" + mt2 + ") 2,\n (" + mt1 + ") (len=" + klen +
571 ") \"one\": (" + mt2 + ") 1\n}"
572 addDumpTest(m, "("+mt+") "+ms+"\n", "("+mt+") "+ms2+"\n")
573 addDumpTest(pm, "(*"+mt+")("+mAddr+")("+ms+")\n",
574 "(*"+mt+")("+mAddr+")("+ms2+")\n")
575 addDumpTest(&pm, "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms+")\n",
576 "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms2+")\n")
577 addDumpTest(nm, "(*"+mt+")(<nil>)\n")
578 addDumpTest(nilMap, "("+mt+") <nil>\n")
580 // Map with custom formatter type on pointer receiver only keys and vals.
581 k2 := pstringer("one")
583 m2 := map[pstringer]pstringer{k2: v2}
584 k2Len := fmt.Sprintf("%d", len(k2))
585 v2Len := fmt.Sprintf("%d", len(v2))
586 m2Len := fmt.Sprintf("%d", len(m2))
587 nilMap2 := map[pstringer]pstringer(nil)
588 nm2 := (*map[pstringer]pstringer)(nil)
590 m2Addr := fmt.Sprintf("%p", pm2)
591 pm2Addr := fmt.Sprintf("%p", &pm2)
592 m2t := "map[spew_test.pstringer]spew_test.pstringer"
593 m2t1 := "spew_test.pstringer"
594 m2t2 := "spew_test.pstringer"
595 m2s := "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len + ") " +
596 "stringer one: (" + m2t2 + ") (len=" + v2Len + ") stringer 1\n}"
597 if spew.UnsafeDisabled {
598 m2s = "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len +
599 ") " + "\"one\": (" + m2t2 + ") (len=" + v2Len +
602 addDumpTest(m2, "("+m2t+") "+m2s+"\n")
603 addDumpTest(pm2, "(*"+m2t+")("+m2Addr+")("+m2s+")\n")
604 addDumpTest(&pm2, "(**"+m2t+")("+pm2Addr+"->"+m2Addr+")("+m2s+")\n")
605 addDumpTest(nm2, "(*"+m2t+")(<nil>)\n")
606 addDumpTest(nilMap2, "("+m2t+") <nil>\n")
608 // Map with interface keys and values.
610 k3Len := fmt.Sprintf("%d", len(k3))
611 m3 := map[interface{}]interface{}{k3: 1}
612 m3Len := fmt.Sprintf("%d", len(m3))
613 nilMap3 := map[interface{}]interface{}(nil)
614 nm3 := (*map[interface{}]interface{})(nil)
616 m3Addr := fmt.Sprintf("%p", pm3)
617 pm3Addr := fmt.Sprintf("%p", &pm3)
618 m3t := "map[interface {}]interface {}"
621 m3s := "(len=" + m3Len + ") {\n (" + m3t1 + ") (len=" + k3Len + ") " +
622 "\"one\": (" + m3t2 + ") 1\n}"
623 addDumpTest(m3, "("+m3t+") "+m3s+"\n")
624 addDumpTest(pm3, "(*"+m3t+")("+m3Addr+")("+m3s+")\n")
625 addDumpTest(&pm3, "(**"+m3t+")("+pm3Addr+"->"+m3Addr+")("+m3s+")\n")
626 addDumpTest(nm3, "(*"+m3t+")(<nil>)\n")
627 addDumpTest(nilMap3, "("+m3t+") <nil>\n")
629 // Map with nil interface value.
631 k4Len := fmt.Sprintf("%d", len(k4))
632 m4 := map[string]interface{}{k4: nil}
633 m4Len := fmt.Sprintf("%d", len(m4))
634 nilMap4 := map[string]interface{}(nil)
635 nm4 := (*map[string]interface{})(nil)
637 m4Addr := fmt.Sprintf("%p", pm4)
638 pm4Addr := fmt.Sprintf("%p", &pm4)
639 m4t := "map[string]interface {}"
641 m4t2 := "interface {}"
642 m4s := "(len=" + m4Len + ") {\n (" + m4t1 + ") (len=" + k4Len + ")" +
643 " \"nil\": (" + m4t2 + ") <nil>\n}"
644 addDumpTest(m4, "("+m4t+") "+m4s+"\n")
645 addDumpTest(pm4, "(*"+m4t+")("+m4Addr+")("+m4s+")\n")
646 addDumpTest(&pm4, "(**"+m4t+")("+pm4Addr+"->"+m4Addr+")("+m4s+")\n")
647 addDumpTest(nm4, "(*"+m4t+")(<nil>)\n")
648 addDumpTest(nilMap4, "("+m4t+") <nil>\n")
651 func addStructDumpTests() {
652 // Struct with primitives.
660 vAddr := fmt.Sprintf("%p", pv)
661 pvAddr := fmt.Sprintf("%p", &pv)
665 vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
666 addDumpTest(v, "("+vt+") "+vs+"\n")
667 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
668 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
669 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
671 // Struct that contains another struct.
676 v2 := s2{s1{127, 255}, true}
679 v2Addr := fmt.Sprintf("%p", pv2)
680 pv2Addr := fmt.Sprintf("%p", &pv2)
681 v2t := "spew_test.s2"
682 v2t2 := "spew_test.s1"
686 v2s := "{\n s1: (" + v2t2 + ") {\n a: (" + v2t3 + ") 127,\n b: (" +
687 v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
688 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
689 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
690 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
691 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
693 // Struct that contains custom type with Stringer pointer interface via both
694 // exported and unexported fields.
699 v3 := s3{"test", "test2"}
702 v3Addr := fmt.Sprintf("%p", pv3)
703 pv3Addr := fmt.Sprintf("%p", &pv3)
704 v3t := "spew_test.s3"
705 v3t2 := "spew_test.pstringer"
706 v3s := "{\n s: (" + v3t2 + ") (len=4) stringer test,\n S: (" + v3t2 +
707 ") (len=5) stringer test2\n}"
709 if spew.UnsafeDisabled {
710 v3s = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
711 v3t2 + ") (len=5) \"test2\"\n}"
712 v3sp = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
713 v3t2 + ") (len=5) stringer test2\n}"
715 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
716 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3sp+")\n")
717 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3sp+")\n")
718 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
720 // Struct that contains embedded struct and field to same struct.
721 e := embed{"embedstr"}
722 eLen := fmt.Sprintf("%d", len("embedstr"))
723 v4 := embedwrap{embed: &e, e: &e}
724 nv4 := (*embedwrap)(nil)
726 eAddr := fmt.Sprintf("%p", &e)
727 v4Addr := fmt.Sprintf("%p", pv4)
728 pv4Addr := fmt.Sprintf("%p", &pv4)
729 v4t := "spew_test.embedwrap"
730 v4t2 := "spew_test.embed"
732 v4s := "{\n embed: (*" + v4t2 + ")(" + eAddr + ")({\n a: (" + v4t3 +
733 ") (len=" + eLen + ") \"embedstr\"\n }),\n e: (*" + v4t2 +
734 ")(" + eAddr + ")({\n a: (" + v4t3 + ") (len=" + eLen + ")" +
735 " \"embedstr\"\n })\n}"
736 addDumpTest(v4, "("+v4t+") "+v4s+"\n")
737 addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
738 addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
739 addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
742 func addUintptrDumpTests() {
746 vAddr := fmt.Sprintf("%p", pv)
747 pvAddr := fmt.Sprintf("%p", &pv)
750 addDumpTest(v, "("+vt+") "+vs+"\n")
751 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
752 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
754 // Address of real variable.
756 v2 := uintptr(unsafe.Pointer(&i))
757 nv2 := (*uintptr)(nil)
759 v2Addr := fmt.Sprintf("%p", pv2)
760 pv2Addr := fmt.Sprintf("%p", &pv2)
762 v2s := fmt.Sprintf("%p", &i)
763 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
764 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
765 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
766 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
769 func addUnsafePointerDumpTests() {
771 v := unsafe.Pointer(uintptr(0))
772 nv := (*unsafe.Pointer)(nil)
774 vAddr := fmt.Sprintf("%p", pv)
775 pvAddr := fmt.Sprintf("%p", &pv)
776 vt := "unsafe.Pointer"
778 addDumpTest(v, "("+vt+") "+vs+"\n")
779 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
780 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
781 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
783 // Address of real variable.
785 v2 := unsafe.Pointer(&i)
787 v2Addr := fmt.Sprintf("%p", pv2)
788 pv2Addr := fmt.Sprintf("%p", &pv2)
789 v2t := "unsafe.Pointer"
790 v2s := fmt.Sprintf("%p", &i)
791 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
792 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
793 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
794 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
797 func addChanDumpTests() {
801 nv := (*chan int)(nil)
802 vAddr := fmt.Sprintf("%p", pv)
803 pvAddr := fmt.Sprintf("%p", &pv)
806 addDumpTest(v, "("+vt+") "+vs+"\n")
807 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
808 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
809 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
814 v2Addr := fmt.Sprintf("%p", pv2)
815 pv2Addr := fmt.Sprintf("%p", &pv2)
817 v2s := fmt.Sprintf("%p", v2)
818 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
819 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
820 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
823 func addFuncDumpTests() {
824 // Function with no params and no returns.
828 vAddr := fmt.Sprintf("%p", pv)
829 pvAddr := fmt.Sprintf("%p", &pv)
831 vs := fmt.Sprintf("%p", v)
832 addDumpTest(v, "("+vt+") "+vs+"\n")
833 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
834 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
835 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
837 // Function with param and no returns.
839 nv2 := (*func(*testing.T))(nil)
841 v2Addr := fmt.Sprintf("%p", pv2)
842 pv2Addr := fmt.Sprintf("%p", &pv2)
843 v2t := "func(*testing.T)"
844 v2s := fmt.Sprintf("%p", v2)
845 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
846 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
847 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
848 addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
850 // Function with multiple params and multiple returns.
851 var v3 = func(i int, s string) (b bool, err error) {
854 nv3 := (*func(int, string) (bool, error))(nil)
856 v3Addr := fmt.Sprintf("%p", pv3)
857 pv3Addr := fmt.Sprintf("%p", &pv3)
858 v3t := "func(int, string) (bool, error)"
859 v3s := fmt.Sprintf("%p", v3)
860 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
861 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
862 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
863 addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
866 func addCircularDumpTests() {
867 // Struct that is circular through self referencing.
868 type circular struct {
874 vAddr := fmt.Sprintf("%p", pv)
875 pvAddr := fmt.Sprintf("%p", &pv)
876 vt := "spew_test.circular"
877 vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n c: (*" + vt + ")(" +
878 vAddr + ")(<already shown>)\n })\n}"
879 vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
880 addDumpTest(v, "("+vt+") "+vs+"\n")
881 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
882 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
884 // Structs that are circular through cross referencing.
889 ts2Addr := fmt.Sprintf("%p", &ts2)
890 v2Addr := fmt.Sprintf("%p", pv2)
891 pv2Addr := fmt.Sprintf("%p", &pv2)
892 v2t := "spew_test.xref1"
893 v2t2 := "spew_test.xref2"
894 v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
895 ")(" + v2Addr + ")({\n ps2: (*" + v2t2 + ")(" + ts2Addr +
896 ")(<already shown>)\n })\n })\n}"
897 v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
898 ")(" + v2Addr + ")(<already shown>)\n })\n}"
899 addDumpTest(v2, "("+v2t+") "+v2s+"\n")
900 addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
901 addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
903 // Structs that are indirectly circular.
905 tic2 := indirCir2{nil}
906 tic3 := indirCir3{&v3}
910 tic2Addr := fmt.Sprintf("%p", &tic2)
911 tic3Addr := fmt.Sprintf("%p", &tic3)
912 v3Addr := fmt.Sprintf("%p", pv3)
913 pv3Addr := fmt.Sprintf("%p", &pv3)
914 v3t := "spew_test.indirCir1"
915 v3t2 := "spew_test.indirCir2"
916 v3t3 := "spew_test.indirCir3"
917 v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
918 ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
919 ")({\n ps2: (*" + v3t2 + ")(" + tic2Addr +
920 ")(<already shown>)\n })\n })\n })\n}"
921 v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
922 ")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
923 ")(<already shown>)\n })\n })\n}"
924 addDumpTest(v3, "("+v3t+") "+v3s+"\n")
925 addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
926 addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
929 func addPanicDumpTests() {
930 // Type that panics in its Stringer interface.
932 nv := (*panicer)(nil)
934 vAddr := fmt.Sprintf("%p", pv)
935 pvAddr := fmt.Sprintf("%p", &pv)
936 vt := "spew_test.panicer"
937 vs := "(PANIC=test panic)127"
938 addDumpTest(v, "("+vt+") "+vs+"\n")
939 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
940 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
941 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
944 func addErrorDumpTests() {
945 // Type that has a custom Error interface.
946 v := customError(127)
947 nv := (*customError)(nil)
949 vAddr := fmt.Sprintf("%p", pv)
950 pvAddr := fmt.Sprintf("%p", &pv)
951 vt := "spew_test.customError"
953 addDumpTest(v, "("+vt+") "+vs+"\n")
954 addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
955 addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
956 addDumpTest(nv, "(*"+vt+")(<nil>)\n")
959 // TestDump executes all of the tests described by dumpTests.
960 func TestDump(t *testing.T) {
966 addComplexDumpTests()
970 addInterfaceDumpTests()
973 addUintptrDumpTests()
974 addUnsafePointerDumpTests()
977 addCircularDumpTests()
982 t.Logf("Running %d tests", len(dumpTests))
983 for i, test := range dumpTests {
984 buf := new(bytes.Buffer)
985 spew.Fdump(buf, test.in)
987 if testFailed(s, test.wants) {
988 t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
994 func TestDumpSortedKeys(t *testing.T) {
995 cfg := spew.ConfigState{SortKeys: true}
996 s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"})
997 expected := "(map[int]string) (len=3) {\n(int) 1: (string) (len=1) " +
998 "\"1\",\n(int) 2: (string) (len=1) \"2\",\n(int) 3: (string) " +
1002 t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
1005 s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2})
1006 expected = "(map[spew_test.stringer]int) (len=3) {\n" +
1007 "(spew_test.stringer) (len=1) stringer 1: (int) 1,\n" +
1008 "(spew_test.stringer) (len=1) stringer 2: (int) 2,\n" +
1009 "(spew_test.stringer) (len=1) stringer 3: (int) 3\n" +
1012 t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
1015 s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
1016 expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
1017 "(spew_test.pstringer) (len=1) stringer 1: (int) 1,\n" +
1018 "(spew_test.pstringer) (len=1) stringer 2: (int) 2,\n" +
1019 "(spew_test.pstringer) (len=1) stringer 3: (int) 3\n" +
1021 if spew.UnsafeDisabled {
1022 expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
1023 "(spew_test.pstringer) (len=1) \"1\": (int) 1,\n" +
1024 "(spew_test.pstringer) (len=1) \"2\": (int) 2,\n" +
1025 "(spew_test.pstringer) (len=1) \"3\": (int) 3\n" +
1029 t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
1032 s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
1033 expected = "(map[spew_test.customError]int) (len=3) {\n" +
1034 "(spew_test.customError) error: 1: (int) 1,\n" +
1035 "(spew_test.customError) error: 2: (int) 2,\n" +
1036 "(spew_test.customError) error: 3: (int) 3\n" +
1039 t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)