From d4a8d15a8a3ed15e5e3eb417273c5b401013e320 Mon Sep 17 00:00:00 2001 From: nate smith Date: Mon, 10 Apr 2023 17:37:36 -0700 Subject: [PATCH] implement multi select support for prompter --- internal/prompter/prompter.go | 19 ++++++++++--- internal/prompter/prompter_mock.go | 44 +++++++++++++++--------------- internal/prompter/test.go | 10 +++---- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/internal/prompter/prompter.go b/internal/prompter/prompter.go index a9cf77992..60c223cff 100644 --- a/internal/prompter/prompter.go +++ b/internal/prompter/prompter.go @@ -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) diff --git a/internal/prompter/prompter_mock.go b/internal/prompter/prompter_mock.go index 859832450..174375bfd 100644 --- a/internal/prompter/prompter_mock.go +++ b/internal/prompter/prompter_mock.go @@ -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 diff --git a/internal/prompter/test.go b/internal/prompter/test.go index a2d0b83ee..a5cebacda 100644 --- a/internal/prompter/test.go +++ b/internal/prompter/test.go @@ -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,