Imported Upstream version 2.5.0
[scm/test.git] / vendor / github.com / git-lfs / gitobj / vendor / github.com / davecgh / go-spew / spew / spew_test.go
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 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
134         // Variables for tests on types which implement Stringer interface with and
135         // without a pointer receiver.
136         ts := stringer("test")
137         tps := pstringer("test")
138
139         // depthTester is used to test max depth handling for structs, array, slices
140         // and maps.
141         type depthTester struct {
142                 ic    indirCir1
143                 arr   [1]string
144                 slice []string
145                 m     map[string]int
146         }
147         dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"},
148                 map[string]int{"one": 1}}
149
150         // Variable for tests on types which implement error interface.
151         te := customError(10)
152
153         spewTests = []spewTest{
154                 {scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
155                 {scsDefault, fCSFprint, "", int16(32767), "32767"},
156                 {scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
157                 {scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
158                 {scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
159                 {scsDefault, fCSPrintln, "", uint8(255), "255\n"},
160                 {scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"},
161                 {scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"},
162                 {scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"},
163                 {scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"},
164                 {scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
165                 {scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
166                 {scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
167                 {scsDefault, fFprint, "", float32(3.14), "3.14"},
168                 {scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
169                 {scsDefault, fPrint, "", true, "true"},
170                 {scsDefault, fPrintln, "", false, "false\n"},
171                 {scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"},
172                 {scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"},
173                 {scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"},
174                 {scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"},
175                 {scsNoMethods, fCSFprint, "", ts, "test"},
176                 {scsNoMethods, fCSFprint, "", &ts, "<*>test"},
177                 {scsNoMethods, fCSFprint, "", tps, "test"},
178                 {scsNoMethods, fCSFprint, "", &tps, "<*>test"},
179                 {scsNoPmethods, fCSFprint, "", ts, "stringer test"},
180                 {scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
181                 {scsNoPmethods, fCSFprint, "", tps, "test"},
182                 {scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
183                 {scsMaxDepth, fCSFprint, "", dt, "{{<max>} [<max>] [<max>] map[<max>]}"},
184                 {scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" +
185                         " ic: (spew_test.indirCir1) {\n  <max depth reached>\n },\n" +
186                         " arr: ([1]string) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
187                         " slice: ([]string) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
188                         " m: (map[string]int) (len=1) {\n  <max depth reached>\n }\n}\n"},
189                 {scsContinue, fCSFprint, "", ts, "(stringer test) test"},
190                 {scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
191                         "(len=4) (stringer test) \"test\"\n"},
192                 {scsContinue, fCSFprint, "", te, "(error: 10) 10"},
193                 {scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
194                         "(error: 10) 10\n"},
195         }
196 }
197
198 // TestSpew executes all of the tests described by spewTests.
199 func TestSpew(t *testing.T) {
200         initSpewTests()
201
202         t.Logf("Running %d tests", len(spewTests))
203         for i, test := range spewTests {
204                 buf := new(bytes.Buffer)
205                 switch test.f {
206                 case fCSFdump:
207                         test.cs.Fdump(buf, test.in)
208
209                 case fCSFprint:
210                         test.cs.Fprint(buf, test.in)
211
212                 case fCSFprintf:
213                         test.cs.Fprintf(buf, test.format, test.in)
214
215                 case fCSFprintln:
216                         test.cs.Fprintln(buf, test.in)
217
218                 case fCSPrint:
219                         b, err := redirStdout(func() { test.cs.Print(test.in) })
220                         if err != nil {
221                                 t.Errorf("%v #%d %v", test.f, i, err)
222                                 continue
223                         }
224                         buf.Write(b)
225
226                 case fCSPrintln:
227                         b, err := redirStdout(func() { test.cs.Println(test.in) })
228                         if err != nil {
229                                 t.Errorf("%v #%d %v", test.f, i, err)
230                                 continue
231                         }
232                         buf.Write(b)
233
234                 case fCSSdump:
235                         str := test.cs.Sdump(test.in)
236                         buf.WriteString(str)
237
238                 case fCSSprint:
239                         str := test.cs.Sprint(test.in)
240                         buf.WriteString(str)
241
242                 case fCSSprintf:
243                         str := test.cs.Sprintf(test.format, test.in)
244                         buf.WriteString(str)
245
246                 case fCSSprintln:
247                         str := test.cs.Sprintln(test.in)
248                         buf.WriteString(str)
249
250                 case fCSErrorf:
251                         err := test.cs.Errorf(test.format, test.in)
252                         buf.WriteString(err.Error())
253
254                 case fCSNewFormatter:
255                         fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))
256
257                 case fErrorf:
258                         err := spew.Errorf(test.format, test.in)
259                         buf.WriteString(err.Error())
260
261                 case fFprint:
262                         spew.Fprint(buf, test.in)
263
264                 case fFprintln:
265                         spew.Fprintln(buf, test.in)
266
267                 case fPrint:
268                         b, err := redirStdout(func() { spew.Print(test.in) })
269                         if err != nil {
270                                 t.Errorf("%v #%d %v", test.f, i, err)
271                                 continue
272                         }
273                         buf.Write(b)
274
275                 case fPrintln:
276                         b, err := redirStdout(func() { spew.Println(test.in) })
277                         if err != nil {
278                                 t.Errorf("%v #%d %v", test.f, i, err)
279                                 continue
280                         }
281                         buf.Write(b)
282
283                 case fSdump:
284                         str := spew.Sdump(test.in)
285                         buf.WriteString(str)
286
287                 case fSprint:
288                         str := spew.Sprint(test.in)
289                         buf.WriteString(str)
290
291                 case fSprintf:
292                         str := spew.Sprintf(test.format, test.in)
293                         buf.WriteString(str)
294
295                 case fSprintln:
296                         str := spew.Sprintln(test.in)
297                         buf.WriteString(str)
298
299                 default:
300                         t.Errorf("%v #%d unrecognized function", test.f, i)
301                         continue
302                 }
303                 s := buf.String()
304                 if test.want != s {
305                         t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
306                         continue
307                 }
308         }
309 }