github.com/palcoin-project/palcd@v1.0.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/palcoin-project/palcd/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  }