-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
Copy pathoptions.go
222 lines (193 loc) · 6.29 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright 2022 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 integration
import (
"strings"
"testing"
"time"
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/test/integration/fake"
"golang.org/x/tools/internal/drivertest"
)
type runConfig struct {
editor fake.EditorConfig
sandbox fake.SandboxConfig
modes Mode
noLogsOnError bool
writeGoSum []string
}
func defaultConfig() runConfig {
return runConfig{
editor: fake.EditorConfig{
Settings: map[string]any{
// Shorten the diagnostic delay to speed up test execution (else we'd add
// the default delay to each assertion about diagnostics)
"diagnosticsDelay": "10ms",
},
},
}
}
// A RunOption augments the behavior of the test runner.
type RunOption interface {
set(*runConfig)
}
type optionSetter func(*runConfig)
func (f optionSetter) set(opts *runConfig) {
f(opts)
}
// ProxyFiles configures a file proxy using the given txtar-encoded string.
func ProxyFiles(txt string) RunOption {
return optionSetter(func(opts *runConfig) {
opts.sandbox.ProxyFiles = fake.UnpackTxt(txt)
})
}
// WriteGoSum causes the environment to write a go.sum file for the requested
// relative directories (via `go list -mod=mod`), before starting gopls.
//
// Useful for tests that use ProxyFiles, but don't care about crafting the
// go.sum content.
func WriteGoSum(dirs ...string) RunOption {
return optionSetter(func(opts *runConfig) {
opts.writeGoSum = dirs
})
}
// Modes configures the execution modes that the test should run in.
//
// By default, modes are configured by the test runner. If this option is set,
// it overrides the set of default modes and the test runs in exactly these
// modes.
func Modes(modes Mode) RunOption {
return optionSetter(func(opts *runConfig) {
if opts.modes != 0 {
panic("modes set more than once")
}
opts.modes = modes
})
}
// NoLogsOnError turns off dumping the LSP logs on test failures.
func NoLogsOnError() RunOption {
return optionSetter(func(opts *runConfig) {
opts.noLogsOnError = true
})
}
// WindowsLineEndings configures the editor to use windows line endings.
func WindowsLineEndings() RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.WindowsLineEndings = true
})
}
// ClientName sets the LSP client name.
func ClientName(name string) RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.ClientName = name
})
}
// CapabilitiesJSON sets the capabalities json.
func CapabilitiesJSON(capabilities []byte) RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.CapabilitiesJSON = capabilities
})
}
// Settings sets user-provided configuration for the LSP server.
//
// As a special case, the env setting must not be provided via Settings: use
// EnvVars instead.
type Settings map[string]any
func (s Settings) set(opts *runConfig) {
if opts.editor.Settings == nil {
opts.editor.Settings = make(map[string]any)
}
for k, v := range s {
opts.editor.Settings[k] = v
}
}
// WorkspaceFolders configures the workdir-relative workspace folders or uri
// to send to the LSP server. By default the editor sends a single workspace folder
// corresponding to the workdir root. To explicitly configure no workspace
// folders, use WorkspaceFolders with no arguments.
func WorkspaceFolders(relFolders ...string) RunOption {
if len(relFolders) == 0 {
// Use an empty non-nil slice to signal explicitly no folders.
relFolders = []string{}
}
return optionSetter(func(opts *runConfig) {
opts.editor.WorkspaceFolders = relFolders
})
}
// NoDefaultWorkspaceFiles is used to specify whether the fake editor
// should give a default workspace folder to the LSP server.
// When it's true, the editor will pass original WorkspaceFolders to the LSP server.
func NoDefaultWorkspaceFiles() RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.NoDefaultWorkspaceFiles = true
})
}
// RootPath configures the roo path which will be converted to rootUri and sent to the LSP server.
func RootPath(relpath string) RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.RelRootPath = relpath
})
}
// FolderSettings defines per-folder workspace settings, keyed by relative path
// to the folder.
//
// Use in conjunction with WorkspaceFolders to have different settings for
// different folders.
type FolderSettings map[string]Settings
func (fs FolderSettings) set(opts *runConfig) {
// Re-use the Settings type, for symmetry, but translate back into maps for
// the editor config.
folders := make(map[string]map[string]any)
for k, v := range fs {
folders[k] = v
}
opts.editor.FolderSettings = folders
}
// EnvVars sets environment variables for the LSP session. When applying these
// variables to the session, the special string $SANDBOX_WORKDIR is replaced by
// the absolute path to the sandbox working directory.
type EnvVars map[string]string
func (e EnvVars) set(opts *runConfig) {
if opts.editor.Env == nil {
opts.editor.Env = make(map[string]string)
}
for k, v := range e {
opts.editor.Env[k] = v
}
}
// FakeGoPackagesDriver configures gopls to run with a fake GOPACKAGESDRIVER
// environment variable.
func FakeGoPackagesDriver(t *testing.T) RunOption {
env := drivertest.Env(t)
vars := make(EnvVars)
for _, e := range env {
kv := strings.SplitN(e, "=", 2)
vars[kv[0]] = kv[1]
}
return vars
}
// InGOPATH configures the workspace working directory to be GOPATH, rather
// than a separate working directory for use with modules.
func InGOPATH() RunOption {
return optionSetter(func(opts *runConfig) {
opts.sandbox.InGoPath = true
})
}
// MessageResponder configures the editor to respond to
// window/showMessageRequest messages using the provided function.
func MessageResponder(f func(*protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error)) RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.MessageResponder = f
})
}
// DelayMessages can be used to fuzz message delivery delays for the purpose of
// reproducing test flakes.
//
// (Even though this option may be unused, keep it around to aid in debugging
// future flakes.)
func DelayMessages(upto time.Duration) RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.MaxMessageDelay = upto
})
}