1/*
2 * Copyright (c) 2013-2016 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/*
18Test Summary:
19NOTE: For each test, a nil pointer, a single pointer and double pointer to the
20base test element are also tested to ensure proper indirection across all types.
21
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
34- Nil slice
35- Standard string
36- Nil interface
37- Sub-interface
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
51- Nil channel
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
60*/
61
62package spew_test
63
64import (
65	"bytes"
66	"fmt"
67	"testing"
68	"unsafe"
69
70	"github.com/davecgh/go-spew/spew"
71)
72
73// dumpTest is used to describe a test to be performed against the Dump method.
74type dumpTest struct {
75	in    interface{}
76	wants []string
77}
78
79// dumpTests houses all of the tests to be performed against the Dump method.
80var dumpTests = make([]dumpTest, 0)
81
82// addDumpTest is a helper method to append the passed input and desired result
83// to dumpTests
84func addDumpTest(in interface{}, wants ...string) {
85	test := dumpTest{in, wants}
86	dumpTests = append(dumpTests, test)
87}
88
89func addIntDumpTests() {
90	// Max int8.
91	v := int8(127)
92	nv := (*int8)(nil)
93	pv := &v
94	vAddr := fmt.Sprintf("%p", pv)
95	pvAddr := fmt.Sprintf("%p", &pv)
96	vt := "int8"
97	vs := "127"
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")
102
103	// Max int16.
104	v2 := int16(32767)
105	nv2 := (*int16)(nil)
106	pv2 := &v2
107	v2Addr := fmt.Sprintf("%p", pv2)
108	pv2Addr := fmt.Sprintf("%p", &pv2)
109	v2t := "int16"
110	v2s := "32767"
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")
115
116	// Max int32.
117	v3 := int32(2147483647)
118	nv3 := (*int32)(nil)
119	pv3 := &v3
120	v3Addr := fmt.Sprintf("%p", pv3)
121	pv3Addr := fmt.Sprintf("%p", &pv3)
122	v3t := "int32"
123	v3s := "2147483647"
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")
128
129	// Max int64.
130	v4 := int64(9223372036854775807)
131	nv4 := (*int64)(nil)
132	pv4 := &v4
133	v4Addr := fmt.Sprintf("%p", pv4)
134	pv4Addr := fmt.Sprintf("%p", &pv4)
135	v4t := "int64"
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")
141
142	// Max int.
143	v5 := int(2147483647)
144	nv5 := (*int)(nil)
145	pv5 := &v5
146	v5Addr := fmt.Sprintf("%p", pv5)
147	pv5Addr := fmt.Sprintf("%p", &pv5)
148	v5t := "int"
149	v5s := "2147483647"
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")
154}
155
156func addUintDumpTests() {
157	// Max uint8.
158	v := uint8(255)
159	nv := (*uint8)(nil)
160	pv := &v
161	vAddr := fmt.Sprintf("%p", pv)
162	pvAddr := fmt.Sprintf("%p", &pv)
163	vt := "uint8"
164	vs := "255"
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")
169
170	// Max uint16.
171	v2 := uint16(65535)
172	nv2 := (*uint16)(nil)
173	pv2 := &v2
174	v2Addr := fmt.Sprintf("%p", pv2)
175	pv2Addr := fmt.Sprintf("%p", &pv2)
176	v2t := "uint16"
177	v2s := "65535"
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")
182
183	// Max uint32.
184	v3 := uint32(4294967295)
185	nv3 := (*uint32)(nil)
186	pv3 := &v3
187	v3Addr := fmt.Sprintf("%p", pv3)
188	pv3Addr := fmt.Sprintf("%p", &pv3)
189	v3t := "uint32"
190	v3s := "4294967295"
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")
195
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
209	// Max uint.
210	v5 := uint(4294967295)
211	nv5 := (*uint)(nil)
212	pv5 := &v5
213	v5Addr := fmt.Sprintf("%p", pv5)
214	pv5Addr := fmt.Sprintf("%p", &pv5)
215	v5t := "uint"
216	v5s := "4294967295"
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")
221}
222
223func addBoolDumpTests() {
224	// Boolean true.
225	v := bool(true)
226	nv := (*bool)(nil)
227	pv := &v
228	vAddr := fmt.Sprintf("%p", pv)
229	pvAddr := fmt.Sprintf("%p", &pv)
230	vt := "bool"
231	vs := "true"
232	addDumpTest(v, "("+vt+") "+vs+"\n")
233	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
234	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
235	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
236
237	// Boolean false.
238	v2 := bool(false)
239	pv2 := &v2
240	v2Addr := fmt.Sprintf("%p", pv2)
241	pv2Addr := fmt.Sprintf("%p", &pv2)
242	v2t := "bool"
243	v2s := "false"
244	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
245	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
246	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
247}
248
249func addFloatDumpTests() {
250	// Standard float32.
251	v := float32(3.1415)
252	nv := (*float32)(nil)
253	pv := &v
254	vAddr := fmt.Sprintf("%p", pv)
255	pvAddr := fmt.Sprintf("%p", &pv)
256	vt := "float32"
257	vs := "3.1415"
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")
262
263	// Standard float64.
264	v2 := float64(3.1415926)
265	nv2 := (*float64)(nil)
266	pv2 := &v2
267	v2Addr := fmt.Sprintf("%p", pv2)
268	pv2Addr := fmt.Sprintf("%p", &pv2)
269	v2t := "float64"
270	v2s := "3.1415926"
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")
275}
276
277func addComplexDumpTests() {
278	// Standard complex64.
279	v := complex(float32(6), -2)
280	nv := (*complex64)(nil)
281	pv := &v
282	vAddr := fmt.Sprintf("%p", pv)
283	pvAddr := fmt.Sprintf("%p", &pv)
284	vt := "complex64"
285	vs := "(6-2i)"
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")
290
291	// Standard complex128.
292	v2 := complex(float64(-6), 2)
293	nv2 := (*complex128)(nil)
294	pv2 := &v2
295	v2Addr := fmt.Sprintf("%p", pv2)
296	pv2Addr := fmt.Sprintf("%p", &pv2)
297	v2t := "complex128"
298	v2s := "(-6+2i)"
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")
303}
304
305func addArrayDumpTests() {
306	// Array containing standard ints.
307	v := [3]int{1, 2, 3}
308	vLen := fmt.Sprintf("%d", len(v))
309	vCap := fmt.Sprintf("%d", cap(v))
310	nv := (*[3]int)(nil)
311	pv := &v
312	vAddr := fmt.Sprintf("%p", pv)
313	pvAddr := fmt.Sprintf("%p", &pv)
314	vt := "int"
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")
321
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)
333	pv2 := &v2
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}"
341	v2s := v2sp
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 +
346			") " + "\"3\"\n}"
347	}
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")
352
353	// Array containing interfaces.
354	v3i0 := "one"
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)
360	pv3 := &v3
361	v3Addr := fmt.Sprintf("%p", pv3)
362	pv3Addr := fmt.Sprintf("%p", &pv3)
363	v3t := "[3]interface {}"
364	v3t2 := "string"
365	v3t3 := "int"
366	v3t4 := "uint"
367	v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
368		"(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
369		v3t4 + ") 3\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")
374
375	// Array containing bytes.
376	v4 := [34]byte{
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,
381		0x31, 0x32,
382	}
383	v4Len := fmt.Sprintf("%d", len(v4))
384	v4Cap := fmt.Sprintf("%d", cap(v4))
385	nv4 := (*[34]byte)(nil)
386	pv4 := &v4
387	v4Addr := fmt.Sprintf("%p", pv4)
388	pv4Addr := fmt.Sprintf("%p", &pv4)
389	v4t := "[34]uint8"
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" +
395		" 00000020  31 32                                           " +
396		"  |12|\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")
401}
402
403func 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)
409	pv := &v
410	vAddr := fmt.Sprintf("%p", pv)
411	pvAddr := fmt.Sprintf("%p", &pv)
412	vt := "float32"
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")
419
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)
431	pv2 := &v2
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 + ") " +
438		"stringer 3\n}"
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")
443
444	// Slice containing interfaces.
445	v3i0 := "one"
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)
451	pv3 := &v3
452	v3Addr := fmt.Sprintf("%p", pv3)
453	pv3Addr := fmt.Sprintf("%p", &pv3)
454	v3t := "[]interface {}"
455	v3t2 := "string"
456	v3t3 := "int"
457	v3t4 := "uint"
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")
466
467	// Slice containing bytes.
468	v4 := []byte{
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,
473		0x31, 0x32,
474	}
475	v4Len := fmt.Sprintf("%d", len(v4))
476	v4Cap := fmt.Sprintf("%d", cap(v4))
477	nv4 := (*[]byte)(nil)
478	pv4 := &v4
479	v4Addr := fmt.Sprintf("%p", pv4)
480	pv4Addr := fmt.Sprintf("%p", &pv4)
481	v4t := "[]uint8"
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" +
487		" 00000020  31 32                                           " +
488		"  |12|\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")
493
494	// Nil slice.
495	v5 := []int(nil)
496	nv5 := (*[]int)(nil)
497	pv5 := &v5
498	v5Addr := fmt.Sprintf("%p", pv5)
499	pv5Addr := fmt.Sprintf("%p", &pv5)
500	v5t := "[]int"
501	v5s := "<nil>"
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")
506}
507
508func addStringDumpTests() {
509	// Standard string.
510	v := "test"
511	vLen := fmt.Sprintf("%d", len(v))
512	nv := (*string)(nil)
513	pv := &v
514	vAddr := fmt.Sprintf("%p", pv)
515	pvAddr := fmt.Sprintf("%p", &pv)
516	vt := "string"
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")
522}
523
524func addInterfaceDumpTests() {
525	// Nil interface.
526	var v interface{}
527	nv := (*interface{})(nil)
528	pv := &v
529	vAddr := fmt.Sprintf("%p", pv)
530	pvAddr := fmt.Sprintf("%p", &pv)
531	vt := "interface {}"
532	vs := "<nil>"
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")
537
538	// Sub-interface.
539	v2 := interface{}(uint16(65535))
540	pv2 := &v2
541	v2Addr := fmt.Sprintf("%p", pv2)
542	pv2Addr := fmt.Sprintf("%p", &pv2)
543	v2t := "uint16"
544	v2s := "65535"
545	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
546	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
547	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
548}
549
550func addMapDumpTests() {
551	// Map with string keys and int vals.
552	k := "one"
553	kk := "two"
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)
560	pm := &m
561	mAddr := fmt.Sprintf("%p", pm)
562	pmAddr := fmt.Sprintf("%p", &pm)
563	mt := "map[string]int"
564	mt1 := "string"
565	mt2 := "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")
579
580	// Map with custom formatter type on pointer receiver only keys and vals.
581	k2 := pstringer("one")
582	v2 := pstringer("1")
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)
589	pm2 := &m2
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 +
600			") \"1\"\n}"
601	}
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")
607
608	// Map with interface keys and values.
609	k3 := "one"
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)
615	pm3 := &m3
616	m3Addr := fmt.Sprintf("%p", pm3)
617	pm3Addr := fmt.Sprintf("%p", &pm3)
618	m3t := "map[interface {}]interface {}"
619	m3t1 := "string"
620	m3t2 := "int"
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")
628
629	// Map with nil interface value.
630	k4 := "nil"
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)
636	pm4 := &m4
637	m4Addr := fmt.Sprintf("%p", pm4)
638	pm4Addr := fmt.Sprintf("%p", &pm4)
639	m4t := "map[string]interface {}"
640	m4t1 := "string"
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")
649}
650
651func addStructDumpTests() {
652	// Struct with primitives.
653	type s1 struct {
654		a int8
655		b uint8
656	}
657	v := s1{127, 255}
658	nv := (*s1)(nil)
659	pv := &v
660	vAddr := fmt.Sprintf("%p", pv)
661	pvAddr := fmt.Sprintf("%p", &pv)
662	vt := "spew_test.s1"
663	vt2 := "int8"
664	vt3 := "uint8"
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")
670
671	// Struct that contains another struct.
672	type s2 struct {
673		s1 s1
674		b  bool
675	}
676	v2 := s2{s1{127, 255}, true}
677	nv2 := (*s2)(nil)
678	pv2 := &v2
679	v2Addr := fmt.Sprintf("%p", pv2)
680	pv2Addr := fmt.Sprintf("%p", &pv2)
681	v2t := "spew_test.s2"
682	v2t2 := "spew_test.s1"
683	v2t3 := "int8"
684	v2t4 := "uint8"
685	v2t5 := "bool"
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")
692
693	// Struct that contains custom type with Stringer pointer interface via both
694	// exported and unexported fields.
695	type s3 struct {
696		s pstringer
697		S pstringer
698	}
699	v3 := s3{"test", "test2"}
700	nv3 := (*s3)(nil)
701	pv3 := &v3
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}"
708	v3sp := v3s
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}"
714	}
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")
719
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)
725	pv4 := &v4
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"
731	v4t3 := "string"
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")
740}
741
742func addUintptrDumpTests() {
743	// Null pointer.
744	v := uintptr(0)
745	pv := &v
746	vAddr := fmt.Sprintf("%p", pv)
747	pvAddr := fmt.Sprintf("%p", &pv)
748	vt := "uintptr"
749	vs := "<nil>"
750	addDumpTest(v, "("+vt+") "+vs+"\n")
751	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
752	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
753
754	// Address of real variable.
755	i := 1
756	v2 := uintptr(unsafe.Pointer(&i))
757	nv2 := (*uintptr)(nil)
758	pv2 := &v2
759	v2Addr := fmt.Sprintf("%p", pv2)
760	pv2Addr := fmt.Sprintf("%p", &pv2)
761	v2t := "uintptr"
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")
767}
768
769func addUnsafePointerDumpTests() {
770	// Null pointer.
771	v := unsafe.Pointer(nil)
772	nv := (*unsafe.Pointer)(nil)
773	pv := &v
774	vAddr := fmt.Sprintf("%p", pv)
775	pvAddr := fmt.Sprintf("%p", &pv)
776	vt := "unsafe.Pointer"
777	vs := "<nil>"
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")
782
783	// Address of real variable.
784	i := 1
785	v2 := unsafe.Pointer(&i)
786	pv2 := &v2
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")
795}
796
797func addChanDumpTests() {
798	// Nil channel.
799	var v chan int
800	pv := &v
801	nv := (*chan int)(nil)
802	vAddr := fmt.Sprintf("%p", pv)
803	pvAddr := fmt.Sprintf("%p", &pv)
804	vt := "chan int"
805	vs := "<nil>"
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")
810
811	// Real channel.
812	v2 := make(chan int)
813	pv2 := &v2
814	v2Addr := fmt.Sprintf("%p", pv2)
815	pv2Addr := fmt.Sprintf("%p", &pv2)
816	v2t := "chan int"
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")
821}
822
823func addFuncDumpTests() {
824	// Function with no params and no returns.
825	v := addIntDumpTests
826	nv := (*func())(nil)
827	pv := &v
828	vAddr := fmt.Sprintf("%p", pv)
829	pvAddr := fmt.Sprintf("%p", &pv)
830	vt := "func()"
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")
836
837	// Function with param and no returns.
838	v2 := TestDump
839	nv2 := (*func(*testing.T))(nil)
840	pv2 := &v2
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")
849
850	// Function with multiple params and multiple returns.
851	var v3 = func(i int, s string) (b bool, err error) {
852		return true, nil
853	}
854	nv3 := (*func(int, string) (bool, error))(nil)
855	pv3 := &v3
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")
864}
865
866func addCircularDumpTests() {
867	// Struct that is circular through self referencing.
868	type circular struct {
869		c *circular
870	}
871	v := circular{nil}
872	v.c = &v
873	pv := &v
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")
883
884	// Structs that are circular through cross referencing.
885	v2 := xref1{nil}
886	ts2 := xref2{&v2}
887	v2.ps2 = &ts2
888	pv2 := &v2
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")
902
903	// Structs that are indirectly circular.
904	v3 := indirCir1{nil}
905	tic2 := indirCir2{nil}
906	tic3 := indirCir3{&v3}
907	tic2.ps3 = &tic3
908	v3.ps2 = &tic2
909	pv3 := &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")
927}
928
929func addPanicDumpTests() {
930	// Type that panics in its Stringer interface.
931	v := panicer(127)
932	nv := (*panicer)(nil)
933	pv := &v
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")
942}
943
944func addErrorDumpTests() {
945	// Type that has a custom Error interface.
946	v := customError(127)
947	nv := (*customError)(nil)
948	pv := &v
949	vAddr := fmt.Sprintf("%p", pv)
950	pvAddr := fmt.Sprintf("%p", &pv)
951	vt := "spew_test.customError"
952	vs := "error: 127"
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")
957}
958
959// TestDump executes all of the tests described by dumpTests.
960func TestDump(t *testing.T) {
961	// Setup tests.
962	addIntDumpTests()
963	addUintDumpTests()
964	addBoolDumpTests()
965	addFloatDumpTests()
966	addComplexDumpTests()
967	addArrayDumpTests()
968	addSliceDumpTests()
969	addStringDumpTests()
970	addInterfaceDumpTests()
971	addMapDumpTests()
972	addStructDumpTests()
973	addUintptrDumpTests()
974	addUnsafePointerDumpTests()
975	addChanDumpTests()
976	addFuncDumpTests()
977	addCircularDumpTests()
978	addPanicDumpTests()
979	addErrorDumpTests()
980	addCgoDumpTests()
981
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)
986		s := buf.String()
987		if testFailed(s, test.wants) {
988			t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
989			continue
990		}
991	}
992}
993
994func 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) " +
999		"(len=1) \"3\"\n" +
1000		"}\n"
1001	if s != expected {
1002		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
1003	}
1004
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" +
1010		"}\n"
1011	if s != expected {
1012		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
1013	}
1014
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" +
1020		"}\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" +
1026			"}\n"
1027	}
1028	if s != expected {
1029		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
1030	}
1031
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" +
1037		"}\n"
1038	if s != expected {
1039		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
1040	}
1041
1042}
1043