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.
12 "github.com/btcsuite/btcd/btcjson"
15 // TestUsageFlagStringer tests the stringized output for the UsageFlag type.
16 func TestUsageFlagStringer(t *testing.T) {
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"},
33 // Detect additional usage flags that don't have the stringer added.
35 highestUsageFlagBit := btcjson.TstHighestUsageFlagBit
36 for highestUsageFlagBit > 1 {
38 highestUsageFlagBit >>= 1
40 if len(tests)-3 != numUsageFlags {
41 t.Errorf("It appears a usage flag was added without adding " +
42 "an associated stringer test")
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,
56 // TestRegisterCmdErrors ensures the RegisterCmd function returns the expected
57 // error when provided with invalid types.
58 func TestRegisterCmdErrors(t *testing.T) {
64 cmdFunc func() interface{}
65 flags btcjson.UsageFlag
69 name: "duplicate method",
71 cmdFunc: func() interface{} {
74 err: btcjson.Error{ErrorCode: btcjson.ErrDuplicateMethod},
77 name: "invalid usage flags",
78 method: "registertestcmd",
79 cmdFunc: func() interface{} {
82 flags: btcjson.TstHighestUsageFlagBit,
83 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidUsageFlags},
87 method: "registertestcmd",
88 cmdFunc: func() interface{} {
91 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
94 name: "invalid type 2",
95 method: "registertestcmd",
96 cmdFunc: func() interface{} {
99 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
102 name: "embedded field",
103 method: "registertestcmd",
104 cmdFunc: func() interface{} {
105 type test struct{ int }
108 err: btcjson.Error{ErrorCode: btcjson.ErrEmbeddedType},
111 name: "unexported field",
112 method: "registertestcmd",
113 cmdFunc: func() interface{} {
114 type test struct{ a int }
117 err: btcjson.Error{ErrorCode: btcjson.ErrUnexportedField},
120 name: "unsupported field type 1",
121 method: "registertestcmd",
122 cmdFunc: func() interface{} {
123 type test struct{ A **int }
126 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
129 name: "unsupported field type 2",
130 method: "registertestcmd",
131 cmdFunc: func() interface{} {
132 type test struct{ A chan int }
135 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
138 name: "unsupported field type 3",
139 method: "registertestcmd",
140 cmdFunc: func() interface{} {
141 type test struct{ A complex64 }
144 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
147 name: "unsupported field type 4",
148 method: "registertestcmd",
149 cmdFunc: func() interface{} {
150 type test struct{ A complex128 }
153 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
156 name: "unsupported field type 5",
157 method: "registertestcmd",
158 cmdFunc: func() interface{} {
159 type test struct{ A func() }
162 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
165 name: "unsupported field type 6",
166 method: "registertestcmd",
167 cmdFunc: func() interface{} {
168 type test struct{ A interface{} }
171 err: btcjson.Error{ErrorCode: btcjson.ErrUnsupportedFieldType},
174 name: "required after optional",
175 method: "registertestcmd",
176 cmdFunc: func() interface{} {
183 err: btcjson.Error{ErrorCode: btcjson.ErrNonOptionalField},
186 name: "non-optional with default",
187 method: "registertestcmd",
188 cmdFunc: func() interface{} {
190 A int `jsonrpcdefault:"1"`
194 err: btcjson.Error{ErrorCode: btcjson.ErrNonOptionalDefault},
197 name: "mismatched default",
198 method: "registertestcmd",
199 cmdFunc: func() interface{} {
201 A *int `jsonrpcdefault:"1.7"`
205 err: btcjson.Error{ErrorCode: btcjson.ErrMismatchedDefault},
209 t.Logf("Running %d tests", len(tests))
210 for i, test := range tests {
211 err := btcjson.RegisterCmd(test.method, test.cmdFunc(),
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)
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,
228 // TestMustRegisterCmdPanic ensures the MustRegisterCmd function panics when
229 // used to register an invalid type.
230 func TestMustRegisterCmdPanic(t *testing.T) {
233 // Setup a defer to catch the expected panic to ensure it actually
236 if err := recover(); err == nil {
237 t.Error("MustRegisterCmd did not panic as expected")
241 // Intentionally try to register an invalid type to force a panic.
242 btcjson.MustRegisterCmd("panicme", 0, 0)
245 // TestRegisteredCmdMethods tests the RegisteredCmdMethods function ensure it
246 // works as expected.
247 func TestRegisteredCmdMethods(t *testing.T) {
250 // Ensure the registerd methods are returned.
251 methods := btcjson.RegisteredCmdMethods()
252 if len(methods) == 0 {
253 t.Fatal("RegisteredCmdMethods: no methods")
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")