GoPLS Viewer

Home|gopls/internal/jsonrpc2/jsonrpc2_test.go
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package jsonrpc2_test
6
7import (
8    "context"
9    "encoding/json"
10    "flag"
11    "fmt"
12    "net"
13    "path"
14    "reflect"
15    "testing"
16
17    "golang.org/x/tools/internal/event/export/eventtest"
18    "golang.org/x/tools/internal/jsonrpc2"
19    "golang.org/x/tools/internal/stack/stacktest"
20)
21
22var logRPC = flag.Bool("logrpc"false"Enable jsonrpc2 communication logging")
23
24type callTest struct {
25    method string
26    params interface{}
27    expect interface{}
28}
29
30var callTests = []callTest{
31    {"no_args"niltrue},
32    {"one_string""fish""got:fish"},
33    {"one_number"10"got:10"},
34    {"join", []string{"a""b""c"}, "a/b/c"},
35    //TODO: expand the test cases
36}
37
38func (test *callTestnewResults() interface{} {
39    switch e := test.expect.(type) {
40    case []interface{}:
41        var r []interface{}
42        for _v := range e {
43            r = append(rreflect.New(reflect.TypeOf(v)).Interface())
44        }
45        return r
46    case nil:
47        return nil
48    default:
49        return reflect.New(reflect.TypeOf(test.expect)).Interface()
50    }
51}
52
53func (test *callTestverifyResults(t *testing.Tresults interface{}) {
54    if results == nil {
55        return
56    }
57    val := reflect.Indirect(reflect.ValueOf(results)).Interface()
58    if !reflect.DeepEqual(valtest.expect) {
59        t.Errorf("%v:Results are incorrect, got %+v expect %+v"test.methodvaltest.expect)
60    }
61}
62
63func TestCall(t *testing.T) {
64    stacktest.NoLeak(t)
65    ctx := eventtest.NewContext(context.Background(), t)
66    for _headers := range []bool{falsetrue} {
67        name := "Plain"
68        if headers {
69            name = "Headers"
70        }
71        t.Run(name, func(t *testing.T) {
72            ctx := eventtest.NewContext(ctxt)
73            abdone := prepare(ctxtheaders)
74            defer done()
75            for _test := range callTests {
76                t.Run(test.method, func(t *testing.T) {
77                    ctx := eventtest.NewContext(ctxt)
78                    results := test.newResults()
79                    if _err := a.Call(ctxtest.methodtest.paramsresults); err != nil {
80                        t.Fatalf("%v:Call failed: %v"test.methoderr)
81                    }
82                    test.verifyResults(tresults)
83                    if _err := b.Call(ctxtest.methodtest.paramsresults); err != nil {
84                        t.Fatalf("%v:Call failed: %v"test.methoderr)
85                    }
86                    test.verifyResults(tresults)
87                })
88            }
89        })
90    }
91}
92
93func prepare(ctx context.Contextt *testing.TwithHeaders bool) (jsonrpc2.Connjsonrpc2.Conn, func()) {
94    // make a wait group that can be used to wait for the system to shut down
95    aPipebPipe := net.Pipe()
96    a := run(ctxwithHeadersaPipe)
97    b := run(ctxwithHeadersbPipe)
98    return ab, func() {
99        a.Close()
100        b.Close()
101        <-a.Done()
102        <-b.Done()
103    }
104}
105
106func run(ctx context.ContextwithHeaders boolnc net.Connjsonrpc2.Conn {
107    var stream jsonrpc2.Stream
108    if withHeaders {
109        stream = jsonrpc2.NewHeaderStream(nc)
110    } else {
111        stream = jsonrpc2.NewRawStream(nc)
112    }
113    conn := jsonrpc2.NewConn(stream)
114    conn.Go(ctxtestHandler(*logRPC))
115    return conn
116}
117
118func testHandler(log booljsonrpc2.Handler {
119    return func(ctx context.Contextreply jsonrpc2.Replierreq jsonrpc2.Requesterror {
120        switch req.Method() {
121        case "no_args":
122            if len(req.Params()) > 0 {
123                return reply(ctxnilfmt.Errorf("%w: expected no params"jsonrpc2.ErrInvalidParams))
124            }
125            return reply(ctxtruenil)
126        case "one_string":
127            var v string
128            if err := json.Unmarshal(req.Params(), &v); err != nil {
129                return reply(ctxnilfmt.Errorf("%w: %s"jsonrpc2.ErrParseerr))
130            }
131            return reply(ctx"got:"+vnil)
132        case "one_number":
133            var v int
134            if err := json.Unmarshal(req.Params(), &v); err != nil {
135                return reply(ctxnilfmt.Errorf("%w: %s"jsonrpc2.ErrParseerr))
136            }
137            return reply(ctxfmt.Sprintf("got:%d"v), nil)
138        case "join":
139            var v []string
140            if err := json.Unmarshal(req.Params(), &v); err != nil {
141                return reply(ctxnilfmt.Errorf("%w: %s"jsonrpc2.ErrParseerr))
142            }
143            return reply(ctxpath.Join(v...), nil)
144        default:
145            return jsonrpc2.MethodNotFound(ctxreplyreq)
146        }
147    }
148}
149
MembersX
callTest.newResults.BlockStmt.RangeStmt_909.v
TestCall.RangeStmt_1523.BlockStmt.name
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.b
prepare
prepare.bPipe
callTest.method
callTest.verifyResults.val
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.RangeStmt_1761.test
prepare.ctx
testHandler.BlockStmt.BlockStmt.v
callTest.params
jsonrpc2
callTest.expect
callTest.verifyResults.results
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.done
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.RangeStmt_1761.BlockStmt.BlockStmt.ctx
prepare.b
testHandler.log
path
eventtest
stacktest
callTest
callTest.verifyResults.test
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.a
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.RangeStmt_1761.BlockStmt.BlockStmt._
prepare.withHeaders
flag
run.conn
testHandler
prepare.t
testing
callTest.newResults.test
callTest.newResults
callTest.verifyResults.t
TestCall.t
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.RangeStmt_1761.BlockStmt.BlockStmt.err
prepare.aPipe
net
run.ctx
run.nc
prepare.a
callTest.verifyResults
TestCall.RangeStmt_1523.headers
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.ctx
TestCall.RangeStmt_1523.BlockStmt.BlockStmt.RangeStmt_1761.BlockStmt.BlockStmt.results
run
reflect
TestCall.ctx
run.withHeaders
run.stream
testHandler.BlockStmt.BlockStmt.err
TestCall
Members
X