.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / internal / lsp / cmd / test / cmdtest.go
1 // Copyright 2019 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
5 // Package cmdtest contains the test suite for the command line behavior of gopls.
6 package cmdtest
7
8 import (
9         "bytes"
10         "context"
11         "fmt"
12         "io"
13         "os"
14         "sync"
15         "testing"
16
17         "golang.org/x/tools/internal/jsonrpc2/servertest"
18         "golang.org/x/tools/internal/lsp/cache"
19         "golang.org/x/tools/internal/lsp/cmd"
20         "golang.org/x/tools/internal/lsp/debug"
21         "golang.org/x/tools/internal/lsp/lsprpc"
22         "golang.org/x/tools/internal/lsp/protocol"
23         "golang.org/x/tools/internal/lsp/source"
24         "golang.org/x/tools/internal/lsp/tests"
25         "golang.org/x/tools/internal/span"
26         "golang.org/x/tools/internal/tool"
27 )
28
29 type runner struct {
30         data        *tests.Data
31         ctx         context.Context
32         options     func(*source.Options)
33         normalizers []tests.Normalizer
34         remote      string
35 }
36
37 func TestCommandLine(t *testing.T, testdata string, options func(*source.Options)) {
38         // On Android, the testdata directory is not copied to the runner.
39         if stat, err := os.Stat(testdata); err != nil || !stat.IsDir() {
40                 t.Skip("testdata directory not present")
41         }
42         tests.RunTests(t, testdata, false, func(t *testing.T, datum *tests.Data) {
43                 ctx := tests.Context(t)
44                 ts := NewTestServer(ctx, options)
45                 tests.Run(t, NewRunner(datum, ctx, ts.Addr, options), datum)
46                 cmd.CloseTestConnections(ctx)
47         })
48 }
49
50 func NewTestServer(ctx context.Context, options func(*source.Options)) *servertest.TCPServer {
51         ctx = debug.WithInstance(ctx, "", "")
52         cache := cache.New(ctx, options)
53         ss := lsprpc.NewStreamServer(cache, false)
54         return servertest.NewTCPServer(ctx, ss, nil)
55 }
56
57 func NewRunner(data *tests.Data, ctx context.Context, remote string, options func(*source.Options)) *runner {
58         return &runner{
59                 data:        data,
60                 ctx:         ctx,
61                 options:     options,
62                 normalizers: tests.CollectNormalizers(data.Exported),
63                 remote:      remote,
64         }
65 }
66
67 func (r *runner) CodeLens(t *testing.T, uri span.URI, want []protocol.CodeLens) {
68         //TODO: add command line completions tests when it works
69 }
70
71 func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
72         //TODO: add command line completions tests when it works
73 }
74
75 func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
76         //TODO: add command line completions tests when it works
77 }
78
79 func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
80         //TODO: add command line completions tests when it works
81 }
82
83 func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
84         //TODO: add command line completions tests when it works
85 }
86
87 func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
88         //TODO: add command line completions tests when it works
89 }
90
91 func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
92         //TODO: add command line completions tests when it works
93 }
94
95 func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
96         //TODO: add command line completions tests when it works
97 }
98
99 func (r *runner) FunctionExtraction(t *testing.T, start span.Span, end span.Span) {
100         //TODO: function extraction not supported on command line
101 }
102
103 func (r *runner) runGoplsCmd(t testing.TB, args ...string) (string, string) {
104         rStdout, wStdout, err := os.Pipe()
105         if err != nil {
106                 t.Fatal(err)
107         }
108         oldStdout := os.Stdout
109         rStderr, wStderr, err := os.Pipe()
110         if err != nil {
111                 t.Fatal(err)
112         }
113         oldStderr := os.Stderr
114         stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
115         var wg sync.WaitGroup
116         wg.Add(2)
117         go func() {
118                 io.Copy(stdout, rStdout)
119                 wg.Done()
120         }()
121         go func() {
122                 io.Copy(stderr, rStderr)
123                 wg.Done()
124         }()
125         os.Stdout, os.Stderr = wStdout, wStderr
126         app := cmd.New("gopls-test", r.data.Config.Dir, r.data.Exported.Config.Env, r.options)
127         remote := r.remote
128         err = tool.Run(tests.Context(t),
129                 app,
130                 append([]string{fmt.Sprintf("-remote=internal@%s", remote)}, args...))
131         if err != nil {
132                 fmt.Fprint(os.Stderr, err)
133         }
134         wStdout.Close()
135         wStderr.Close()
136         wg.Wait()
137         os.Stdout, os.Stderr = oldStdout, oldStderr
138         rStdout.Close()
139         rStderr.Close()
140         return stdout.String(), stderr.String()
141 }
142
143 // NormalizeGoplsCmd runs the gopls command and normalizes its output.
144 func (r *runner) NormalizeGoplsCmd(t testing.TB, args ...string) (string, string) {
145         stdout, stderr := r.runGoplsCmd(t, args...)
146         return r.Normalize(stdout), r.Normalize(stderr)
147 }
148
149 func (r *runner) Normalize(s string) string {
150         return tests.Normalize(s, r.normalizers)
151 }
152
153 func (r *runner) NormalizePrefix(s string) string {
154         return tests.NormalizePrefix(s, r.normalizers)
155 }