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