golang.org/x/tools/gopls@v0.15.3/internal/test/integration/options.go (about)

     1  // Copyright 2022 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 integration
     6  
     7  import (
     8  	"golang.org/x/tools/gopls/internal/protocol"
     9  	"golang.org/x/tools/gopls/internal/test/integration/fake"
    10  )
    11  
    12  type runConfig struct {
    13  	editor  fake.EditorConfig
    14  	sandbox fake.SandboxConfig
    15  	modes   Mode
    16  }
    17  
    18  func defaultConfig() runConfig {
    19  	return runConfig{
    20  		editor: fake.EditorConfig{
    21  			Settings: map[string]interface{}{
    22  				// Shorten the diagnostic delay to speed up test execution (else we'd add
    23  				// the default delay to each assertion about diagnostics)
    24  				"diagnosticsDelay": "10ms",
    25  			},
    26  		},
    27  	}
    28  }
    29  
    30  // A RunOption augments the behavior of the test runner.
    31  type RunOption interface {
    32  	set(*runConfig)
    33  }
    34  
    35  type optionSetter func(*runConfig)
    36  
    37  func (f optionSetter) set(opts *runConfig) {
    38  	f(opts)
    39  }
    40  
    41  // ProxyFiles configures a file proxy using the given txtar-encoded string.
    42  func ProxyFiles(txt string) RunOption {
    43  	return optionSetter(func(opts *runConfig) {
    44  		opts.sandbox.ProxyFiles = fake.UnpackTxt(txt)
    45  	})
    46  }
    47  
    48  // Modes configures the execution modes that the test should run in.
    49  //
    50  // By default, modes are configured by the test runner. If this option is set,
    51  // it overrides the set of default modes and the test runs in exactly these
    52  // modes.
    53  func Modes(modes Mode) RunOption {
    54  	return optionSetter(func(opts *runConfig) {
    55  		if opts.modes != 0 {
    56  			panic("modes set more than once")
    57  		}
    58  		opts.modes = modes
    59  	})
    60  }
    61  
    62  // WindowsLineEndings configures the editor to use windows line endings.
    63  func WindowsLineEndings() RunOption {
    64  	return optionSetter(func(opts *runConfig) {
    65  		opts.editor.WindowsLineEndings = true
    66  	})
    67  }
    68  
    69  // ClientName sets the LSP client name.
    70  func ClientName(name string) RunOption {
    71  	return optionSetter(func(opts *runConfig) {
    72  		opts.editor.ClientName = name
    73  	})
    74  }
    75  
    76  // CapabilitiesJSON sets the capabalities json.
    77  func CapabilitiesJSON(capabilities []byte) RunOption {
    78  	return optionSetter(func(opts *runConfig) {
    79  		opts.editor.CapabilitiesJSON = capabilities
    80  	})
    81  }
    82  
    83  // Settings sets user-provided configuration for the LSP server.
    84  //
    85  // As a special case, the env setting must not be provided via Settings: use
    86  // EnvVars instead.
    87  type Settings map[string]interface{}
    88  
    89  func (s Settings) set(opts *runConfig) {
    90  	if opts.editor.Settings == nil {
    91  		opts.editor.Settings = make(map[string]interface{})
    92  	}
    93  	for k, v := range s {
    94  		opts.editor.Settings[k] = v
    95  	}
    96  }
    97  
    98  // WorkspaceFolders configures the workdir-relative workspace folders to send
    99  // to the LSP server. By default the editor sends a single workspace folder
   100  // corresponding to the workdir root. To explicitly configure no workspace
   101  // folders, use WorkspaceFolders with no arguments.
   102  func WorkspaceFolders(relFolders ...string) RunOption {
   103  	if len(relFolders) == 0 {
   104  		// Use an empty non-nil slice to signal explicitly no folders.
   105  		relFolders = []string{}
   106  	}
   107  
   108  	return optionSetter(func(opts *runConfig) {
   109  		opts.editor.WorkspaceFolders = relFolders
   110  	})
   111  }
   112  
   113  // FolderSettings defines per-folder workspace settings, keyed by relative path
   114  // to the folder.
   115  //
   116  // Use in conjunction with WorkspaceFolders to have different settings for
   117  // different folders.
   118  type FolderSettings map[string]Settings
   119  
   120  func (fs FolderSettings) set(opts *runConfig) {
   121  	// Re-use the Settings type, for symmetry, but translate back into maps for
   122  	// the editor config.
   123  	folders := make(map[string]map[string]any)
   124  	for k, v := range fs {
   125  		folders[k] = v
   126  	}
   127  	opts.editor.FolderSettings = folders
   128  }
   129  
   130  // EnvVars sets environment variables for the LSP session. When applying these
   131  // variables to the session, the special string $SANDBOX_WORKDIR is replaced by
   132  // the absolute path to the sandbox working directory.
   133  type EnvVars map[string]string
   134  
   135  func (e EnvVars) set(opts *runConfig) {
   136  	if opts.editor.Env == nil {
   137  		opts.editor.Env = make(map[string]string)
   138  	}
   139  	for k, v := range e {
   140  		opts.editor.Env[k] = v
   141  	}
   142  }
   143  
   144  // InGOPATH configures the workspace working directory to be GOPATH, rather
   145  // than a separate working directory for use with modules.
   146  func InGOPATH() RunOption {
   147  	return optionSetter(func(opts *runConfig) {
   148  		opts.sandbox.InGoPath = true
   149  	})
   150  }
   151  
   152  // MessageResponder configures the editor to respond to
   153  // window/showMessageRequest messages using the provided function.
   154  func MessageResponder(f func(*protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error)) RunOption {
   155  	return optionSetter(func(opts *runConfig) {
   156  		opts.editor.MessageResponder = f
   157  	})
   158  }