github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/rpc/json_test.go (about) 1 package rpc 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "reflect" 8 "strconv" 9 "testing" 10 ) 11 12 type RWC struct { 13 *bufio.ReadWriter 14 } 15 16 func (rwc *RWC) Close() error { 17 return nil 18 } 19 20 func TestJSONRequestParsing(t *testing.T) { 21 server := NewServer() 22 service := new(Service) 23 24 if err := server.RegisterName("calc", service); err != nil { 25 t.Fatalf("%v", err) 26 } 27 28 req := bytes.NewBufferString(`{"id": 1234, "jsonrpc": "2.0", "method": "calc_add", "params": [11, 22]}`) 29 var str string 30 reply := bytes.NewBufferString(str) 31 rw := &RWC{bufio.NewReadWriter(bufio.NewReader(req), bufio.NewWriter(reply))} 32 33 codec := NewJSONCodec(rw) 34 35 requests, batch, err := codec.ReadRequestHeaders() 36 if err != nil { 37 t.Fatalf("%v", err) 38 } 39 40 if batch { 41 t.Fatalf("Request isn't a batch") 42 } 43 44 if len(requests) != 1 { 45 t.Fatalf("Expected 1 request but got %d requests - %v", len(requests), requests) 46 } 47 48 if requests[0].service != "calc" { 49 t.Fatalf("Expected service 'calc' but got '%s'", requests[0].service) 50 } 51 52 if requests[0].method != "add" { 53 t.Fatalf("Expected method 'Add' but got '%s'", requests[0].method) 54 } 55 56 if rawId, ok := requests[0].id.(*json.RawMessage); ok { 57 id, e := strconv.ParseInt(string(*rawId), 0, 64) 58 if e != nil { 59 t.Fatalf("%v", e) 60 } 61 if id != 1234 { 62 t.Fatalf("Expected id 1234 but got %d", id) 63 } 64 } else { 65 t.Fatalf("invalid request, expected *json.RawMesage got %T", requests[0].id) 66 } 67 68 var arg int 69 args := []reflect.Type{reflect.TypeOf(arg), reflect.TypeOf(arg)} 70 71 v, err := codec.ParseRequestArguments(args, requests[0].params) 72 if err != nil { 73 t.Fatalf("%v", err) 74 } 75 76 if len(v) != 2 { 77 t.Fatalf("Expected 2 argument values, got %d", len(v)) 78 } 79 80 if v[0].Int() != 11 || v[1].Int() != 22 { 81 t.Fatalf("expected %d == 11 && %d == 22", v[0].Int(), v[1].Int()) 82 } 83 } 84 85 func TestJSONRequestParamsParsing(t *testing.T) { 86 87 var ( 88 stringT = reflect.TypeOf("") 89 intT = reflect.TypeOf(0) 90 intPtrT = reflect.TypeOf(new(int)) 91 92 stringV = reflect.ValueOf("abc") 93 i = 1 94 intV = reflect.ValueOf(i) 95 intPtrV = reflect.ValueOf(&i) 96 ) 97 98 var validTests = []struct { 99 input string 100 argTypes []reflect.Type 101 expected []reflect.Value 102 }{ 103 {`[]`, []reflect.Type{}, []reflect.Value{}}, 104 {`[]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}}, 105 {`[1]`, []reflect.Type{intT}, []reflect.Value{intV}}, 106 {`[1,"abc"]`, []reflect.Type{intT, stringT}, []reflect.Value{intV, stringV}}, 107 {`[null]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}}, 108 {`[null,"abc"]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}}, 109 {`[null,"abc",null]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}}, 110 } 111 112 codec := jsonCodec{} 113 114 for _, test := range validTests { 115 params := (json.RawMessage)([]byte(test.input)) 116 args, err := codec.ParseRequestArguments(test.argTypes, params) 117 118 if err != nil { 119 t.Fatal(err) 120 } 121 122 var match []interface{} 123 json.Unmarshal([]byte(test.input), &match) 124 125 if len(args) != len(test.argTypes) { 126 t.Fatalf("expected %d parsed args, got %d", len(test.argTypes), len(args)) 127 } 128 129 for i, arg := range args { 130 expected := test.expected[i] 131 132 if arg.Kind() != expected.Kind() { 133 t.Errorf("expected type for param %d in %s", i, test.input) 134 } 135 136 if arg.Kind() == reflect.Int && arg.Int() != expected.Int() { 137 t.Errorf("expected int(%d), got int(%d) in %s", expected.Int(), arg.Int(), test.input) 138 } 139 140 if arg.Kind() == reflect.String && arg.String() != expected.String() { 141 t.Errorf("expected string(%s), got string(%s) in %s", expected.String(), arg.String(), test.input) 142 } 143 } 144 } 145 146 var invalidTests = []struct { 147 input string 148 argTypes []reflect.Type 149 }{ 150 {`[]`, []reflect.Type{intT}}, 151 {`[null]`, []reflect.Type{intT}}, 152 {`[1]`, []reflect.Type{stringT}}, 153 {`[1,2]`, []reflect.Type{stringT}}, 154 {`["abc", null]`, []reflect.Type{stringT, intT}}, 155 } 156 157 for i, test := range invalidTests { 158 if _, err := codec.ParseRequestArguments(test.argTypes, test.input); err == nil { 159 t.Errorf("expected test %d - %s to fail", i, test.input) 160 } 161 } 162 }