// TestGenerateHelpErrors ensures the GenerateHelp function returns the expected // errors. func TestGenerateHelpErrors(t *testing.T) { t.Parallel() tests := []struct { name string method string resultTypes []interface{} err btcjson.Error }{ { name: "unregistered command", method: "boguscommand", err: btcjson.Error{ErrorCode: btcjson.ErrUnregisteredMethod}, }, { name: "non-pointer result type", method: "help", resultTypes: []interface{}{0}, err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, }, { name: "invalid result type", method: "help", resultTypes: []interface{}{(*complex64)(nil)}, err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, }, { name: "missing description", method: "help", resultTypes: []interface{}{(*string)(nil), nil}, err: btcjson.Error{ErrorCode: btcjson.ErrMissingDescription}, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { _, err := btcjson.GenerateHelp(test.method, nil, test.resultTypes...) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("Test #%d (%s) wrong error - got %T (%[2]v), "+ "want %T", i, test.name, err, test.err) continue } gotErrorCode := err.(btcjson.Error).ErrorCode if gotErrorCode != test.err.ErrorCode { t.Errorf("Test #%d (%s) mismatched error code - got "+ "%v (%v), want %v", i, test.name, gotErrorCode, err, test.err.ErrorCode) continue } } }
func writeLocaleHelp(locale, goLocale string, descs map[string]string) { funcName := "helpDescs" + goLocale writefln("func %s() map[string]string {", funcName) writefln("return map[string]string{") for i := range rpchelp.Methods { m := &rpchelp.Methods[i] helpText, err := btcjson.GenerateHelp(m.Method, descs, m.ResultTypes...) if err != nil { log.Fatal(err) } writefln("%q: %q,", m.Method, helpText) } writefln("}") writefln("}") }
// TestGenerateHelp performs a very basic test to ensure GenerateHelp is working // as expected. The internal are testd much more thoroughly in other tests, so // there is no need to add more tests here. func TestGenerateHelp(t *testing.T) { t.Parallel() descs := map[string]string{ "help--synopsis": "test", "help-command": "test", } help, err := btcjson.GenerateHelp("help", descs) if err != nil { t.Fatalf("GenerateHelp: unexpected error: %v", err) } wantHelp := "help (\"command\")\n\n" + "test\n\nArguments:\n1. command (string, optional) test\n\n" + "Result:\nNothing\n" if help != wantHelp { t.Fatalf("GenerateHelp: unexpected help - got\n%v\nwant\n%v", help, wantHelp) } }
// TestRPCMethodHelpGeneration ensures that help text can be generated for every // method of the RPC server for every supported locale. func TestRPCMethodHelpGeneration(t *testing.T) { needsGenerate := false defer func() { if needsGenerate && !t.Failed() { t.Error("Generated help texts are out of date: run 'go generate'") return } if t.Failed() { t.Log("Regenerate help texts with 'go generate' after fixing") } }() for i := range rpchelp.HelpDescs { svrMethods := serverMethods() locale := rpchelp.HelpDescs[i].Locale generatedDescs := localeHelpDescs[locale]() for _, m := range rpchelp.Methods { delete(svrMethods, m.Method) helpText, err := btcjson.GenerateHelp(m.Method, rpchelp.HelpDescs[i].Descs, m.ResultTypes...) if err != nil { t.Errorf("Cannot generate '%s' help for method '%s': missing description for '%s'", locale, m.Method, err) continue } if !needsGenerate && helpText != generatedDescs[m.Method] { needsGenerate = true } } for m := range svrMethods { t.Errorf("Missing '%s' help for method '%s'", locale, m) } } }
// rpcMethodHelp returns an RPC help string for the provided method. // // This function is safe for concurrent access. func (c *helpCacher) rpcMethodHelp(method string) (string, error) { c.Lock() defer c.Unlock() // Return the cached method help if it exists. if help, exists := c.methodHelp[method]; exists { return help, nil } // Look up the result types for the method. resultTypes, ok := rpcResultTypes[method] if !ok { return "", errors.New("no result types specified for method " + method) } // Generate, cache, and return the help. help, err := btcjson.GenerateHelp(method, helpDescsEnUS, resultTypes...) if err != nil { return "", err } c.methodHelp[method] = help return help, nil }