OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / btcjson / register_test.go
1 // Copyright (c) 2014 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
4
5 package btcjson_test
6
7 import (
8         "reflect"
9         "sort"
10         "testing"
11
12         "github.com/btcsuite/btcd/btcjson"
13 )
14
15 // TestUsageFlagStringer tests the stringized output for the UsageFlag type.
16 func TestUsageFlagStringer(t *testing.T) {
17         t.Parallel()
18
19         tests := []struct {
20                 in   btcjson.UsageFlag
21                 want string
22         }{
23                 {0, "0x0"},
24                 {btcjson.UFWalletOnly, "UFWalletOnly"},
25                 {btcjson.UFWebsocketOnly, "UFWebsocketOnly"},
26                 {btcjson.UFNotification, "UFNotification"},
27                 {btcjson.UFWalletOnly | btcjson.UFWebsocketOnly,
28                         "UFWalletOnly|UFWebsocketOnly"},
29                 {btcjson.UFWalletOnly | btcjson.UFWebsocketOnly | (1 << 31),
30                         "UFWalletOnly|UFWebsocketOnly|0x80000000"},
31         }
32
33         // Detect additional usage flags that don't have the stringer added.
34         numUsageFlags := 0
35         highestUsageFlagBit := btcjson.TstHighestUsageFlagBit
36         for highestUsageFlagBit > 1 {
37                 numUsageFlags++
38                 highestUsageFlagBit >>= 1
39         }
40         if len(tests)-3 != numUsageFlags {
41                 t.Errorf("It appears a usage flag was added without adding " +
42                         "an associated stringer test")
43         }
44
45         t.Logf("Running %d tests", len(tests))
46         for i, test := range tests {
47                 result := test.in.String()
48                 if result != test.want {
49                         t.Errorf("String #%d\n got: %s want: %s", i, result,
50                                 test.want)
51                         continue
52                 }
53         }
54 }
55
56 // TestRegisterCmdErrors ensures the RegisterCmd function returns the expected
57 // error when provided with invalid types.
58 func TestRegisterCmdErrors(t *testing.T) {
59         t.Parallel()
60
61         tests := []struct {
62                 name    string
63                 method  string
64                 cmdFunc func() interface{}
65                 flags   btcjson.UsageFlag
66                 err     btcjson.Error
67         }{
68                 {
69                         name:   "duplicate method",
70                         method: "getblock",
71                         cmdFunc: func() interface{} {
72                                 return struct{}{}
73                         },
74                         err: btcjson.Error{ErrorCode: btcjson.ErrDuplicateMethod},
75                 },
76                 {
77                         name:   "invalid usage flags",
78                         method: "registertestcmd",
79                         cmdFunc: func() interface{} {
80                                 return 0
81                         },
82                         flags: btcjson.TstHighestUsageFlagBit,
83                         err:   btcjson.Error{ErrorCode: btcjson.ErrInvalidUsageFlags},
84                 },
85                 {
86                         name:   "invalid type",
87                         method: "registertestcmd",
88                         cmdFunc: func() interface{} {
89                                 return 0
90                         },
91                         err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
92                 },
93                 {
94                         name:   "invalid type 2",
95                         method: "registertestcmd",
96                         cmdFunc: func() interface{} {
97                                 return &[]string{}
98                         },
99                         err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
100                 },
101                 {
102                         name:   "embedded field",
103                         method: "registertestcmd",
104                         cmdFunc: func() interface{} {
105                                 type test struct{ int }
106                                 return (*test)(nil)
107                         },
108                         err: btcjson.Error{ErrorCode: btcjson.ErrEmbeddedType},
109                 },
110                 {
111                         name:   "unexported field",
112                         method: "registertestcmd",
113                         cmdFunc: func() interface{} {
114                                 type test struct{ a int }
115                                 return (*test)(nil)
116                         },
117                         err: btcjson.Error{ErrorCode: btcjson.ErrUnexportedField},
118                 },
119                 {
120                         name:   "unsupported field type 1",
121                         method: "registertestcmd",
122                         cmdFunc: func() interface{} {
123                                 type test struct{ A **int }
124                                 return (*test)(nil)
125                         },
126                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
127                 },
128                 {
129                         name:   "unsupported field type 2",
130                         method: "registertestcmd",
131                         cmdFunc: func() interface{} {
132                                 type test struct{ A chan int }
133                                 return (*test)(nil)
134                         },
135                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
136                 },
137                 {
138                         name:   "unsupported field type 3",
139                         method: "registertestcmd",
140                         cmdFunc: func() interface{} {
141                                 type test struct{ A complex64 }
142                                 return (*test)(nil)
143                         },
144                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
145                 },
146                 {
147                         name:   "unsupported field type 4",
148                         method: "registertestcmd",
149                         cmdFunc: func() interface{} {
150                                 type test struct{ A complex128 }
151                                 return (*test)(nil)
152                         },
153                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
154                 },
155                 {
156                         name:   "unsupported field type 5",
157                         method: "registertestcmd",
158                         cmdFunc: func() interface{} {
159                                 type test struct{ A func() }
160                                 return (*test)(nil)
161                         },
162                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
163                 },
164                 {
165                         name:   "unsupported field type 6",
166                         method: "registertestcmd",
167                         cmdFunc: func() interface{} {
168                                 type test struct{ A interface{} }
169                                 return (*test)(nil)
170                         },
171                         err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
172                 },
173                 {
174                         name:   "required after optional",
175                         method: "registertestcmd",
176                         cmdFunc: func() interface{} {
177                                 type test struct {
178                                         A *int
179                                         B int
180                                 }
181                                 return (*test)(nil)
182                         },
183                         err: btcjson.Error{ErrorCode: btcjson.ErrNonOptionalField},
184                 },
185                 {
186                         name:   "non-optional with default",
187                         method: "registertestcmd",
188                         cmdFunc: func() interface{} {
189                                 type test struct {
190                                         A int `jsonrpcdefault:"1"`
191                                 }
192                                 return (*test)(nil)
193                         },
194                         err: btcjson.Error{ErrorCode: btcjson.ErrNonOptionalDefault},
195                 },
196                 {
197                         name:   "mismatched default",
198                         method: "registertestcmd",
199                         cmdFunc: func() interface{} {
200                                 type test struct {
201                                         A *int `jsonrpcdefault:"1.7"`
202                                 }
203                                 return (*test)(nil)
204                         },
205                         err: btcjson.Error{ErrorCode: btcjson.ErrMismatchedDefault},
206                 },
207         }
208
209         t.Logf("Running %d tests", len(tests))
210         for i, test := range tests {
211                 err := btcjson.RegisterCmd(test.method, test.cmdFunc(),
212                         test.flags)
213                 if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
214                         t.Errorf("Test #%d (%s) wrong error - got %T, "+
215                                 "want %T", i, test.name, err, test.err)
216                         continue
217                 }
218                 gotErrorCode := err.(btcjson.Error).ErrorCode
219                 if gotErrorCode != test.err.ErrorCode {
220                         t.Errorf("Test #%d (%s) mismatched error code - got "+
221                                 "%v, want %v", i, test.name, gotErrorCode,
222                                 test.err.ErrorCode)
223                         continue
224                 }
225         }
226 }
227
228 // TestMustRegisterCmdPanic ensures the MustRegisterCmd function panics when
229 // used to register an invalid type.
230 func TestMustRegisterCmdPanic(t *testing.T) {
231         t.Parallel()
232
233         // Setup a defer to catch the expected panic to ensure it actually
234         // paniced.
235         defer func() {
236                 if err := recover(); err == nil {
237                         t.Error("MustRegisterCmd did not panic as expected")
238                 }
239         }()
240
241         // Intentionally try to register an invalid type to force a panic.
242         btcjson.MustRegisterCmd("panicme", 0, 0)
243 }
244
245 // TestRegisteredCmdMethods tests the RegisteredCmdMethods function ensure it
246 // works as expected.
247 func TestRegisteredCmdMethods(t *testing.T) {
248         t.Parallel()
249
250         // Ensure the registerd methods are returned.
251         methods := btcjson.RegisteredCmdMethods()
252         if len(methods) == 0 {
253                 t.Fatal("RegisteredCmdMethods: no methods")
254         }
255
256         // Ensure the returned methods are sorted.
257         sortedMethods := make([]string, len(methods))
258         copy(sortedMethods, methods)
259         sort.Sort(sort.StringSlice(sortedMethods))
260         if !reflect.DeepEqual(sortedMethods, methods) {
261                 t.Fatal("RegisteredCmdMethods: methods are not sorted")
262         }
263 }