OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / davecgh / go-spew / spew / common_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         "fmt"
21         "reflect"
22         "testing"
23
24         "github.com/davecgh/go-spew/spew"
25 )
26
27 // custom type to test Stinger interface on non-pointer receiver.
28 type stringer string
29
30 // String implements the Stringer interface for testing invocation of custom
31 // stringers on types with non-pointer receivers.
32 func (s stringer) String() string {
33         return "stringer " + string(s)
34 }
35
36 // custom type to test Stinger interface on pointer receiver.
37 type pstringer string
38
39 // String implements the Stringer interface for testing invocation of custom
40 // stringers on types with only pointer receivers.
41 func (s *pstringer) String() string {
42         return "stringer " + string(*s)
43 }
44
45 // xref1 and xref2 are cross referencing structs for testing circular reference
46 // detection.
47 type xref1 struct {
48         ps2 *xref2
49 }
50 type xref2 struct {
51         ps1 *xref1
52 }
53
54 // indirCir1, indirCir2, and indirCir3 are used to generate an indirect circular
55 // reference for testing detection.
56 type indirCir1 struct {
57         ps2 *indirCir2
58 }
59 type indirCir2 struct {
60         ps3 *indirCir3
61 }
62 type indirCir3 struct {
63         ps1 *indirCir1
64 }
65
66 // embed is used to test embedded structures.
67 type embed struct {
68         a string
69 }
70
71 // embedwrap is used to test embedded structures.
72 type embedwrap struct {
73         *embed
74         e *embed
75 }
76
77 // panicer is used to intentionally cause a panic for testing spew properly
78 // handles them
79 type panicer int
80
81 func (p panicer) String() string {
82         panic("test panic")
83 }
84
85 // customError is used to test custom error interface invocation.
86 type customError int
87
88 func (e customError) Error() string {
89         return fmt.Sprintf("error: %d", int(e))
90 }
91
92 // stringizeWants converts a slice of wanted test output into a format suitable
93 // for a test error message.
94 func stringizeWants(wants []string) string {
95         s := ""
96         for i, want := range wants {
97                 if i > 0 {
98                         s += fmt.Sprintf("want%d: %s", i+1, want)
99                 } else {
100                         s += "want: " + want
101                 }
102         }
103         return s
104 }
105
106 // testFailed returns whether or not a test failed by checking if the result
107 // of the test is in the slice of wanted strings.
108 func testFailed(result string, wants []string) bool {
109         for _, want := range wants {
110                 if result == want {
111                         return false
112                 }
113         }
114         return true
115 }
116
117 type sortableStruct struct {
118         x int
119 }
120
121 func (ss sortableStruct) String() string {
122         return fmt.Sprintf("ss.%d", ss.x)
123 }
124
125 type unsortableStruct struct {
126         x int
127 }
128
129 type sortTestCase struct {
130         input    []reflect.Value
131         expected []reflect.Value
132 }
133
134 func helpTestSortValues(tests []sortTestCase, cs *spew.ConfigState, t *testing.T) {
135         getInterfaces := func(values []reflect.Value) []interface{} {
136                 interfaces := []interface{}{}
137                 for _, v := range values {
138                         interfaces = append(interfaces, v.Interface())
139                 }
140                 return interfaces
141         }
142
143         for _, test := range tests {
144                 spew.SortValues(test.input, cs)
145                 // reflect.DeepEqual cannot really make sense of reflect.Value,
146                 // probably because of all the pointer tricks. For instance,
147                 // v(2.0) != v(2.0) on a 32-bits system. Turn them into interface{}
148                 // instead.
149                 input := getInterfaces(test.input)
150                 expected := getInterfaces(test.expected)
151                 if !reflect.DeepEqual(input, expected) {
152                         t.Errorf("Sort mismatch:\n %v != %v", input, expected)
153                 }
154         }
155 }
156
157 // TestSortValues ensures the sort functionality for relect.Value based sorting
158 // works as intended.
159 func TestSortValues(t *testing.T) {
160         v := reflect.ValueOf
161
162         a := v("a")
163         b := v("b")
164         c := v("c")
165         embedA := v(embed{"a"})
166         embedB := v(embed{"b"})
167         embedC := v(embed{"c"})
168         tests := []sortTestCase{
169                 // No values.
170                 {
171                         []reflect.Value{},
172                         []reflect.Value{},
173                 },
174                 // Bools.
175                 {
176                         []reflect.Value{v(false), v(true), v(false)},
177                         []reflect.Value{v(false), v(false), v(true)},
178                 },
179                 // Ints.
180                 {
181                         []reflect.Value{v(2), v(1), v(3)},
182                         []reflect.Value{v(1), v(2), v(3)},
183                 },
184                 // Uints.
185                 {
186                         []reflect.Value{v(uint8(2)), v(uint8(1)), v(uint8(3))},
187                         []reflect.Value{v(uint8(1)), v(uint8(2)), v(uint8(3))},
188                 },
189                 // Floats.
190                 {
191                         []reflect.Value{v(2.0), v(1.0), v(3.0)},
192                         []reflect.Value{v(1.0), v(2.0), v(3.0)},
193                 },
194                 // Strings.
195                 {
196                         []reflect.Value{b, a, c},
197                         []reflect.Value{a, b, c},
198                 },
199                 // Array
200                 {
201                         []reflect.Value{v([3]int{3, 2, 1}), v([3]int{1, 3, 2}), v([3]int{1, 2, 3})},
202                         []reflect.Value{v([3]int{1, 2, 3}), v([3]int{1, 3, 2}), v([3]int{3, 2, 1})},
203                 },
204                 // Uintptrs.
205                 {
206                         []reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))},
207                         []reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))},
208                 },
209                 // SortableStructs.
210                 {
211                         // Note: not sorted - DisableMethods is set.
212                         []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
213                         []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
214                 },
215                 // UnsortableStructs.
216                 {
217                         // Note: not sorted - SpewKeys is false.
218                         []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
219                         []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
220                 },
221                 // Invalid.
222                 {
223                         []reflect.Value{embedB, embedA, embedC},
224                         []reflect.Value{embedB, embedA, embedC},
225                 },
226         }
227         cs := spew.ConfigState{DisableMethods: true, SpewKeys: false}
228         helpTestSortValues(tests, &cs, t)
229 }
230
231 // TestSortValuesWithMethods ensures the sort functionality for relect.Value
232 // based sorting works as intended when using string methods.
233 func TestSortValuesWithMethods(t *testing.T) {
234         v := reflect.ValueOf
235
236         a := v("a")
237         b := v("b")
238         c := v("c")
239         tests := []sortTestCase{
240                 // Ints.
241                 {
242                         []reflect.Value{v(2), v(1), v(3)},
243                         []reflect.Value{v(1), v(2), v(3)},
244                 },
245                 // Strings.
246                 {
247                         []reflect.Value{b, a, c},
248                         []reflect.Value{a, b, c},
249                 },
250                 // SortableStructs.
251                 {
252                         []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
253                         []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
254                 },
255                 // UnsortableStructs.
256                 {
257                         // Note: not sorted - SpewKeys is false.
258                         []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
259                         []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
260                 },
261         }
262         cs := spew.ConfigState{DisableMethods: false, SpewKeys: false}
263         helpTestSortValues(tests, &cs, t)
264 }
265
266 // TestSortValuesWithSpew ensures the sort functionality for relect.Value
267 // based sorting works as intended when using spew to stringify keys.
268 func TestSortValuesWithSpew(t *testing.T) {
269         v := reflect.ValueOf
270
271         a := v("a")
272         b := v("b")
273         c := v("c")
274         tests := []sortTestCase{
275                 // Ints.
276                 {
277                         []reflect.Value{v(2), v(1), v(3)},
278                         []reflect.Value{v(1), v(2), v(3)},
279                 },
280                 // Strings.
281                 {
282                         []reflect.Value{b, a, c},
283                         []reflect.Value{a, b, c},
284                 },
285                 // SortableStructs.
286                 {
287                         []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
288                         []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
289                 },
290                 // UnsortableStructs.
291                 {
292                         []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
293                         []reflect.Value{v(unsortableStruct{1}), v(unsortableStruct{2}), v(unsortableStruct{3})},
294                 },
295         }
296         cs := spew.ConfigState{DisableMethods: true, SpewKeys: true}
297         helpTestSortValues(tests, &cs, t)
298 }