OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / davecgh / go-spew / spew / spew_test.go
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 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 // spewFunc is used to identify which public function of the spew package or
30 // ConfigState a test applies to.
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 // Map of spewFunc values to names for pretty printing.
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 // spewTest is used to describe a test to be performed against the public
90 // functions of the spew package or ConfigState.
91 type spewTest struct {
92         cs     *spew.ConfigState
93         f      spewFunc
94         format string
95         in     interface{}
96         want   string
97 }
98
99 // spewTests houses the tests to be performed against the public functions of
100 // the spew package and ConfigState.
101 //
102 // These tests are only intended to ensure the public functions are exercised
103 // and are intentionally not exhaustive of types.  The exhaustive type
104 // tests are handled in the dump and format tests.
105 var spewTests []spewTest
106
107 // redirStdout is a helper function to return the standard output from f as a
108 // byte slice.
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) // Ignore error
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         // Config states with various settings.
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         // Variables for tests on types which implement Stringer interface with and
137         // without a pointer receiver.
138         ts := stringer("test")
139         tps := pstringer("test")
140
141         type ptrTester struct {
142                 s *struct{}
143         }
144         tptr := &ptrTester{s: &struct{}{}}
145
146         // depthTester is used to test max depth handling for structs, array, slices
147         // and maps.
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         // Variable for tests on types which implement error interface.
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 // TestSpew executes all of the tests described by spewTests.
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 }