implement multi select support for prompter

This commit is contained in:
nate smith 2023-04-10 17:37:36 -07:00
parent 6fd17ec2d2
commit d4a8d15a8a
3 changed files with 42 additions and 31 deletions

View file

@ -13,7 +13,7 @@ import (
//go:generate moq -rm -out prompter_mock.go . Prompter
type Prompter interface {
Select(string, string, []string) (int, error)
MultiSelect(string, string, []string) ([]string, error)
MultiSelect(string, []string, []string) ([]string, error)
Input(string, string) (string, error)
InputHostname() (string, error)
Password(string) (string, error)
@ -72,15 +72,26 @@ func (p *surveyPrompter) Select(message, defaultValue string, options []string)
return
}
func (p *surveyPrompter) MultiSelect(message, defaultValue string, options []string) (result []string, err error) {
func (p *surveyPrompter) MultiSelect(message string, defaultValue, options []string) (result []string, err error) {
q := &survey.MultiSelect{
Message: message,
Options: options,
PageSize: 20,
}
if defaultValue != "" {
q.Default = defaultValue
// TODO will I regret this returning []string and not []int?
if defaultValue != nil && len(defaultValue) > 0 {
// TODO I don't actually know that this is needed, just being extra cautious
validatedDefault := []string{}
for _, x := range defaultValue {
for _, y := range options {
if x == y {
validatedDefault = append(validatedDefault, x)
}
}
}
q.Default = validatedDefault
}
err = p.ask(q, &result)

View file

@ -35,7 +35,7 @@ var _ Prompter = &PrompterMock{}
// MarkdownEditorFunc: func(s1 string, s2 string, b bool) (string, error) {
// panic("mock out the MarkdownEditor method")
// },
// MultiSelectFunc: func(s1 string, s2 string, strings []string) ([]string, error) {
// MultiSelectFunc: func(s string, strings1 []string, strings2 []string) ([]string, error) {
// panic("mock out the MultiSelect method")
// },
// PasswordFunc: func(s string) (string, error) {
@ -70,7 +70,7 @@ type PrompterMock struct {
MarkdownEditorFunc func(s1 string, s2 string, b bool) (string, error)
// MultiSelectFunc mocks the MultiSelect method.
MultiSelectFunc func(s1 string, s2 string, strings []string) ([]string, error)
MultiSelectFunc func(s string, strings1 []string, strings2 []string) ([]string, error)
// PasswordFunc mocks the Password method.
PasswordFunc func(s string) (string, error)
@ -116,12 +116,12 @@ type PrompterMock struct {
}
// MultiSelect holds details about calls to the MultiSelect method.
MultiSelect []struct {
// S1 is the s1 argument value.
S1 string
// S2 is the s2 argument value.
S2 string
// Strings is the strings argument value.
Strings []string
// S is the s argument value.
S string
// Strings1 is the strings1 argument value.
Strings1 []string
// Strings2 is the strings2 argument value.
Strings2 []string
}
// Password holds details about calls to the Password method.
Password []struct {
@ -348,23 +348,23 @@ func (mock *PrompterMock) MarkdownEditorCalls() []struct {
}
// MultiSelect calls MultiSelectFunc.
func (mock *PrompterMock) MultiSelect(s1 string, s2 string, strings []string) ([]string, error) {
func (mock *PrompterMock) MultiSelect(s string, strings1 []string, strings2 []string) ([]string, error) {
if mock.MultiSelectFunc == nil {
panic("PrompterMock.MultiSelectFunc: method is nil but Prompter.MultiSelect was just called")
}
callInfo := struct {
S1 string
S2 string
Strings []string
S string
Strings1 []string
Strings2 []string
}{
S1: s1,
S2: s2,
Strings: strings,
S: s,
Strings1: strings1,
Strings2: strings2,
}
mock.lockMultiSelect.Lock()
mock.calls.MultiSelect = append(mock.calls.MultiSelect, callInfo)
mock.lockMultiSelect.Unlock()
return mock.MultiSelectFunc(s1, s2, strings)
return mock.MultiSelectFunc(s, strings1, strings2)
}
// MultiSelectCalls gets all the calls that were made to MultiSelect.
@ -372,14 +372,14 @@ func (mock *PrompterMock) MultiSelect(s1 string, s2 string, strings []string) ([
//
// len(mockedPrompter.MultiSelectCalls())
func (mock *PrompterMock) MultiSelectCalls() []struct {
S1 string
S2 string
Strings []string
S string
Strings1 []string
Strings2 []string
} {
var calls []struct {
S1 string
S2 string
Strings []string
S string
Strings1 []string
Strings2 []string
}
mock.lockMultiSelect.RLock()
calls = mock.calls.MultiSelect

View file

@ -50,7 +50,7 @@ type ConfirmStub struct {
type MultiSelectStub struct {
Prompt string
ExpectedOpts []string
Fn func(string, string, []string) ([]string, error)
Fn func(string, []string, []string) ([]string, error)
}
type InputHostnameStub struct {
@ -120,11 +120,11 @@ func NewMockPrompter(t *testing.T) *MockPrompter {
return s.Fn(p, d, opts)
}
m.MultiSelectFunc = func(p, d string, opts []string) ([]string, error) {
m.MultiSelectFunc = func(p string, d, opts []string) ([]string, error) {
var s MultiSelectStub
if len(m.SelectStubs) > 0 {
if len(m.MultiSelectStubs) > 0 {
s = m.MultiSelectStubs[0]
m.SelectStubs = m.SelectStubs[1:len(m.SelectStubs)]
m.MultiSelectStubs = m.MultiSelectStubs[1:len(m.MultiSelectStubs)]
} else {
return []string{}, NoSuchPromptErr(p)
}
@ -240,7 +240,7 @@ func (m *MockPrompter) RegisterSelect(prompt string, opts []string, stub func(_,
Fn: stub})
}
func (m *MockPrompter) RegisterMultiSelect(prompt string, opts []string, stub func(_, _ string, _ []string) ([]string, error)) {
func (m *MockPrompter) RegisterMultiSelect(prompt string, d, opts []string, stub func(_ string, _, _ []string) ([]string, error)) {
m.MultiSelectStubs = append(m.MultiSelectStubs, MultiSelectStub{
Prompt: prompt,
ExpectedOpts: opts,