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.
13 "github.com/btcsuite/btcd/btcjson"
16 // TestAssignField tests the assignField function handles supported combinations
18 func TestAssignField(t *testing.T) {
34 name: "same types - more source pointers",
36 src: func() interface{} {
43 name: "same types - more dest pointers",
44 dest: func() interface{} {
52 name: "convertible types - more source pointers",
54 src: func() interface{} {
61 name: "convertible types - both pointers",
62 dest: func() interface{} {
66 src: func() interface{} {
73 name: "convertible types - int16 -> int8",
79 name: "convertible types - int16 -> uint8",
85 name: "convertible types - uint16 -> int8",
91 name: "convertible types - uint16 -> uint8",
97 name: "convertible types - float32 -> float64",
100 expected: float64(1.5),
103 name: "convertible types - float64 -> float32",
106 expected: float32(1.5),
109 name: "convertible types - string -> bool",
115 name: "convertible types - string -> int8",
121 name: "convertible types - string -> uint8",
124 expected: uint8(100),
127 name: "convertible types - string -> float32",
130 expected: float32(1.5),
133 name: "convertible types - typecase string -> string",
135 src: func() interface{} {
142 name: "convertible types - string -> array",
144 src: `["test","test2"]`,
145 expected: [2]string{"test", "test2"},
148 name: "convertible types - string -> slice",
150 src: `["test","test2"]`,
151 expected: []string{"test", "test2"},
154 name: "convertible types - string -> struct",
155 dest: struct{ A int }{},
157 expected: struct{ A int }{100},
160 name: "convertible types - string -> map",
161 dest: map[string]float64{},
162 src: `{"1Address":1.5}`,
163 expected: map[string]float64{"1Address": 1.5},
167 t.Logf("Running %d tests", len(tests))
168 for i, test := range tests {
169 dst := reflect.New(reflect.TypeOf(test.dest)).Elem()
170 src := reflect.ValueOf(test.src)
171 err := btcjson.TstAssignField(1, "testField", dst, src)
173 t.Errorf("Test #%d (%s) unexpected error: %v", i,
178 // Inidirect through to the base types to ensure their values
180 for dst.Kind() == reflect.Ptr {
183 if !reflect.DeepEqual(dst.Interface(), test.expected) {
184 t.Errorf("Test #%d (%s) unexpected value - got %v, "+
185 "want %v", i, test.name, dst.Interface(),
192 // TestAssignFieldErrors tests the assignField function error paths.
193 func TestAssignFieldErrors(t *testing.T) {
203 name: "general incompatible int -> string",
206 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
209 name: "overflow source int -> dest int",
212 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
215 name: "overflow source int -> dest uint",
218 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
221 name: "int -> float",
224 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
227 name: "overflow source uint64 -> dest int64",
229 src: uint64(1 << 63),
230 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
233 name: "overflow source uint -> dest int",
236 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
239 name: "overflow source uint -> dest uint",
242 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
245 name: "uint -> float",
248 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
251 name: "float -> int",
254 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
257 name: "overflow float64 -> float32",
259 src: float64(math.MaxFloat64),
260 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
263 name: "invalid string -> bool",
266 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
269 name: "invalid string -> int",
272 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
275 name: "overflow string -> int",
278 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
281 name: "invalid string -> uint",
284 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
287 name: "overflow string -> uint",
290 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
293 name: "invalid string -> float",
296 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
299 name: "overflow string -> float",
301 src: "1.7976931348623157e+308",
302 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
305 name: "invalid string -> array",
308 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
311 name: "invalid string -> slice",
314 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
317 name: "invalid string -> struct",
318 dest: struct{ A int }{},
320 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
323 name: "invalid string -> map",
324 dest: map[string]int{},
326 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
330 t.Logf("Running %d tests", len(tests))
331 for i, test := range tests {
332 dst := reflect.New(reflect.TypeOf(test.dest)).Elem()
333 src := reflect.ValueOf(test.src)
334 err := btcjson.TstAssignField(1, "testField", dst, src)
335 if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
336 t.Errorf("Test #%d (%s) wrong error - got %T (%[3]v), "+
337 "want %T", i, test.name, err, test.err)
340 gotErrorCode := err.(btcjson.Error).ErrorCode
341 if gotErrorCode != test.err.ErrorCode {
342 t.Errorf("Test #%d (%s) mismatched error code - got "+
343 "%v (%v), want %v", i, test.name, gotErrorCode,
344 err, test.err.ErrorCode)
350 // TestNewCmdErrors ensures the error paths of NewCmd behave as expected.
351 func TestNewCmdErrors(t *testing.T) {
361 name: "unregistered command",
362 method: "boguscommand",
363 args: []interface{}{},
364 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod},
367 name: "too few parameters to command with required + optional",
369 args: []interface{}{},
370 err: btcjson.Error{ErrorCode: btcjson.ErrNumParams},
373 name: "too many parameters to command with no optional",
374 method: "getblockcount",
375 args: []interface{}{"123"},
376 err: btcjson.Error{ErrorCode: btcjson.ErrNumParams},
379 name: "incorrect parameter type",
381 args: []interface{}{1},
382 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
386 t.Logf("Running %d tests", len(tests))
387 for i, test := range tests {
388 _, err := btcjson.NewCmd(test.method, test.args...)
389 if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
390 t.Errorf("Test #%d (%s) wrong error - got %T (%[2]v), "+
391 "want %T", i, test.name, err, test.err)
394 gotErrorCode := err.(btcjson.Error).ErrorCode
395 if gotErrorCode != test.err.ErrorCode {
396 t.Errorf("Test #%d (%s) mismatched error code - got "+
397 "%v (%v), want %v", i, test.name, gotErrorCode,
398 err, test.err.ErrorCode)
404 // TestMarshalCmdErrors tests the error paths of the MarshalCmd function.
405 func TestMarshalCmdErrors(t *testing.T) {
415 name: "unregistered type",
418 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod},
421 name: "nil instance of registered type",
423 cmd: (*btcjson.GetBlockCmd)(nil),
424 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
427 name: "nil instance of registered type",
429 cmd: &btcjson.GetBlockCountCmd{},
430 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
434 t.Logf("Running %d tests", len(tests))
435 for i, test := range tests {
436 _, err := btcjson.MarshalCmd(test.id, test.cmd)
437 if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
438 t.Errorf("Test #%d (%s) wrong error - got %T (%[2]v), "+
439 "want %T", i, test.name, err, test.err)
442 gotErrorCode := err.(btcjson.Error).ErrorCode
443 if gotErrorCode != test.err.ErrorCode {
444 t.Errorf("Test #%d (%s) mismatched error code - got "+
445 "%v (%v), want %v", i, test.name, gotErrorCode,
446 err, test.err.ErrorCode)
452 // TestUnmarshalCmdErrors tests the error paths of the UnmarshalCmd function.
453 func TestUnmarshalCmdErrors(t *testing.T) {
458 request btcjson.Request
462 name: "unregistered type",
463 request: btcjson.Request{
465 Method: "bogusmethod",
469 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod},
472 name: "incorrect number of params",
473 request: btcjson.Request{
475 Method: "getblockcount",
476 Params: []json.RawMessage{[]byte(`"bogusparam"`)},
479 err: btcjson.Error{ErrorCode: btcjson.ErrNumParams},
482 name: "invalid type for a parameter",
483 request: btcjson.Request{
486 Params: []json.RawMessage{[]byte("1")},
489 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
492 name: "invalid JSON for a parameter",
493 request: btcjson.Request{
496 Params: []json.RawMessage{[]byte(`"1`)},
499 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType},
503 t.Logf("Running %d tests", len(tests))
504 for i, test := range tests {
505 _, err := btcjson.UnmarshalCmd(&test.request)
506 if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
507 t.Errorf("Test #%d (%s) wrong error - got %T (%[2]v), "+
508 "want %T", i, test.name, err, test.err)
511 gotErrorCode := err.(btcjson.Error).ErrorCode
512 if gotErrorCode != test.err.ErrorCode {
513 t.Errorf("Test #%d (%s) mismatched error code - got "+
514 "%v (%v), want %v", i, test.name, gotErrorCode,
515 err, test.err.ErrorCode)