Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / internal / jsonrpc2 / servertest / servertest.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/jsonrpc2/servertest/servertest.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/jsonrpc2/servertest/servertest.go
new file mode 100644 (file)
index 0000000..392e084
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package servertest provides utilities for running tests against a remote LSP
+// server.
+package servertest
+
+import (
+       "context"
+       "fmt"
+       "net"
+       "strings"
+       "sync"
+
+       "golang.org/x/tools/internal/jsonrpc2"
+)
+
+// Connector is the interface used to connect to a server.
+type Connector interface {
+       Connect(context.Context) jsonrpc2.Conn
+}
+
+// TCPServer is a helper for executing tests against a remote jsonrpc2
+// connection. Once initialized, its Addr field may be used to connect a
+// jsonrpc2 client.
+type TCPServer struct {
+       *connList
+
+       Addr string
+
+       ln     net.Listener
+       framer jsonrpc2.Framer
+}
+
+// NewTCPServer returns a new test server listening on local tcp port and
+// serving incoming jsonrpc2 streams using the provided stream server. It
+// panics on any error.
+func NewTCPServer(ctx context.Context, server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *TCPServer {
+       ln, err := net.Listen("tcp", "127.0.0.1:0")
+       if err != nil {
+               panic(fmt.Sprintf("servertest: failed to listen: %v", err))
+       }
+       if framer == nil {
+               framer = jsonrpc2.NewHeaderStream
+       }
+       go jsonrpc2.Serve(ctx, ln, server, 0)
+       return &TCPServer{Addr: ln.Addr().String(), ln: ln, framer: framer, connList: &connList{}}
+}
+
+// Connect dials the test server and returns a jsonrpc2 Connection that is
+// ready for use.
+func (s *TCPServer) Connect(ctx context.Context) jsonrpc2.Conn {
+       netConn, err := net.Dial("tcp", s.Addr)
+       if err != nil {
+               panic(fmt.Sprintf("servertest: failed to connect to test instance: %v", err))
+       }
+       conn := jsonrpc2.NewConn(s.framer(netConn))
+       s.add(conn)
+       return conn
+}
+
+// PipeServer is a test server that handles connections over io.Pipes.
+type PipeServer struct {
+       *connList
+       server jsonrpc2.StreamServer
+       framer jsonrpc2.Framer
+}
+
+// NewPipeServer returns a test server that can be connected to via io.Pipes.
+func NewPipeServer(ctx context.Context, server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *PipeServer {
+       if framer == nil {
+               framer = jsonrpc2.NewRawStream
+       }
+       return &PipeServer{server: server, framer: framer, connList: &connList{}}
+}
+
+// Connect creates new io.Pipes and binds them to the underlying StreamServer.
+func (s *PipeServer) Connect(ctx context.Context) jsonrpc2.Conn {
+       sPipe, cPipe := net.Pipe()
+       serverStream := s.framer(sPipe)
+       serverConn := jsonrpc2.NewConn(serverStream)
+       s.add(serverConn)
+       go s.server.ServeStream(ctx, serverConn)
+
+       clientStream := s.framer(cPipe)
+       clientConn := jsonrpc2.NewConn(clientStream)
+       s.add(clientConn)
+       return clientConn
+}
+
+// connList tracks closers to run when a testserver is closed.  This is a
+// convenience, so that callers don't have to worry about closing each
+// connection.
+type connList struct {
+       mu    sync.Mutex
+       conns []jsonrpc2.Conn
+}
+
+func (l *connList) add(conn jsonrpc2.Conn) {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       l.conns = append(l.conns, conn)
+}
+
+func (l *connList) Close() error {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       var errmsgs []string
+       for _, conn := range l.conns {
+               if err := conn.Close(); err != nil {
+                       errmsgs = append(errmsgs, err.Error())
+               }
+       }
+       if len(errmsgs) > 0 {
+               return fmt.Errorf("closing errors:\n%s", strings.Join(errmsgs, "\n"))
+       }
+       return nil
+}