github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/rpc/json_test.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package rpc 13 14 import ( 15 "bufio" 16 "bytes" 17 "encoding/json" 18 "reflect" 19 "strconv" 20 "testing" 21 ) 22 23 type RWC struct { 24 *bufio.ReadWriter 25 } 26 27 func (rwc *RWC) Close() error { 28 return nil 29 } 30 31 func TestJSONRequestParsing(t *testing.T) { 32 server := NewServer() 33 service := new(Service) 34 35 if err := server.RegisterName("calc", service); err != nil { 36 t.Fatalf("%v", err) 37 } 38 39 req := bytes.NewBufferString(`{"id": 1234, "jsonrpc": "2.0", "method": "calc_add", "params": [11, 22]}`) 40 var str string 41 reply := bytes.NewBufferString(str) 42 rw := &RWC{bufio.NewReadWriter(bufio.NewReader(req), bufio.NewWriter(reply))} 43 44 codec := NewJSONCodec(rw) 45 46 requests, batch, err := codec.ReadRequestHeaders() 47 if err != nil { 48 t.Fatalf("%v", err) 49 } 50 51 if batch { 52 t.Fatalf("Request isn't a batch") 53 } 54 55 if len(requests) != 1 { 56 t.Fatalf("Expected 1 request but got %d requests - %v", len(requests), requests) 57 } 58 59 if requests[0].service != "calc" { 60 t.Fatalf("Expected service 'calc' but got '%s'", requests[0].service) 61 } 62 63 if requests[0].method != "add" { 64 t.Fatalf("Expected method 'Add' but got '%s'", requests[0].method) 65 } 66 67 if rawId, ok := requests[0].id.(*json.RawMessage); ok { 68 id, e := strconv.ParseInt(string(*rawId), 0, 64) 69 if e != nil { 70 t.Fatalf("%v", e) 71 } 72 if id != 1234 { 73 t.Fatalf("Expected id 1234 but got %d", id) 74 } 75 } else { 76 t.Fatalf("invalid request, expected *json.RawMesage got %T", requests[0].id) 77 } 78 79 var arg int 80 args := []reflect.Type{reflect.TypeOf(arg), reflect.TypeOf(arg)} 81 82 v, err := codec.ParseRequestArguments(args, requests[0].params) 83 if err != nil { 84 t.Fatalf("%v", err) 85 } 86 87 if len(v) != 2 { 88 t.Fatalf("Expected 2 argument values, got %d", len(v)) 89 } 90 91 if v[0].Int() != 11 || v[1].Int() != 22 { 92 t.Fatalf("expected %d == 11 && %d == 22", v[0].Int(), v[1].Int()) 93 } 94 } 95 96 func TestJSONRequestParamsParsing(t *testing.T) { 97 98 var ( 99 stringT = reflect.TypeOf("") 100 intT = reflect.TypeOf(0) 101 intPtrT = reflect.TypeOf(new(int)) 102 103 stringV = reflect.ValueOf("abc") 104 i = 1 105 intV = reflect.ValueOf(i) 106 intPtrV = reflect.ValueOf(&i) 107 ) 108 109 var validTests = []struct { 110 input string 111 argTypes []reflect.Type 112 expected []reflect.Value 113 }{ 114 {`[]`, []reflect.Type{}, []reflect.Value{}}, 115 {`[]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}}, 116 {`[1]`, []reflect.Type{intT}, []reflect.Value{intV}}, 117 {`[1,"abc"]`, []reflect.Type{intT, stringT}, []reflect.Value{intV, stringV}}, 118 {`[null]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}}, 119 {`[null,"abc"]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}}, 120 {`[null,"abc",null]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}}, 121 } 122 123 codec := jsonCodec{} 124 125 for _, test := range validTests { 126 params := (json.RawMessage)([]byte(test.input)) 127 args, err := codec.ParseRequestArguments(test.argTypes, params) 128 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 var match []interface{} 134 json.Unmarshal([]byte(test.input), &match) 135 136 if len(args) != len(test.argTypes) { 137 t.Fatalf("expected %d parsed args, got %d", len(test.argTypes), len(args)) 138 } 139 140 for i, arg := range args { 141 expected := test.expected[i] 142 143 if arg.Kind() != expected.Kind() { 144 t.Errorf("expected type for param %d in %s", i, test.input) 145 } 146 147 if arg.Kind() == reflect.Int && arg.Int() != expected.Int() { 148 t.Errorf("expected int(%d), got int(%d) in %s", expected.Int(), arg.Int(), test.input) 149 } 150 151 if arg.Kind() == reflect.String && arg.String() != expected.String() { 152 t.Errorf("expected string(%s), got string(%s) in %s", expected.String(), arg.String(), test.input) 153 } 154 } 155 } 156 157 var invalidTests = []struct { 158 input string 159 argTypes []reflect.Type 160 }{ 161 {`[]`, []reflect.Type{intT}}, 162 {`[null]`, []reflect.Type{intT}}, 163 {`[1]`, []reflect.Type{stringT}}, 164 {`[1,2]`, []reflect.Type{stringT}}, 165 {`["abc", null]`, []reflect.Type{stringT, intT}}, 166 } 167 168 for i, test := range invalidTests { 169 if _, err := codec.ParseRequestArguments(test.argTypes, test.input); err == nil { 170 t.Errorf("expected test %d - %s to fail", i, test.input) 171 } 172 } 173 }