diff --git a/pkg/cmd/gist/edit/edit.go b/pkg/cmd/gist/edit/edit.go index bbe62d80b..3ad28b6c4 100644 --- a/pkg/cmd/gist/edit/edit.go +++ b/pkg/cmd/gist/edit/edit.go @@ -12,21 +12,23 @@ import ( "sort" "strings" - "github.com/AlecAivazis/survey/v2" "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/config" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/gist/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/prompt" "github.com/cli/cli/v2/pkg/surveyext" "github.com/spf13/cobra" ) +var editNextOptions = []string{"Edit another file", "Submit", "Cancel"} + type EditOptions struct { IO *iostreams.IOStreams HttpClient func() (*http.Client, error) Config func() (config.Config, error) + Prompter prompter.Prompter Edit func(string, string, string, *iostreams.IOStreams) (string, error) @@ -42,6 +44,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman IO: f.IOStreams, HttpClient: f.HttpClient, Config: f.Config, + Prompter: f.Prompter, Edit: func(editorCmd, filename, defaultContent string, io *iostreams.IOStreams) (string, error) { return surveyext.Edit( editorCmd, @@ -100,7 +103,7 @@ func editRun(opts *EditOptions) error { if gistID == "" { cs := opts.IO.ColorScheme() if gistID == "" { - gistID, err = shared.PromptGists(client, host, cs) + gistID, err = shared.PromptGists(opts.Prompter, client, host, cs) if err != nil { return err } @@ -202,15 +205,11 @@ func editRun(opts *EditOptions) error { if !opts.IO.CanPrompt() { return errors.New("unsure what file to edit; either specify --filename or run interactively") } - //nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter - err = prompt.SurveyAskOne(&survey.Select{ - Message: "Edit which file?", - Options: candidates, - }, &filename) - + result, err := opts.Prompter.Select("Edit which file?", "", candidates) if err != nil { return fmt.Errorf("could not prompt: %w", err) } + filename = candidates[result] } } @@ -262,20 +261,11 @@ func editRun(opts *EditOptions) error { } choice := "" - - //nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter - err = prompt.SurveyAskOne(&survey.Select{ - Message: "What next?", - Options: []string{ - "Edit another file", - "Submit", - "Cancel", - }, - }, &choice) - + result, err := opts.Prompter.Select("What next?", "", editNextOptions) if err != nil { return fmt.Errorf("could not prompt: %w", err) } + choice = editNextOptions[result] stop := false diff --git a/pkg/cmd/gist/edit/edit_test.go b/pkg/cmd/gist/edit/edit_test.go index 33223ddee..5e52a8ffb 100644 --- a/pkg/cmd/gist/edit/edit_test.go +++ b/pkg/cmd/gist/edit/edit_test.go @@ -10,11 +10,11 @@ import ( "testing" "github.com/cli/cli/v2/internal/config" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/gist/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/prompt" "github.com/google/shlex" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -115,15 +115,15 @@ func Test_editRun(t *testing.T) { require.NoError(t, err) tests := []struct { - name string - opts *EditOptions - gist *shared.Gist - httpStubs func(*httpmock.Registry) - askStubs func(*prompt.AskStubber) - nontty bool - stdin string - wantErr string - wantParams map[string]interface{} + name string + opts *EditOptions + gist *shared.Gist + httpStubs func(*httpmock.Registry) + prompterStubs func(*prompter.MockPrompter) + nontty bool + stdin string + wantErr string + wantParams map[string]interface{} }{ { name: "no such gist", @@ -161,9 +161,17 @@ func Test_editRun(t *testing.T) { }, { name: "multiple files, submit", - askStubs: func(as *prompt.AskStubber) { - as.StubPrompt("Edit which file?").AnswerWith("unix.md") - as.StubPrompt("What next?").AnswerWith("Submit") + prompterStubs: func(pm *prompter.MockPrompter) { + pm.RegisterSelect("Edit which file?", + []string{"cicada.txt", "unix.md"}, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "unix.md") + }) + pm.RegisterSelect("What next?", + editNextOptions, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "Submit") + }) }, gist: &shared.Gist{ ID: "1234", @@ -206,9 +214,17 @@ func Test_editRun(t *testing.T) { }, { name: "multiple files, cancel", - askStubs: func(as *prompt.AskStubber) { - as.StubPrompt("Edit which file?").AnswerWith("unix.md") - as.StubPrompt("What next?").AnswerWith("Cancel") + prompterStubs: func(pm *prompter.MockPrompter) { + pm.RegisterSelect("Edit which file?", + []string{"cicada.txt", "unix.md"}, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "unix.md") + }) + pm.RegisterSelect("What next?", + editNextOptions, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "Cancel") + }) }, wantErr: "CancelError", gist: &shared.Gist{ @@ -486,11 +502,11 @@ func Test_editRun(t *testing.T) { } t.Run(tt.name, func(t *testing.T) { - //nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock - as := prompt.NewAskStubber(t) - if tt.askStubs != nil { - tt.askStubs(as) + pm := prompter.NewMockPrompter(t) + if tt.prompterStubs != nil { + tt.prompterStubs(pm) } + tt.opts.Prompter = pm err := editRun(tt.opts) reg.Verify(t) diff --git a/pkg/cmd/gist/shared/shared.go b/pkg/cmd/gist/shared/shared.go index 547140838..66ba6fe0a 100644 --- a/pkg/cmd/gist/shared/shared.go +++ b/pkg/cmd/gist/shared/shared.go @@ -9,11 +9,10 @@ import ( "strings" "time" - "github.com/AlecAivazis/survey/v2" "github.com/cli/cli/v2/api" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/internal/text" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/prompt" "github.com/gabriel-vasile/mimetype" "github.com/shurcooL/githubv4" ) @@ -177,7 +176,7 @@ func IsBinaryContents(contents []byte) bool { return isBinary } -func PromptGists(client *http.Client, host string, cs *iostreams.ColorScheme) (gistID string, err error) { +func PromptGists(prompter prompter.Prompter, client *http.Client, host string, cs *iostreams.ColorScheme) (gistID string, err error) { gists, err := ListGists(client, host, 10, "all") if err != nil { return "", err @@ -188,7 +187,6 @@ func PromptGists(client *http.Client, host string, cs *iostreams.ColorScheme) (g } var opts []string - var result int var gistIDs = make([]string, len(gists)) for i, gist := range gists { @@ -214,13 +212,7 @@ func PromptGists(client *http.Client, host string, cs *iostreams.ColorScheme) (g opts = append(opts, opt) } - questions := &survey.Select{ - Message: "Select a gist", - Options: opts, - } - - //nolint:staticcheck // SA1019: prompt.SurveyAskOne is deprecated: use Prompter - err = prompt.SurveyAskOne(questions, &result) + result, err := prompter.Select("Select a gist", "", opts) if err != nil { return "", err diff --git a/pkg/cmd/gist/shared/shared_test.go b/pkg/cmd/gist/shared/shared_test.go index 0811464e5..1ec66d156 100644 --- a/pkg/cmd/gist/shared/shared_test.go +++ b/pkg/cmd/gist/shared/shared_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/prompt" "github.com/stretchr/testify/assert" ) @@ -94,17 +94,21 @@ func TestIsBinaryContents(t *testing.T) { func TestPromptGists(t *testing.T) { tests := []struct { - name string - askStubs func(as *prompt.AskStubber) - response string - wantOut string - gist *Gist - wantErr bool + name string + prompterStubs func(pm *prompter.MockPrompter) + response string + wantOut string + gist *Gist + wantErr bool }{ { name: "multiple files, select first gist", - askStubs: func(as *prompt.AskStubber) { - as.StubPrompt("Select a gist").AnswerWith("cool.txt about 6 hours ago") + prompterStubs: func(pm *prompter.MockPrompter) { + pm.RegisterSelect("Select a gist", + []string{"cool.txt about 6 hours ago", "gistfile0.txt about 6 hours ago"}, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "cool.txt about 6 hours ago") + }) }, response: `{ "data": { "viewer": { "gists": { "nodes": [ { @@ -126,8 +130,12 @@ func TestPromptGists(t *testing.T) { }, { name: "multiple files, select second gist", - askStubs: func(as *prompt.AskStubber) { - as.StubPrompt("Select a gist").AnswerWith("gistfile0.txt about 6 hours ago") + prompterStubs: func(pm *prompter.MockPrompter) { + pm.RegisterSelect("Select a gist", + []string{"cool.txt about 6 hours ago", "gistfile0.txt about 6 hours ago"}, + func(_, _ string, opts []string) (int, error) { + return prompter.IndexFor(opts, "gistfile0.txt about 6 hours ago") + }) }, response: `{ "data": { "viewer": { "gists": { "nodes": [ { @@ -173,12 +181,13 @@ func TestPromptGists(t *testing.T) { t.Run(tt.name, func(t *testing.T) { //nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock - as := prompt.NewAskStubber(t) - if tt.askStubs != nil { - tt.askStubs(as) + + mockPrompter := prompter.NewMockPrompter(t) + if tt.prompterStubs != nil { + tt.prompterStubs(mockPrompter) } - gistID, err := PromptGists(client, "github.com", ios.ColorScheme()) + gistID, err := PromptGists(mockPrompter, client, "github.com", ios.ColorScheme()) assert.NoError(t, err) assert.Equal(t, tt.wantOut, gistID) reg.Verify(t) diff --git a/pkg/cmd/gist/view/view.go b/pkg/cmd/gist/view/view.go index ffc5d54a9..e4f5c84e1 100644 --- a/pkg/cmd/gist/view/view.go +++ b/pkg/cmd/gist/view/view.go @@ -89,7 +89,7 @@ func viewRun(opts *ViewOptions) error { cs := opts.IO.ColorScheme() if gistID == "" { - gistID, err = shared.PromptGists(client, hostname, cs) + gistID, err = shared.PromptGists(opts.Prompter, client, hostname, cs) if err != nil { return err } diff --git a/pkg/cmd/gist/view/view_test.go b/pkg/cmd/gist/view/view_test.go index 49cf878ec..c571422c5 100644 --- a/pkg/cmd/gist/view/view_test.go +++ b/pkg/cmd/gist/view/view_test.go @@ -8,11 +8,11 @@ import ( "time" "github.com/cli/cli/v2/internal/config" + "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/cmd/gist/shared" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/prompt" "github.com/google/shlex" "github.com/stretchr/testify/assert" ) @@ -336,6 +336,10 @@ func Test_viewRun(t *testing.T) { httpmock.JSONResponse(tt.gist)) } + if tt.opts == nil { + tt.opts = &ViewOptions{} + } + if tt.mockGistList { sixHours, _ := time.ParseDuration("6h") sixHoursAgo := time.Now().Add(-sixHours) @@ -355,13 +359,11 @@ func Test_viewRun(t *testing.T) { )), ) - //nolint:staticcheck // SA1019: prompt.NewAskStubber is deprecated: use PrompterMock - as := prompt.NewAskStubber(t) - as.StubPrompt("Select a gist").AnswerDefault() - } - - if tt.opts == nil { - tt.opts = &ViewOptions{} + pm := prompter.NewMockPrompter(t) + pm.RegisterSelect("Select a gist", []string{"cool.txt about 6 hours ago"}, func(_, _ string, opts []string) (int, error) { + return 0, nil + }) + tt.opts.Prompter = pm } tt.opts.HttpClient = func() (*http.Client, error) {