1
16
17 package spew_test
18
19 import (
20 "bytes"
21 "fmt"
22 "io/ioutil"
23 "os"
24 "testing"
25
26 "github.com/davecgh/go-spew/spew"
27 )
28
29
30
31 type spewFunc int
32
33 const (
34 fCSFdump spewFunc = iota
35 fCSFprint
36 fCSFprintf
37 fCSFprintln
38 fCSPrint
39 fCSPrintln
40 fCSSdump
41 fCSSprint
42 fCSSprintf
43 fCSSprintln
44 fCSErrorf
45 fCSNewFormatter
46 fErrorf
47 fFprint
48 fFprintln
49 fPrint
50 fPrintln
51 fSdump
52 fSprint
53 fSprintf
54 fSprintln
55 )
56
57
58 var spewFuncStrings = map[spewFunc]string{
59 fCSFdump: "ConfigState.Fdump",
60 fCSFprint: "ConfigState.Fprint",
61 fCSFprintf: "ConfigState.Fprintf",
62 fCSFprintln: "ConfigState.Fprintln",
63 fCSSdump: "ConfigState.Sdump",
64 fCSPrint: "ConfigState.Print",
65 fCSPrintln: "ConfigState.Println",
66 fCSSprint: "ConfigState.Sprint",
67 fCSSprintf: "ConfigState.Sprintf",
68 fCSSprintln: "ConfigState.Sprintln",
69 fCSErrorf: "ConfigState.Errorf",
70 fCSNewFormatter: "ConfigState.NewFormatter",
71 fErrorf: "spew.Errorf",
72 fFprint: "spew.Fprint",
73 fFprintln: "spew.Fprintln",
74 fPrint: "spew.Print",
75 fPrintln: "spew.Println",
76 fSdump: "spew.Sdump",
77 fSprint: "spew.Sprint",
78 fSprintf: "spew.Sprintf",
79 fSprintln: "spew.Sprintln",
80 }
81
82 func (f spewFunc) String() string {
83 if s, ok := spewFuncStrings[f]; ok {
84 return s
85 }
86 return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
87 }
88
89
90
91 type spewTest struct {
92 cs *spew.ConfigState
93 f spewFunc
94 format string
95 in interface{}
96 want string
97 }
98
99
100
101
102
103
104
105 var spewTests []spewTest
106
107
108
109 func redirStdout(f func()) ([]byte, error) {
110 tempFile, err := ioutil.TempFile("", "ss-test")
111 if err != nil {
112 return nil, err
113 }
114 fileName := tempFile.Name()
115 defer os.Remove(fileName)
116
117 origStdout := os.Stdout
118 os.Stdout = tempFile
119 f()
120 os.Stdout = origStdout
121 tempFile.Close()
122
123 return ioutil.ReadFile(fileName)
124 }
125
126 func initSpewTests() {
127
128 scsDefault := spew.NewDefaultConfig()
129 scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true}
130 scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true}
131 scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1}
132 scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true}
133 scsNoPtrAddr := &spew.ConfigState{DisablePointerAddresses: true}
134 scsNoCap := &spew.ConfigState{DisableCapacities: true}
135
136
137
138 ts := stringer("test")
139 tps := pstringer("test")
140
141 type ptrTester struct {
142 s *struct{}
143 }
144 tptr := &ptrTester{s: &struct{}{}}
145
146
147
148 type depthTester struct {
149 ic indirCir1
150 arr [1]string
151 slice []string
152 m map[string]int
153 }
154 dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"},
155 map[string]int{"one": 1}}
156
157
158 te := customError(10)
159
160 spewTests = []spewTest{
161 {scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
162 {scsDefault, fCSFprint, "", int16(32767), "32767"},
163 {scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
164 {scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
165 {scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
166 {scsDefault, fCSPrintln, "", uint8(255), "255\n"},
167 {scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"},
168 {scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"},
169 {scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"},
170 {scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"},
171 {scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
172 {scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
173 {scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
174 {scsDefault, fFprint, "", float32(3.14), "3.14"},
175 {scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
176 {scsDefault, fPrint, "", true, "true"},
177 {scsDefault, fPrintln, "", false, "false\n"},
178 {scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"},
179 {scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"},
180 {scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"},
181 {scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"},
182 {scsNoMethods, fCSFprint, "", ts, "test"},
183 {scsNoMethods, fCSFprint, "", &ts, "<*>test"},
184 {scsNoMethods, fCSFprint, "", tps, "test"},
185 {scsNoMethods, fCSFprint, "", &tps, "<*>test"},
186 {scsNoPmethods, fCSFprint, "", ts, "stringer test"},
187 {scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
188 {scsNoPmethods, fCSFprint, "", tps, "test"},
189 {scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
190 {scsMaxDepth, fCSFprint, "", dt, "{{<max>} [<max>] [<max>] map[<max>]}"},
191 {scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" +
192 " ic: (spew_test.indirCir1) {\n <max depth reached>\n },\n" +
193 " arr: ([1]string) (len=1 cap=1) {\n <max depth reached>\n },\n" +
194 " slice: ([]string) (len=1 cap=1) {\n <max depth reached>\n },\n" +
195 " m: (map[string]int) (len=1) {\n <max depth reached>\n }\n}\n"},
196 {scsContinue, fCSFprint, "", ts, "(stringer test) test"},
197 {scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
198 "(len=4) (stringer test) \"test\"\n"},
199 {scsContinue, fCSFprint, "", te, "(error: 10) 10"},
200 {scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
201 "(error: 10) 10\n"},
202 {scsNoPtrAddr, fCSFprint, "", tptr, "<*>{<*>{}}"},
203 {scsNoPtrAddr, fCSSdump, "", tptr, "(*spew_test.ptrTester)({\ns: (*struct {})({\n})\n})\n"},
204 {scsNoCap, fCSSdump, "", make([]string, 0, 10), "([]string) {\n}\n"},
205 {scsNoCap, fCSSdump, "", make([]string, 1, 10), "([]string) (len=1) {\n(string) \"\"\n}\n"},
206 }
207 }
208
209
210 func TestSpew(t *testing.T) {
211 initSpewTests()
212
213 t.Logf("Running %d tests", len(spewTests))
214 for i, test := range spewTests {
215 buf := new(bytes.Buffer)
216 switch test.f {
217 case fCSFdump:
218 test.cs.Fdump(buf, test.in)
219
220 case fCSFprint:
221 test.cs.Fprint(buf, test.in)
222
223 case fCSFprintf:
224 test.cs.Fprintf(buf, test.format, test.in)
225
226 case fCSFprintln:
227 test.cs.Fprintln(buf, test.in)
228
229 case fCSPrint:
230 b, err := redirStdout(func() { test.cs.Print(test.in) })
231 if err != nil {
232 t.Errorf("%v #%d %v", test.f, i, err)
233 continue
234 }
235 buf.Write(b)
236
237 case fCSPrintln:
238 b, err := redirStdout(func() { test.cs.Println(test.in) })
239 if err != nil {
240 t.Errorf("%v #%d %v", test.f, i, err)
241 continue
242 }
243 buf.Write(b)
244
245 case fCSSdump:
246 str := test.cs.Sdump(test.in)
247 buf.WriteString(str)
248
249 case fCSSprint:
250 str := test.cs.Sprint(test.in)
251 buf.WriteString(str)
252
253 case fCSSprintf:
254 str := test.cs.Sprintf(test.format, test.in)
255 buf.WriteString(str)
256
257 case fCSSprintln:
258 str := test.cs.Sprintln(test.in)
259 buf.WriteString(str)
260
261 case fCSErrorf:
262 err := test.cs.Errorf(test.format, test.in)
263 buf.WriteString(err.Error())
264
265 case fCSNewFormatter:
266 fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))
267
268 case fErrorf:
269 err := spew.Errorf(test.format, test.in)
270 buf.WriteString(err.Error())
271
272 case fFprint:
273 spew.Fprint(buf, test.in)
274
275 case fFprintln:
276 spew.Fprintln(buf, test.in)
277
278 case fPrint:
279 b, err := redirStdout(func() { spew.Print(test.in) })
280 if err != nil {
281 t.Errorf("%v #%d %v", test.f, i, err)
282 continue
283 }
284 buf.Write(b)
285
286 case fPrintln:
287 b, err := redirStdout(func() { spew.Println(test.in) })
288 if err != nil {
289 t.Errorf("%v #%d %v", test.f, i, err)
290 continue
291 }
292 buf.Write(b)
293
294 case fSdump:
295 str := spew.Sdump(test.in)
296 buf.WriteString(str)
297
298 case fSprint:
299 str := spew.Sprint(test.in)
300 buf.WriteString(str)
301
302 case fSprintf:
303 str := spew.Sprintf(test.format, test.in)
304 buf.WriteString(str)
305
306 case fSprintln:
307 str := spew.Sprintln(test.in)
308 buf.WriteString(str)
309
310 default:
311 t.Errorf("%v #%d unrecognized function", test.f, i)
312 continue
313 }
314 s := buf.String()
315 if test.want != s {
316 t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
317 continue
318 }
319 }
320 }
321
View as plain text