github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/rpc/json_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package rpc
    26  
    27  import (
    28  	"bufio"
    29  	"bytes"
    30  	"encoding/json"
    31  	"reflect"
    32  	"strconv"
    33  	"testing"
    34  )
    35  
    36  type RWC struct {
    37  	*bufio.ReadWriter
    38  }
    39  
    40  func (rwc *RWC) Close() error {
    41  	return nil
    42  }
    43  
    44  func TestJSONRequestParsing(t *testing.T) {
    45  	server := NewServer()
    46  	service := new(Service)
    47  
    48  	if err := server.RegisterName("calc", service); err != nil {
    49  		t.Fatalf("%v", err)
    50  	}
    51  
    52  	req := bytes.NewBufferString(`{"id": 1234, "jsonrpc": "2.0", "method": "calc_add", "params": [11, 22]}`)
    53  	var str string
    54  	reply := bytes.NewBufferString(str)
    55  	rw := &RWC{bufio.NewReadWriter(bufio.NewReader(req), bufio.NewWriter(reply))}
    56  
    57  	codec := NewJSONCodec(rw)
    58  
    59  	requests, batch, err := codec.ReadRequestHeaders()
    60  	if err != nil {
    61  		t.Fatalf("%v", err)
    62  	}
    63  
    64  	if batch {
    65  		t.Fatalf("Request isn't a batch")
    66  	}
    67  
    68  	if len(requests) != 1 {
    69  		t.Fatalf("Expected 1 request but got %d requests - %v", len(requests), requests)
    70  	}
    71  
    72  	if requests[0].service != "calc" {
    73  		t.Fatalf("Expected service 'calc' but got '%s'", requests[0].service)
    74  	}
    75  
    76  	if requests[0].method != "add" {
    77  		t.Fatalf("Expected method 'Add' but got '%s'", requests[0].method)
    78  	}
    79  
    80  	if rawId, ok := requests[0].id.(*json.RawMessage); ok {
    81  		id, e := strconv.ParseInt(string(*rawId), 0, 64)
    82  		if e != nil {
    83  			t.Fatalf("%v", e)
    84  		}
    85  		if id != 1234 {
    86  			t.Fatalf("Expected id 1234 but got %d", id)
    87  		}
    88  	} else {
    89  		t.Fatalf("invalid request, expected *json.RawMesage got %T", requests[0].id)
    90  	}
    91  
    92  	var arg int
    93  	args := []reflect.Type{reflect.TypeOf(arg), reflect.TypeOf(arg)}
    94  
    95  	v, err := codec.ParseRequestArguments(args, requests[0].params)
    96  	if err != nil {
    97  		t.Fatalf("%v", err)
    98  	}
    99  
   100  	if len(v) != 2 {
   101  		t.Fatalf("Expected 2 argument values, got %d", len(v))
   102  	}
   103  
   104  	if v[0].Int() != 11 || v[1].Int() != 22 {
   105  		t.Fatalf("expected %d == 11 && %d == 22", v[0].Int(), v[1].Int())
   106  	}
   107  }
   108  
   109  func TestJSONRequestParamsParsing(t *testing.T) {
   110  
   111  	var (
   112  		stringT = reflect.TypeOf("")
   113  		intT    = reflect.TypeOf(0)
   114  		intPtrT = reflect.TypeOf(new(int))
   115  
   116  		stringV = reflect.ValueOf("abc")
   117  		i       = 1
   118  		intV    = reflect.ValueOf(i)
   119  		intPtrV = reflect.ValueOf(&i)
   120  	)
   121  
   122  	var validTests = []struct {
   123  		input    string
   124  		argTypes []reflect.Type
   125  		expected []reflect.Value
   126  	}{
   127  		{`[]`, []reflect.Type{}, []reflect.Value{}},
   128  		{`[]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}},
   129  		{`[1]`, []reflect.Type{intT}, []reflect.Value{intV}},
   130  		{`[1,"abc"]`, []reflect.Type{intT, stringT}, []reflect.Value{intV, stringV}},
   131  		{`[null]`, []reflect.Type{intPtrT}, []reflect.Value{intPtrV}},
   132  		{`[null,"abc"]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}},
   133  		{`[null,"abc",null]`, []reflect.Type{intPtrT, stringT, intPtrT}, []reflect.Value{intPtrV, stringV, intPtrV}},
   134  	}
   135  
   136  	codec := jsonCodec{}
   137  
   138  	for _, test := range validTests {
   139  		params := (json.RawMessage)([]byte(test.input))
   140  		args, err := codec.ParseRequestArguments(test.argTypes, params)
   141  
   142  		if err != nil {
   143  			t.Fatal(err)
   144  		}
   145  
   146  		var match []interface{}
   147  		json.Unmarshal([]byte(test.input), &match)
   148  
   149  		if len(args) != len(test.argTypes) {
   150  			t.Fatalf("expected %d parsed args, got %d", len(test.argTypes), len(args))
   151  		}
   152  
   153  		for i, arg := range args {
   154  			expected := test.expected[i]
   155  
   156  			if arg.Kind() != expected.Kind() {
   157  				t.Errorf("expected type for param %d in %s", i, test.input)
   158  			}
   159  
   160  			if arg.Kind() == reflect.Int && arg.Int() != expected.Int() {
   161  				t.Errorf("expected int(%d), got int(%d) in %s", expected.Int(), arg.Int(), test.input)
   162  			}
   163  
   164  			if arg.Kind() == reflect.String && arg.String() != expected.String() {
   165  				t.Errorf("expected string(%s), got string(%s) in %s", expected.String(), arg.String(), test.input)
   166  			}
   167  		}
   168  	}
   169  
   170  	var invalidTests = []struct {
   171  		input    string
   172  		argTypes []reflect.Type
   173  	}{
   174  		{`[]`, []reflect.Type{intT}},
   175  		{`[null]`, []reflect.Type{intT}},
   176  		{`[1]`, []reflect.Type{stringT}},
   177  		{`[1,2]`, []reflect.Type{stringT}},
   178  		{`["abc", null]`, []reflect.Type{stringT, intT}},
   179  	}
   180  
   181  	for i, test := range invalidTests {
   182  		if _, err := codec.ParseRequestArguments(test.argTypes, test.input); err == nil {
   183  			t.Errorf("expected test %d - %s to fail", i, test.input)
   184  		}
   185  	}
   186  }