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  }