github.com/btcsuite/btcd@v0.24.0/btcjson/cmdinfo_test.go (about) 1 // Copyright (c) 2015 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 "testing" 10 11 "github.com/btcsuite/btcd/btcjson" 12 ) 13 14 // TestCmdMethod tests the CmdMethod function to ensure it retunrs the expected 15 // methods and errors. 16 func TestCmdMethod(t *testing.T) { 17 t.Parallel() 18 19 tests := []struct { 20 name string 21 cmd interface{} 22 method string 23 err error 24 }{ 25 { 26 name: "unregistered type", 27 cmd: (*int)(nil), 28 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod}, 29 }, 30 { 31 name: "nil pointer of registered type", 32 cmd: (*btcjson.GetBlockCmd)(nil), 33 method: "getblock", 34 }, 35 { 36 name: "nil instance of registered type", 37 cmd: &btcjson.GetBlockCountCmd{}, 38 method: "getblockcount", 39 }, 40 } 41 42 t.Logf("Running %d tests", len(tests)) 43 for i, test := range tests { 44 method, err := btcjson.CmdMethod(test.cmd) 45 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 46 t.Errorf("Test #%d (%s) wrong error - got %T (%[3]v), "+ 47 "want %T", i, test.name, err, test.err) 48 continue 49 } 50 if err != nil { 51 gotErrorCode := err.(btcjson.Error).ErrorCode 52 if gotErrorCode != test.err.(btcjson.Error).ErrorCode { 53 t.Errorf("Test #%d (%s) mismatched error code "+ 54 "- got %v (%v), want %v", i, test.name, 55 gotErrorCode, err, 56 test.err.(btcjson.Error).ErrorCode) 57 continue 58 } 59 60 continue 61 } 62 63 // Ensure method matches the expected value. 64 if method != test.method { 65 t.Errorf("Test #%d (%s) mismatched method - got %v, "+ 66 "want %v", i, test.name, method, test.method) 67 continue 68 } 69 } 70 } 71 72 // TestMethodUsageFlags tests the MethodUsage function ensure it returns the 73 // expected flags and errors. 74 func TestMethodUsageFlags(t *testing.T) { 75 t.Parallel() 76 77 tests := []struct { 78 name string 79 method string 80 err error 81 flags btcjson.UsageFlag 82 }{ 83 { 84 name: "unregistered type", 85 method: "bogusmethod", 86 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod}, 87 }, 88 { 89 name: "getblock", 90 method: "getblock", 91 flags: 0, 92 }, 93 { 94 name: "walletpassphrase", 95 method: "walletpassphrase", 96 flags: btcjson.UFWalletOnly, 97 }, 98 } 99 100 t.Logf("Running %d tests", len(tests)) 101 for i, test := range tests { 102 flags, err := btcjson.MethodUsageFlags(test.method) 103 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 104 t.Errorf("Test #%d (%s) wrong error - got %T (%[3]v), "+ 105 "want %T", i, test.name, err, test.err) 106 continue 107 } 108 if err != nil { 109 gotErrorCode := err.(btcjson.Error).ErrorCode 110 if gotErrorCode != test.err.(btcjson.Error).ErrorCode { 111 t.Errorf("Test #%d (%s) mismatched error code "+ 112 "- got %v (%v), want %v", i, test.name, 113 gotErrorCode, err, 114 test.err.(btcjson.Error).ErrorCode) 115 continue 116 } 117 118 continue 119 } 120 121 // Ensure flags match the expected value. 122 if flags != test.flags { 123 t.Errorf("Test #%d (%s) mismatched flags - got %v, "+ 124 "want %v", i, test.name, flags, test.flags) 125 continue 126 } 127 } 128 } 129 130 // TestMethodUsageText tests the MethodUsageText function ensure it returns the 131 // expected text. 132 func TestMethodUsageText(t *testing.T) { 133 t.Parallel() 134 135 tests := []struct { 136 name string 137 method string 138 err error 139 expected string 140 }{ 141 { 142 name: "unregistered type", 143 method: "bogusmethod", 144 err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod}, 145 }, 146 { 147 name: "getblockcount", 148 method: "getblockcount", 149 expected: "getblockcount", 150 }, 151 { 152 name: "getblock", 153 method: "getblock", 154 expected: `getblock "hash" (verbosity=1)`, 155 }, 156 } 157 158 t.Logf("Running %d tests", len(tests)) 159 for i, test := range tests { 160 usage, err := btcjson.MethodUsageText(test.method) 161 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 162 t.Errorf("Test #%d (%s) wrong error - got %T (%[3]v), "+ 163 "want %T", i, test.name, err, test.err) 164 continue 165 } 166 if err != nil { 167 gotErrorCode := err.(btcjson.Error).ErrorCode 168 if gotErrorCode != test.err.(btcjson.Error).ErrorCode { 169 t.Errorf("Test #%d (%s) mismatched error code "+ 170 "- got %v (%v), want %v", i, test.name, 171 gotErrorCode, err, 172 test.err.(btcjson.Error).ErrorCode) 173 continue 174 } 175 176 continue 177 } 178 179 // Ensure usage matches the expected value. 180 if usage != test.expected { 181 t.Errorf("Test #%d (%s) mismatched usage - got %v, "+ 182 "want %v", i, test.name, usage, test.expected) 183 continue 184 } 185 186 // Get the usage again to exercise caching. 187 usage, err = btcjson.MethodUsageText(test.method) 188 if err != nil { 189 t.Errorf("Test #%d (%s) unexpected error: %v", i, 190 test.name, err) 191 continue 192 } 193 194 // Ensure usage still matches the expected value. 195 if usage != test.expected { 196 t.Errorf("Test #%d (%s) mismatched usage - got %v, "+ 197 "want %v", i, test.name, usage, test.expected) 198 continue 199 } 200 } 201 } 202 203 // TestFieldUsage tests the internal fieldUsage function ensure it returns the 204 // expected text. 205 func TestFieldUsage(t *testing.T) { 206 t.Parallel() 207 208 tests := []struct { 209 name string 210 field reflect.StructField 211 defValue *reflect.Value 212 expected string 213 }{ 214 { 215 name: "jsonrpcusage tag override", 216 field: func() reflect.StructField { 217 type s struct { 218 Test int `jsonrpcusage:"testvalue"` 219 } 220 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 221 }(), 222 defValue: nil, 223 expected: "testvalue", 224 }, 225 { 226 name: "generic interface", 227 field: func() reflect.StructField { 228 type s struct { 229 Test interface{} 230 } 231 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 232 }(), 233 defValue: nil, 234 expected: `test`, 235 }, 236 { 237 name: "string without default value", 238 field: func() reflect.StructField { 239 type s struct { 240 Test string 241 } 242 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 243 }(), 244 defValue: nil, 245 expected: `"test"`, 246 }, 247 { 248 name: "string with default value", 249 field: func() reflect.StructField { 250 type s struct { 251 Test string 252 } 253 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 254 }(), 255 defValue: func() *reflect.Value { 256 value := "default" 257 rv := reflect.ValueOf(&value) 258 return &rv 259 }(), 260 expected: `test="default"`, 261 }, 262 { 263 name: "array of strings", 264 field: func() reflect.StructField { 265 type s struct { 266 Test []string 267 } 268 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 269 }(), 270 defValue: nil, 271 expected: `["test",...]`, 272 }, 273 { 274 name: "array of strings with plural field name 1", 275 field: func() reflect.StructField { 276 type s struct { 277 Keys []string 278 } 279 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 280 }(), 281 defValue: nil, 282 expected: `["key",...]`, 283 }, 284 { 285 name: "array of strings with plural field name 2", 286 field: func() reflect.StructField { 287 type s struct { 288 Addresses []string 289 } 290 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 291 }(), 292 defValue: nil, 293 expected: `["address",...]`, 294 }, 295 { 296 name: "array of strings with plural field name 3", 297 field: func() reflect.StructField { 298 type s struct { 299 Capabilities []string 300 } 301 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 302 }(), 303 defValue: nil, 304 expected: `["capability",...]`, 305 }, 306 { 307 name: "array of structs", 308 field: func() reflect.StructField { 309 type s2 struct { 310 Txid string 311 } 312 type s struct { 313 Capabilities []s2 314 } 315 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 316 }(), 317 defValue: nil, 318 expected: `[{"txid":"value"},...]`, 319 }, 320 { 321 name: "array of ints", 322 field: func() reflect.StructField { 323 type s struct { 324 Test []int 325 } 326 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 327 }(), 328 defValue: nil, 329 expected: `[test,...]`, 330 }, 331 { 332 name: "sub struct with jsonrpcusage tag override", 333 field: func() reflect.StructField { 334 type s2 struct { 335 Test string `jsonrpcusage:"testusage"` 336 } 337 type s struct { 338 Test s2 339 } 340 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 341 }(), 342 defValue: nil, 343 expected: `{testusage}`, 344 }, 345 { 346 name: "sub struct with string", 347 field: func() reflect.StructField { 348 type s2 struct { 349 Txid string 350 } 351 type s struct { 352 Test s2 353 } 354 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 355 }(), 356 defValue: nil, 357 expected: `{"txid":"value"}`, 358 }, 359 { 360 name: "sub struct with int", 361 field: func() reflect.StructField { 362 type s2 struct { 363 Vout int 364 } 365 type s struct { 366 Test s2 367 } 368 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 369 }(), 370 defValue: nil, 371 expected: `{"vout":n}`, 372 }, 373 { 374 name: "sub struct with float", 375 field: func() reflect.StructField { 376 type s2 struct { 377 Amount float64 378 } 379 type s struct { 380 Test s2 381 } 382 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 383 }(), 384 defValue: nil, 385 expected: `{"amount":n.nnn}`, 386 }, 387 { 388 name: "sub struct with sub struct", 389 field: func() reflect.StructField { 390 type s3 struct { 391 Amount float64 392 } 393 type s2 struct { 394 Template s3 395 } 396 type s struct { 397 Test s2 398 } 399 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 400 }(), 401 defValue: nil, 402 expected: `{"template":{"amount":n.nnn}}`, 403 }, 404 { 405 name: "sub struct with slice", 406 field: func() reflect.StructField { 407 type s2 struct { 408 Capabilities []string 409 } 410 type s struct { 411 Test s2 412 } 413 return reflect.TypeOf((*s)(nil)).Elem().Field(0) 414 }(), 415 defValue: nil, 416 expected: `{"capabilities":["capability",...]}`, 417 }, 418 } 419 420 t.Logf("Running %d tests", len(tests)) 421 for i, test := range tests { 422 // Ensure usage matches the expected value. 423 usage := btcjson.TstFieldUsage(test.field, test.defValue) 424 if usage != test.expected { 425 t.Errorf("Test #%d (%s) mismatched usage - got %v, "+ 426 "want %v", i, test.name, usage, test.expected) 427 continue 428 } 429 } 430 }