Merge pull request #5032 from cli/ask-stubber

Improve Survey stubber for tests
This commit is contained in:
Mislav Marohnić 2022-01-17 12:32:28 +01:00 committed by GitHub
commit a3f0940c62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 488 additions and 395 deletions

View file

@ -5,6 +5,7 @@ import (
"net/http"
"os"
"regexp"
"runtime"
"testing"
"github.com/MakeNowJust/heredoc"
@ -18,6 +19,21 @@ import (
"github.com/stretchr/testify/assert"
)
func stubHomeDir(t *testing.T, dir string) {
homeEnv := "HOME"
switch runtime.GOOS {
case "windows":
homeEnv = "USERPROFILE"
case "plan9":
homeEnv = "home"
}
oldHomeDir := os.Getenv(homeEnv)
os.Setenv(homeEnv, dir)
t.Cleanup(func() {
os.Setenv(homeEnv, oldHomeDir)
})
}
func Test_NewCmdLogin(t *testing.T) {
tests := []struct {
name string
@ -352,6 +368,8 @@ func Test_loginRun_nontty(t *testing.T) {
}
func Test_loginRun_Survey(t *testing.T) {
stubHomeDir(t, t.TempDir())
tests := []struct {
name string
opts *LoginOptions
@ -377,8 +395,8 @@ func Test_loginRun_Survey(t *testing.T) {
// httpmock.StringResponse(`{"data":{"viewer":{"login":"jillv"}}}`))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0) // host type github.com
as.StubOne(false) // do not continue
as.StubPrompt("What account do you want to log into?").AnswerWith("GitHub.com")
as.StubPrompt("You're already logged into github.com. Do you want to re-authenticate?").AnswerWith(false)
},
wantHosts: "", // nothing should have been written to hosts
wantErrOut: nil,
@ -396,10 +414,10 @@ func Test_loginRun_Survey(t *testing.T) {
git_protocol: https
`),
askStubs: func(as *prompt.AskStubber) {
as.StubOne("HTTPS") // git_protocol
as.StubOne(false) // cache credentials
as.StubOne(1) // auth mode: token
as.StubOne("def456") // auth token
as.StubPrompt("What is your preferred protocol for Git operations?").AnswerWith("HTTPS")
as.StubPrompt("Authenticate Git with your GitHub credentials?").AnswerWith(false)
as.StubPrompt("How would you like to authenticate GitHub CLI?").AnswerWith("Paste an authentication token")
as.StubPrompt("Paste your authentication token:").AnswerWith("def456")
},
runStubs: func(rs *run.CommandStubber) {
rs.Register(`git config credential\.https:/`, 1, "")
@ -425,12 +443,12 @@ func Test_loginRun_Survey(t *testing.T) {
Interactive: true,
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1) // host type enterprise
as.StubOne("brad.vickers") // hostname
as.StubOne("HTTPS") // git_protocol
as.StubOne(false) // cache credentials
as.StubOne(1) // auth mode: token
as.StubOne("def456") // auth token
as.StubPrompt("What account do you want to log into?").AnswerWith("GitHub Enterprise Server")
as.StubPrompt("GHE hostname:").AnswerWith("brad.vickers")
as.StubPrompt("What is your preferred protocol for Git operations?").AnswerWith("HTTPS")
as.StubPrompt("Authenticate Git with your GitHub credentials?").AnswerWith(false)
as.StubPrompt("How would you like to authenticate GitHub CLI?").AnswerWith("Paste an authentication token")
as.StubPrompt("Paste your authentication token:").AnswerWith("def456")
},
runStubs: func(rs *run.CommandStubber) {
rs.Register(`git config credential\.https:/`, 1, "")
@ -456,11 +474,11 @@ func Test_loginRun_Survey(t *testing.T) {
Interactive: true,
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0) // host type github.com
as.StubOne("HTTPS") // git_protocol
as.StubOne(false) // cache credentials
as.StubOne(1) // auth mode: token
as.StubOne("def456") // auth token
as.StubPrompt("What account do you want to log into?").AnswerWith("GitHub.com")
as.StubPrompt("What is your preferred protocol for Git operations?").AnswerWith("HTTPS")
as.StubPrompt("Authenticate Git with your GitHub credentials?").AnswerWith(false)
as.StubPrompt("How would you like to authenticate GitHub CLI?").AnswerWith("Paste an authentication token")
as.StubPrompt("Paste your authentication token:").AnswerWith("def456")
},
runStubs: func(rs *run.CommandStubber) {
rs.Register(`git config credential\.https:/`, 1, "")
@ -480,11 +498,11 @@ func Test_loginRun_Survey(t *testing.T) {
Interactive: true,
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0) // host type github.com
as.StubOne("SSH") // git_protocol
as.StubOne(10) // TODO: SSH key selection
as.StubOne(1) // auth mode: token
as.StubOne("def456") // auth token
as.StubPrompt("What account do you want to log into?").AnswerWith("GitHub.com")
as.StubPrompt("What is your preferred protocol for Git operations?").AnswerWith("SSH")
as.StubPrompt("Generate a new SSH key to add to your GitHub account?").AnswerWith(false)
as.StubPrompt("How would you like to authenticate GitHub CLI?").AnswerWith("Paste an authentication token")
as.StubPrompt("Paste your authentication token:").AnswerWith("def456")
},
wantErrOut: regexp.MustCompile("Tip: you can generate a Personal Access Token here https://github.com/settings/tokens"),
},
@ -530,8 +548,7 @@ func Test_loginRun_Survey(t *testing.T) {
hostsBuf := bytes.Buffer{}
defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}

View file

@ -106,8 +106,8 @@ func Test_logoutRun_tty(t *testing.T) {
cfgHosts: []string{"cheryl.mason", "github.com"},
wantHosts: "cheryl.mason:\n oauth_token: abc123\n",
askStubs: func(as *prompt.AskStubber) {
as.StubOne("github.com")
as.StubOne(true)
as.StubPrompt("What account do you want to log out of?").AnswerWith("github.com")
as.StubPrompt("Are you sure you want to log out of github.com account 'cybilb'?").AnswerWith(true)
},
wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
},
@ -116,7 +116,7 @@ func Test_logoutRun_tty(t *testing.T) {
opts: &LogoutOptions{},
cfgHosts: []string{"github.com"},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(true)
as.StubPrompt("Are you sure you want to log out of github.com account 'cybilb'?").AnswerWith(true)
},
wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
},
@ -133,7 +133,7 @@ func Test_logoutRun_tty(t *testing.T) {
cfgHosts: []string{"cheryl.mason", "github.com"},
wantHosts: "github.com:\n oauth_token: abc123\n",
askStubs: func(as *prompt.AskStubber) {
as.StubOne(true)
as.StubPrompt("Are you sure you want to log out of cheryl.mason account 'cybilb'?").AnswerWith(true)
},
wantErrOut: regexp.MustCompile(`Logged out of cheryl.mason account 'cybilb'`),
},
@ -169,8 +169,7 @@ func Test_logoutRun_tty(t *testing.T) {
hostsBuf := bytes.Buffer{}
defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}

View file

@ -194,7 +194,7 @@ func Test_refreshRun(t *testing.T) {
Hostname: "",
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne("github.com")
as.StubPrompt("What account do you want to refresh auth for?").AnswerWith("github.com")
},
wantAuthArgs: authArgs{
hostname: "github.com",
@ -276,8 +276,7 @@ func Test_refreshRun(t *testing.T) {
hostsBuf := bytes.Buffer{}
defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}

View file

@ -47,14 +47,13 @@ func TestLogin_ssh(t *testing.T) {
httpmock.REST("POST", "api/v3/user/keys"),
httpmock.StringResponse(`{}`))
ask, askRestore := prompt.InitAskStubber()
defer askRestore()
ask := prompt.NewAskStubber(t)
ask.StubOne("SSH") // preferred protocol
ask.StubOne(true) // generate a new key
ask.StubOne("monkey") // enter a passphrase
ask.StubOne(1) // paste a token
ask.StubOne("ATOKEN") // token
ask.StubPrompt("What is your preferred protocol for Git operations?").AnswerWith("SSH")
ask.StubPrompt("Generate a new SSH key to add to your GitHub account?").AnswerWith(true)
ask.StubPrompt("Enter a passphrase for your new SSH key (Optional)").AnswerWith("monkey")
ask.StubPrompt("How would you like to authenticate GitHub CLI?").AnswerWith("Paste an authentication token")
ask.StubPrompt("Paste your authentication token:").AnswerWith("ATOKEN")
rs, runRestore := run.Stub()
defer runRestore(t)

View file

@ -316,8 +316,10 @@ func TestNewCmdExtension(t *testing.T) {
},
isTTY: true,
askStubs: func(as *prompt.AskStubber) {
as.StubOne("test")
as.StubOne(0)
as.StubPrompt("Extension name:").AnswerWith("test")
as.StubPrompt("What kind of extension?").
AssertOptions([]string{"Script (Bash, Ruby, Python, etc)", "Go", "Other Precompiled (C++, Rust, etc)"}).
AnswerDefault()
},
wantStdout: heredoc.Doc(`
Created directory gh-test
@ -456,8 +458,7 @@ func TestNewCmdExtension(t *testing.T) {
assertFunc = tt.managerStubs(em)
}
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}

View file

@ -10,7 +10,6 @@ import (
"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"
)
@ -61,7 +60,6 @@ func Test_deleteRun(t *testing.T) {
opts *DeleteOptions
gist *shared.Gist
httpStubs func(*httpmock.Registry)
askStubs func(*prompt.AskStubber)
nontty bool
wantErr bool
wantStderr string
@ -122,12 +120,6 @@ func Test_deleteRun(t *testing.T) {
tt.httpStubs(reg)
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
if tt.opts == nil {
tt.opts = &DeleteOptions{}
}

View file

@ -146,8 +146,8 @@ func Test_editRun(t *testing.T) {
{
name: "multiple files, submit",
askStubs: func(as *prompt.AskStubber) {
as.StubOne("unix.md")
as.StubOne("Submit")
as.StubPrompt("Edit which file?").AnswerWith("unix.md")
as.StubPrompt("What next?").AnswerWith("Submit")
},
gist: &shared.Gist{
ID: "1234",
@ -191,8 +191,8 @@ func Test_editRun(t *testing.T) {
{
name: "multiple files, cancel",
askStubs: func(as *prompt.AskStubber) {
as.StubOne("unix.md")
as.StubOne("Cancel")
as.StubPrompt("Edit which file?").AnswerWith("unix.md")
as.StubPrompt("What next?").AnswerWith("Cancel")
},
wantErr: "CancelError",
gist: &shared.Gist{
@ -280,12 +280,6 @@ func Test_editRun(t *testing.T) {
tt.httpStubs(reg)
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
if tt.opts == nil {
tt.opts = &EditOptions{}
}
@ -308,6 +302,11 @@ func Test_editRun(t *testing.T) {
}
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
err := editRun(tt.opts)
reg.Verify(t)
if tt.wantErr != "" {

View file

@ -355,9 +355,8 @@ func Test_viewRun(t *testing.T) {
)),
)
as, surveyteardown := prompt.InitAskStubber()
defer surveyteardown()
as.StubOne(0)
as := prompt.NewAskStubber(t)
as.StubPrompt("Select a gist").AnswerDefault()
}
if tt.opts == nil {
@ -392,16 +391,18 @@ func Test_viewRun(t *testing.T) {
func Test_promptGists(t *testing.T) {
tests := []struct {
name string
gistIndex int
response string
wantOut string
gist *shared.Gist
wantErr bool
name string
askStubs func(as *prompt.AskStubber)
response string
wantOut string
gist *shared.Gist
wantErr bool
}{
{
name: "multiple files, select first gist",
gistIndex: 0,
name: "multiple files, select first gist",
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Select a gist").AnswerWith("cool.txt about 6 hours ago")
},
response: `{ "data": { "viewer": { "gists": { "nodes": [
{
"name": "gistid1",
@ -421,8 +422,10 @@ func Test_promptGists(t *testing.T) {
wantOut: "gistid1",
},
{
name: "multiple files, select second gist",
gistIndex: 1,
name: "multiple files, select second gist",
askStubs: func(as *prompt.AskStubber) {
as.StubPrompt("Select a gist").AnswerWith("gistfile0.txt about 6 hours ago")
},
response: `{ "data": { "viewer": { "gists": { "nodes": [
{
"name": "gistid1",
@ -465,11 +468,12 @@ func Test_promptGists(t *testing.T) {
)
client := &http.Client{Transport: reg}
as, surveyteardown := prompt.InitAskStubber()
defer surveyteardown()
as.StubOne(tt.gistIndex)
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
gistID, err := promptGists(client, "github.com", io.ColorScheme())
assert.NoError(t, err)
assert.Equal(t, tt.wantOut, gistID)

View file

@ -401,27 +401,11 @@ func TestIssueCreate_recover(t *testing.T) {
assert.Equal(t, []interface{}{"BUGID", "TODOID"}, inputs["labelIds"])
}))
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
as.Stub([]*prompt.QuestionStub{
{
Name: "Title",
Default: true,
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "Body",
Default: true,
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "confirmation",
Value: 0,
},
})
as.StubPrompt("Title").AnswerDefault()
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").AnswerWith("Submit")
tmpfile, err := ioutil.TempFile(t.TempDir(), "testrecover*")
assert.NoError(t, err)
@ -484,25 +468,11 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) {
}),
)
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
// template
as.StubOne(1)
// body
as.Stub([]*prompt.QuestionStub{
{
Name: "Body",
Default: true,
},
}) // body
// confirm
as.Stub([]*prompt.QuestionStub{
{
Name: "confirmation",
Value: 0,
},
})
as.StubPrompt("Choose a template").AnswerWith("Submit a request")
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").AnswerWith("Submit")
output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./fixtures/repoWithNonLegacyIssueTemplates")
if err != nil {
@ -526,23 +496,10 @@ func TestIssueCreate_continueInBrowser(t *testing.T) {
} } }`),
)
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
// title
as.Stub([]*prompt.QuestionStub{
{
Name: "Title",
Value: "hello",
},
})
// confirm
as.Stub([]*prompt.QuestionStub{
{
Name: "confirmation",
Value: 1,
},
})
as.StubPrompt("Title").AnswerWith("hello")
as.StubPrompt("What's next?").AnswerWith("Continue in browser")
_, cmdTeardown := run.Stub()
defer cmdTeardown(t)

View file

@ -75,9 +75,9 @@ func TestIssueDelete(t *testing.T) {
assert.Equal(t, inputs["issueId"], "THE-ID")
}),
)
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne("13")
as := prompt.NewAskStubber(t)
as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("13")
output, err := runCommand(httpRegistry, true, "13")
if err != nil {
@ -103,9 +103,9 @@ func TestIssueDelete_cancel(t *testing.T) {
"issue": { "id": "THE-ID", "number": 13, "title": "The title of the issue"}
} } }`),
)
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne("14")
as := prompt.NewAskStubber(t)
as.StubPrompt("You're going to delete issue #13. This action cannot be reversed. To confirm, type the issue number:").AnswerWith("14")
output, err := runCommand(httpRegistry, true, "13")
if err != nil {

View file

@ -283,26 +283,13 @@ func TestPRCreate_recover(t *testing.T) {
cs.Register(`git status --porcelain`, 0, "")
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
as.Stub([]*prompt.QuestionStub{
{
Name: "Title",
Default: true,
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "Body",
Default: true,
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "confirmation",
Value: 0,
},
})
as.StubPrompt("Title").AnswerDefault()
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").AnswerDefault()
tmpfile, err := ioutil.TempFile(t.TempDir(), "testrecover*")
assert.NoError(t, err)
@ -393,9 +380,11 @@ func TestPRCreate(t *testing.T) {
cs.Register(`git show-ref --verify -- HEAD refs/remotes/origin/feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
ask, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
ask.StubOne(0)
ask.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
output, err := runCommand(http, nil, "feature", true, `-t "my title" -b "my body"`)
require.NoError(t, err)
@ -438,9 +427,11 @@ func TestPRCreate_NoMaintainerModify(t *testing.T) {
cs.Register(`git show-ref --verify -- HEAD refs/remotes/origin/feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
ask, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
ask.StubOne(0)
ask.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
output, err := runCommand(http, nil, "feature", true, `-t "my title" -b "my body" --no-maintainer-edit`)
require.NoError(t, err)
@ -488,9 +479,13 @@ func TestPRCreate_createFork(t *testing.T) {
cs.Register(`git remote add -f fork https://github.com/monalisa/REPO.git`, 0, "")
cs.Register(`git push --set-upstream fork HEAD:feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
ask, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
ask.StubOne(1)
ask.StubPrompt("Where should we push the 'feature' branch?").
AssertOptions([]string{"OWNER/REPO", "Create a fork of OWNER/REPO", "Skip pushing the branch", "Cancel"}).
AnswerWith("Create a fork of OWNER/REPO")
output, err := runCommand(http, nil, "feature", true, `-t title -b body`)
require.NoError(t, err)
@ -544,6 +539,7 @@ func TestPRCreate_pushedToNonBaseRepo(t *testing.T) {
deadbeef refs/remotes/origin/feature
`)) // determineTrackingBranch
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
_, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
@ -585,6 +581,7 @@ func TestPRCreate_pushedToDifferentBranchName(t *testing.T) {
deadbeef refs/remotes/origin/my-feat2
`)) // determineTrackingBranch
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
_, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
@ -618,21 +615,17 @@ func TestPRCreate_nonLegacyTemplate(t *testing.T) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "1234567890,commit 0\n2345678901,commit 1")
cs.Register(`git status --porcelain`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne(0) // template
as.Stub([]*prompt.QuestionStub{
{
Name: "Body",
Default: true,
},
}) // body
as.Stub([]*prompt.QuestionStub{
{
Name: "confirmation",
Value: 0,
},
}) // confirm
as.StubPrompt("Choose a template").
AssertOptions([]string{"Bug fix", "Open a blank pull request"}).
AnswerWith("Bug fix")
as.StubPrompt("Body").AnswerDefault()
as.StubPrompt("What's next?").
AssertOptions([]string{"Submit", "Continue in browser", "Add metadata", "Cancel"}).
AnswerDefault()
output, err := runCommandWithRootDirOverridden(http, nil, "feature", true, `-t "my title" -H feature`, "./fixtures/repoWithNonLegacyPRTemplates")
require.NoError(t, err)
@ -771,9 +764,13 @@ func TestPRCreate_web(t *testing.T) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
ask, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
ask.StubOne(0)
ask.StubPrompt("Where should we push the 'feature' branch?").
AssertOptions([]string{"OWNER/REPO", "Skip pushing the branch", "Cancel"}).
AnswerDefault()
output, err := runCommand(http, nil, "feature", true, `--web`)
require.NoError(t, err)
@ -842,9 +839,11 @@ func TestPRCreate_webProject(t *testing.T) {
cs.Register(`git( .+)? log( .+)? origin/master\.\.\.feature`, 0, "")
cs.Register(`git push --set-upstream origin HEAD:feature`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
ask, cleanupAsk := prompt.InitAskStubber()
defer cleanupAsk()
ask.StubOne(0)
ask.StubPrompt("Where should we push the 'feature' branch?").AnswerDefault()
output, err := runCommand(http, nil, "feature", true, `--web -p Triage`)
require.NoError(t, err)

View file

@ -769,8 +769,10 @@ func TestPrMerge_alreadyMerged(t *testing.T) {
cs.Register(`git branch -D blueberries`, 0, "")
cs.Register(`git pull --ff-only`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true)
output, err := runCommand(http, "blueberries", true, "pr merge 4")
@ -846,11 +848,15 @@ func TestPRMerge_interactive(t *testing.T) {
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
as.StubOne(0) // Merge method survey
as.StubOne(false) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0) // Merge method survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Submit") // Confirm submit survey
output, err := runCommand(http, "blueberries", true, "")
@ -905,10 +911,13 @@ func TestPRMerge_interactiveWithDeleteBranch(t *testing.T) {
cs.Register(`git branch -D blueberries`, 0, "")
cs.Register(`git pull --ff-only`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
as.StubOne(0) // Merge method survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0) // Merge method survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Submit") // Confirm submit survey
output, err := runCommand(http, "blueberries", true, "-d")
@ -964,14 +973,20 @@ func TestPRMerge_interactiveSquashEditCommitMsgAndSubject(t *testing.T) {
_, cmdTeardown := run.Stub()
defer cmdTeardown(t)
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
as.StubOne(2) // Merge method survey
as.StubOne(false) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2) // Merge method survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Edit commit subject") // Confirm submit survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Edit commit message") // Confirm submit survey
as.StubOne("Submit") // Confirm submit survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Submit") // Confirm submit survey
err := mergeRun(&MergeOptions{
IO: io,
@ -1017,11 +1032,15 @@ func TestPRMerge_interactiveCancelled(t *testing.T) {
cs.Register(`git rev-parse --verify refs/heads/`, 0, "")
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
as.StubOne(0) // Merge method survey
as.StubOne(true) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0) // Merge method survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true) // Delete branch survey
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Cancel") // Confirm submit survey
output, err := runCommand(http, "blueberries", true, "")
@ -1038,8 +1057,10 @@ func Test_mergeMethodSurvey(t *testing.T) {
RebaseMergeAllowed: true,
SquashMergeAllowed: true,
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, surveyTeardown := prompt.InitAskStubber()
defer surveyTeardown()
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0) // Select first option which is rebase merge
method, err := mergeMethodSurvey(repo)
assert.Nil(t, err)

View file

@ -270,21 +270,25 @@ func TestPRReview_interactive(t *testing.T) {
}),
)
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewType",
Value: "Approve",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "body",
Value: "cool story",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "confirm",
@ -309,27 +313,10 @@ func TestPRReview_interactive_no_body(t *testing.T) {
shared.RunCommandFinder("", &api.PullRequest{ID: "THE-ID", Number: 123}, ghrepo.New("OWNER", "REPO"))
as, teardown := prompt.InitAskStubber()
defer teardown()
as := prompt.NewAskStubber(t)
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewType",
Value: "Request changes",
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "body",
Default: true,
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "confirm",
Value: true,
},
})
as.StubPrompt("What kind of review do you want to give?").AnswerWith("Request changes")
as.StubPrompt("Review body").AnswerWith("")
_, err := runCommand(http, nil, true, "")
assert.EqualError(t, err, "this type of review cannot be blank")
@ -350,21 +337,25 @@ func TestPRReview_interactive_blank_approve(t *testing.T) {
}),
)
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewType",
Value: "Approve",
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "body",
Default: true,
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "confirm",

View file

@ -43,15 +43,18 @@ func TestMetadataSurvey_selectAll(t *testing.T) {
},
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, restoreAsk := prompt.InitAskStubber()
defer restoreAsk()
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "metadata",
Value: []string{"Labels", "Projects", "Assignees", "Reviewers", "Milestone"},
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "reviewers",
@ -71,7 +74,7 @@ func TestMetadataSurvey_selectAll(t *testing.T) {
},
{
Name: "milestone",
Value: []string{"(none)"},
Value: "(none)",
},
})
@ -109,15 +112,18 @@ func TestMetadataSurvey_keepExisting(t *testing.T) {
},
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, restoreAsk := prompt.InitAskStubber()
defer restoreAsk()
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "metadata",
Value: []string{"Labels", "Projects"},
},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{
Name: "labels",

View file

@ -63,9 +63,11 @@ func TestTemplateManager_hasAPI(t *testing.T) {
assert.Equal(t, "LEGACY", string(m.LegacyBody()))
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, askRestore := prompt.InitAskStubber()
defer askRestore()
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(1) // choose "Feature Request"
tpl, err := m.Choose()
assert.NoError(t, err)

View file

@ -515,27 +515,16 @@ func Test_createRun_interactive(t *testing.T) {
name: "create a release from existing tag",
opts: &CreateOptions{},
askStubs: func(as *prompt.AskStubber) {
as.StubOne("v1.2.3") // Tag prompt
as.Stub([]*prompt.QuestionStub{
{
Name: "name",
Value: "title",
},
{
Name: "releaseNotesAction",
Value: "Leave blank",
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "prerelease",
Value: false,
},
{
Name: "submitAction",
Value: "Publish release",
},
})
as.StubPrompt("Choose a tag").
AssertOptions([]string{"v1.2.3", "v1.2.2", "v1.0.0", "v0.1.2", "Create a new tag"}).
AnswerWith("v1.2.3")
as.StubPrompt("Title (optional)").AnswerWith("")
as.StubPrompt("Release notes").
AssertOptions([]string{"Write my own", "Write using generated notes as template", "Leave blank"}).
AnswerWith("Leave blank")
as.StubPrompt("Is this a prerelease?").AnswerWith(false)
as.StubPrompt("Submit?").
AssertOptions([]string{"Publish release", "Save as draft", "Cancel"}).AnswerWith("Publish release")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "repos/OWNER/REPO/tags"), httpmock.StatusStringResponse(200, `[
@ -558,28 +547,12 @@ func Test_createRun_interactive(t *testing.T) {
name: "create a release from new tag",
opts: &CreateOptions{},
askStubs: func(as *prompt.AskStubber) {
as.StubOne("Create a new tag") // Tag prompt
as.StubOne("v1.2.3") // New tag prompt
as.Stub([]*prompt.QuestionStub{
{
Name: "name",
Value: "title",
},
{
Name: "releaseNotesAction",
Value: "Leave blank",
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "prerelease",
Value: false,
},
{
Name: "submitAction",
Value: "Publish release",
},
})
as.StubPrompt("Choose a tag").AnswerWith("Create a new tag")
as.StubPrompt("Tag name").AnswerWith("v1.2.3")
as.StubPrompt("Title (optional)").AnswerWith("")
as.StubPrompt("Release notes").AnswerWith("Leave blank")
as.StubPrompt("Is this a prerelease?").AnswerWith(false)
as.StubPrompt("Submit?").AnswerWith("Publish release")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("GET", "repos/OWNER/REPO/tags"), httpmock.StatusStringResponse(200, `[
@ -604,26 +577,10 @@ func Test_createRun_interactive(t *testing.T) {
TagName: "v1.2.3",
},
askStubs: func(as *prompt.AskStubber) {
as.Stub([]*prompt.QuestionStub{
{
Name: "name",
Value: "title",
},
{
Name: "releaseNotesAction",
Value: "Write using generated notes as template",
},
})
as.Stub([]*prompt.QuestionStub{
{
Name: "prerelease",
Value: false,
},
{
Name: "submitAction",
Value: "Publish release",
},
})
as.StubPrompt("Title (optional)").AnswerDefault()
as.StubPrompt("Release notes").AnswerWith("Write using generated notes as template")
as.StubPrompt("Is this a prerelease?").AnswerWith(false)
as.StubPrompt("Submit?").AnswerWith("Publish release")
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(httpmock.REST("POST", "repos/OWNER/REPO/releases/generate-notes"),
@ -641,7 +598,7 @@ func Test_createRun_interactive(t *testing.T) {
wantParams: map[string]interface{}{
"body": "generated body",
"draft": false,
"name": "title",
"name": "generated name",
"prerelease": false,
"tag_name": "v1.2.3",
},
@ -674,6 +631,7 @@ func Test_createRun_interactive(t *testing.T) {
return val, nil
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -80,6 +80,7 @@ func Test_ArchiveRun(t *testing.T) {
name: "unarchived repo tty",
wantStdout: "✓ Archived repository OWNER/REPO\n",
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne(true)
},
isTTY: true,
@ -98,6 +99,7 @@ func Test_ArchiveRun(t *testing.T) {
wantStdout: "✓ Archived repository OWNER/REPO\n",
opts: ArchiveOptions{},
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne(true)
},
isTTY: true,
@ -138,6 +140,7 @@ func Test_ArchiveRun(t *testing.T) {
io, _, stdout, stderr := iostreams.Test()
tt.opts.IO = io
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
q, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -171,22 +171,30 @@ func Test_createRun(t *testing.T) {
tty: true,
wantStdout: "✓ Created repository OWNER/REPO on GitHub\n",
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Create a new repository on GitHub from scratch")
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "repoName", Value: "REPO"},
{Name: "repoDescription", Value: "my new repo"},
{Name: "repoVisibility", Value: "PRIVATE"},
{Name: "repoVisibility", Value: "Private"},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "addGitIgnore", Value: true}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "chooseGitIgnore", Value: "Go"}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "addLicense", Value: true}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "chooseLicense", Value: "GNU Lesser General Public License v3.0"}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "confirmSubmit", Value: true}})
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true) //clone locally?
},
httpStubs: func(reg *httpmock.Registry) {
@ -210,16 +218,21 @@ func Test_createRun(t *testing.T) {
opts: &CreateOptions{Interactive: true},
tty: true,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Create a new repository on GitHub from scratch")
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "repoName", Value: "REPO"},
{Name: "repoDescription", Value: "my new repo"},
{Name: "repoVisibility", Value: "PRIVATE"},
{Name: "repoVisibility", Value: "Private"},
})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "addGitIgnore", Value: false}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "addLicense", Value: false}})
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "confirmSubmit", Value: false}})
},
@ -232,13 +245,17 @@ func Test_createRun(t *testing.T) {
opts: &CreateOptions{Interactive: true},
tty: true,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Push an existing local repository to GitHub")
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(".")
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "repoName", Value: "REPO"},
{Name: "repoDescription", Value: "my new repo"},
{Name: "repoVisibility", Value: "PRIVATE"},
{Name: "repoVisibility", Value: "Private"},
})
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false)
},
httpStubs: func(reg *httpmock.Registry) {
@ -269,16 +286,22 @@ func Test_createRun(t *testing.T) {
opts: &CreateOptions{Interactive: true},
tty: true,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Push an existing local repository to GitHub")
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(".")
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "repoName", Value: "REPO"},
{Name: "repoDescription", Value: "my new repo"},
{Name: "repoVisibility", Value: "PRIVATE"},
{Name: "repoVisibility", Value: "Private"},
})
as.StubOne(true) //ask for adding a remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true) //ask for adding a remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("origin") //ask for remote name
as.StubOne(false) //ask to push to remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false) //ask to push to remote
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
@ -309,16 +332,22 @@ func Test_createRun(t *testing.T) {
opts: &CreateOptions{Interactive: true},
tty: true,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("Push an existing local repository to GitHub")
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(".")
//nolint:staticcheck // SA1019: as.Stub is deprecated: use StubPrompt
as.Stub([]*prompt.QuestionStub{
{Name: "repoName", Value: "REPO"},
{Name: "repoDescription", Value: "my new repo"},
{Name: "repoVisibility", Value: "PRIVATE"},
{Name: "repoVisibility", Value: "Private"},
})
as.StubOne(true) //ask for adding a remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true) //ask for adding a remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne("origin") //ask for remote name
as.StubOne(true) //ask to push to remote
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true) //ask to push to remote
},
httpStubs: func(reg *httpmock.Registry) {
reg.Register(
@ -407,6 +436,7 @@ func Test_createRun(t *testing.T) {
},
}
for _, tt := range tests {
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
q, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -94,6 +94,7 @@ func Test_deleteRun(t *testing.T) {
askStubs: func(q *prompt.AskStubber) {
// TODO: survey stubber doesn't have WithValidator support
// so this always passes regardless of prompt input
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne("OWNER/REPO")
},
httpStubs: func(reg *httpmock.Registry) {
@ -108,6 +109,7 @@ func Test_deleteRun(t *testing.T) {
opts: &DeleteOptions{},
wantStdout: "✓ Deleted repository OWNER/REPO\n",
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne("OWNER/REPO")
},
httpStubs: func(reg *httpmock.Registry) {
@ -134,6 +136,7 @@ func Test_deleteRun(t *testing.T) {
wantStdout: "✓ Deleted repository OWNER/REPO\n",
tty: true,
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne("OWNER/REPO")
},
httpStubs: func(reg *httpmock.Registry) {
@ -147,6 +150,7 @@ func Test_deleteRun(t *testing.T) {
},
}
for _, tt := range tests {
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
q, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -236,6 +236,7 @@ func TestRepoFork(t *testing.T) {
},
httpStubs: forkPost,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false)
},
wantErrOut: "✓ Created fork someone/REPO\n",
@ -254,6 +255,7 @@ func TestRepoFork(t *testing.T) {
cs.Register(`git remote add -f origin https://github.com/someone/REPO.git`, 0, "")
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true)
},
wantErrOut: "✓ Created fork someone/REPO\n✓ Added remote origin\n",
@ -442,6 +444,7 @@ func TestRepoFork(t *testing.T) {
},
httpStubs: forkPost,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(false)
},
wantErrOut: "✓ Created fork someone/REPO\n",
@ -455,6 +458,7 @@ func TestRepoFork(t *testing.T) {
},
httpStubs: forkPost,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true)
},
execStubs: func(cs *run.CommandStubber) {
@ -475,6 +479,7 @@ func TestRepoFork(t *testing.T) {
},
httpStubs: forkPost,
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(true)
},
execStubs: func(cs *run.CommandStubber) {
@ -570,6 +575,7 @@ func TestRepoFork(t *testing.T) {
return tt.remotes, nil
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -117,6 +117,7 @@ func TestRenameRun(t *testing.T) {
name: "none argument",
wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote\n",
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne("NEW_REPO")
},
httpStubs: func(reg *httpmock.Registry) {
@ -136,6 +137,7 @@ func TestRenameRun(t *testing.T) {
},
wantOut: "✓ Renamed repository OWNER/NEW_REPO\n",
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne("NEW_REPO")
},
httpStubs: func(reg *httpmock.Registry) {
@ -184,6 +186,7 @@ func TestRenameRun(t *testing.T) {
},
wantOut: "✓ Renamed repository OWNER/NEW_REPO\n✓ Updated the \"origin\" remote\n",
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne(true)
},
httpStubs: func(reg *httpmock.Registry) {
@ -204,6 +207,7 @@ func TestRenameRun(t *testing.T) {
DoConfirm: true,
},
askStubs: func(q *prompt.AskStubber) {
//nolint:staticcheck // SA1019: q.StubOne is deprecated: use StubPrompt
q.StubOne(false)
},
wantOut: "",
@ -211,6 +215,7 @@ func TestRenameRun(t *testing.T) {
}
for _, tt := range testCases {
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
q, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -174,6 +174,7 @@ func TestRunCancel(t *testing.T) {
httpmock.StatusStringResponse(202, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0)
},
wantOut: "✓ Request to cancel workflow submitted.\n",
@ -195,6 +196,7 @@ func TestRunCancel(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -137,6 +137,7 @@ func TestRerun(t *testing.T) {
httpmock.StringResponse("{}"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
},
wantOut: "✓ Requested rerun of run 1234\n",
@ -193,6 +194,7 @@ func TestRerun(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -375,6 +375,7 @@ func TestViewRun(t *testing.T) {
httpmock.JSONResponse([]shared.Annotation{}))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
},
opts: &ViewOptions{
@ -411,7 +412,9 @@ func TestViewRun(t *testing.T) {
httpmock.FileResponse("./fixtures/run_log.zip"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(1)
},
wantOut: coolJobRunLogOutput,
@ -464,7 +467,9 @@ func TestViewRun(t *testing.T) {
httpmock.FileResponse("./fixtures/run_log.zip"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0)
},
wantOut: expectedRunLogOutput,
@ -523,7 +528,9 @@ func TestViewRun(t *testing.T) {
httpmock.FileResponse("./fixtures/run_log.zip"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(4)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
},
wantOut: quuxTheBarfLogOutput,
@ -576,7 +583,9 @@ func TestViewRun(t *testing.T) {
httpmock.FileResponse("./fixtures/run_log.zip"))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(4)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0)
},
wantOut: quuxTheBarfLogOutput,
@ -700,7 +709,9 @@ func TestViewRun(t *testing.T) {
httpmock.JSONResponse(shared.FailedJobAnnotations))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(0)
},
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: https://github.com/runs/3\n",
@ -733,7 +744,9 @@ func TestViewRun(t *testing.T) {
httpmock.JSONResponse([]shared.Annotation{}))
},
askStubs: func(as *prompt.AskStubber) {
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(2)
//nolint:staticcheck // SA1019: as.StubOne is deprecated: use StubPrompt
as.StubOne(1)
},
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\nTo see the full job log, try: gh run view --log --job=10\nView this run on GitHub: https://github.com/runs/3\n",
@ -830,6 +843,7 @@ func TestViewRun(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
//nolint:staticcheck // SA1019: prompt.InitAskStubber is deprecated: use NewAskStubber
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {

View file

@ -234,7 +234,9 @@ func TestWatchRun(t *testing.T) {
},
httpStubs: successfulRunStubs,
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Select a workflow run").
AssertOptions([]string{"* cool commit, run (trunk) Feb 23, 2021", "* cool commit, more runs (trunk) Feb 23, 2021"}).
AnswerWith("* cool commit, more runs (trunk) Feb 23, 2021")
},
wantOut: "\x1b[2J\x1b[0;0H\x1b[JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n* trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\x1b[0;0H\x1b[JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n✓ trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\n✓ Run more runs (2) completed with 'success'\n",
},
@ -247,7 +249,9 @@ func TestWatchRun(t *testing.T) {
},
httpStubs: successfulRunStubs,
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Select a workflow run").
AssertOptions([]string{"* cool commit, run (trunk) Feb 23, 2021", "* cool commit, more runs (trunk) Feb 23, 2021"}).
AnswerWith("* cool commit, more runs (trunk) Feb 23, 2021")
},
wantOut: "\x1b[2J\x1b[2JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n* trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\x1b[2JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n✓ trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n",
},
@ -262,7 +266,9 @@ func TestWatchRun(t *testing.T) {
},
httpStubs: failedRunStubs,
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Select a workflow run").
AssertOptions([]string{"* cool commit, run (trunk) Feb 23, 2021", "* cool commit, more runs (trunk) Feb 23, 2021"}).
AnswerWith("* cool commit, more runs (trunk) Feb 23, 2021")
},
wantOut: "\x1b[2J\x1b[0;0H\x1b[JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n* trunk more runs · 2\nTriggered via push about 59 minutes ago\n\n\x1b[0;0H\x1b[JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\nX trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nX Run more runs (2) completed with 'failure'\n",
wantErr: true,
@ -278,7 +284,9 @@ func TestWatchRun(t *testing.T) {
},
httpStubs: failedRunStubs,
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Select a workflow run").
AssertOptions([]string{"* cool commit, run (trunk) Feb 23, 2021", "* cool commit, more runs (trunk) Feb 23, 2021"}).
AnswerWith("* cool commit, more runs (trunk) Feb 23, 2021")
},
wantOut: "\x1b[2J\x1b[2JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\n* trunk more runs · 2\nTriggered via push about 59 minutes ago\n\n\x1b[2JRefreshing run status every 0 seconds. Press Ctrl+C to quit.\n\nX trunk more runs · 2\nTriggered via push about 59 minutes ago\n\nJOBS\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n",
wantErr: true,
@ -313,13 +321,12 @@ func TestWatchRun(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
err := watchRun(tt.opts)
if tt.wantErr {
assert.EqualError(t, err, tt.errMsg)

View file

@ -487,10 +487,8 @@ func Test_getBodyPrompt(t *testing.T) {
io.SetStdinTTY(true)
io.SetStdoutTTY(true)
as, teardown := prompt.InitAskStubber()
defer teardown()
as.StubOne("cool secret")
as := prompt.NewAskStubber(t)
as.StubPrompt("Paste your secret").AnswerWith("cool secret")
body, err := getBody(&SetOptions{
IO: io,

View file

@ -121,7 +121,7 @@ func TestDisableRun(t *testing.T) {
httpmock.StatusStringResponse(204, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Select a workflow").AnswerWith("another workflow (another.yml)")
},
wantOut: "✓ Disabled another workflow\n",
},
@ -176,7 +176,7 @@ func TestDisableRun(t *testing.T) {
httpmock.StatusStringResponse(204, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Which workflow do you mean?").AnswerWith("another workflow (yetanother.yml)")
},
wantOut: "✓ Disabled another workflow\n",
},
@ -277,13 +277,12 @@ func TestDisableRun(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
err := runDisable(tt.opts)
if tt.wantErr {
assert.Error(t, err)

View file

@ -121,7 +121,7 @@ func TestEnableRun(t *testing.T) {
httpmock.StatusStringResponse(204, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0)
as.StubPrompt("Select a workflow").AnswerWith("a disabled workflow (disabled.yml)")
},
wantOut: "✓ Enabled a disabled workflow\n",
},
@ -176,7 +176,7 @@ func TestEnableRun(t *testing.T) {
httpmock.StatusStringResponse(204, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(1)
as.StubPrompt("Which workflow do you mean?").AnswerWith("a disabled workflow (anotherDisabled.yml)")
},
wantOut: "✓ Enabled a disabled workflow\n",
},
@ -194,9 +194,6 @@ func TestEnableRun(t *testing.T) {
httpmock.REST("PUT", "repos/OWNER/REPO/actions/workflows/456/enable"),
httpmock.StatusStringResponse(204, "{}"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0)
},
wantOut: "✓ Enabled a disabled workflow\n",
},
{
@ -279,13 +276,12 @@ func TestEnableRun(t *testing.T) {
return ghrepo.FromFullName("OWNER/REPO")
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
err := runEnable(tt.opts)
if tt.wantErr {
assert.Error(t, err)

View file

@ -557,7 +557,7 @@ jobs:
httpmock.StatusStringResponse(204, "cool"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0)
as.StubPrompt("Select a workflow").AnswerDefault()
},
wantBody: map[string]interface{}{
"inputs": map[string]interface{}{},
@ -594,17 +594,9 @@ jobs:
httpmock.StatusStringResponse(204, "cool"))
},
askStubs: func(as *prompt.AskStubber) {
as.StubOne(0)
as.Stub([]*prompt.QuestionStub{
{
Name: "greeting",
Default: true,
},
{
Name: "name",
Value: "scully",
},
})
as.StubPrompt("Select a workflow").AnswerDefault()
as.StubPrompt("greeting").AnswerWith("hi")
as.StubPrompt("name").AnswerWith("scully")
},
wantBody: map[string]interface{}{
"inputs": map[string]interface{}{
@ -638,12 +630,12 @@ jobs:
}, "github.com"), nil
}
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
t.Run(tt.name, func(t *testing.T) {
as := prompt.NewAskStubber(t)
if tt.askStubs != nil {
tt.askStubs(as)
}
err := runRun(tt.opts)
if tt.wantErr {
assert.Error(t, err)

View file

@ -13,7 +13,6 @@ import (
"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"
)
@ -189,7 +188,6 @@ func TestViewRun(t *testing.T) {
name string
opts *ViewOptions
httpStubs func(*httpmock.Registry)
askStubs func(*prompt.AskStubber)
tty bool
wantOut string
wantErrOut string
@ -417,12 +415,6 @@ func TestViewRun(t *testing.T) {
browser := &cmdutil.TestBrowser{}
tt.opts.Browser = browser
as, teardown := prompt.InitAskStubber()
defer teardown()
if tt.askStubs != nil {
tt.askStubs(as)
}
t.Run(tt.name, func(t *testing.T) {
err := runView(tt.opts)
if tt.wantErr {

View file

@ -2,73 +2,143 @@ package prompt
import (
"fmt"
"reflect"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/core"
"github.com/cli/cli/v2/pkg/surveyext"
)
type AskStubber struct {
Asks [][]*survey.Question
AskOnes []*survey.Prompt
Count int
OneCount int
Stubs [][]*QuestionStub
StubOnes []*PromptStub
stubs []*QuestionStub
}
type testing interface {
Errorf(format string, args ...interface{})
Cleanup(func())
}
func NewAskStubber(t testing) *AskStubber {
as, teardown := InitAskStubber()
t.Cleanup(func() {
teardown()
for _, s := range as.stubs {
if !s.matched {
t.Errorf("unmatched prompt stub: %+v", s)
}
}
})
return as
}
// Deprecated: use NewAskStubber
func InitAskStubber() (*AskStubber, func()) {
origSurveyAsk := SurveyAsk
origSurveyAskOne := SurveyAskOne
as := AskStubber{}
SurveyAskOne = func(p survey.Prompt, response interface{}, opts ...survey.AskOpt) error {
as.AskOnes = append(as.AskOnes, &p)
count := as.OneCount
as.OneCount += 1
if count >= len(as.StubOnes) {
panic(fmt.Sprintf("more asks than stubs. most recent call: %v", p))
}
stubbedPrompt := as.StubOnes[count]
if stubbedPrompt.Default {
// TODO this is failing for basic AskOne invocations with a string result.
defaultValue := reflect.ValueOf(p).Elem().FieldByName("Default")
_ = core.WriteAnswer(response, "", defaultValue)
} else {
_ = core.WriteAnswer(response, "", stubbedPrompt.Value)
answerFromStub := func(p survey.Prompt, fieldName string, response interface{}) error {
var message string
var defaultValue interface{}
var options []string
switch pt := p.(type) {
case *survey.Confirm:
message = pt.Message
defaultValue = pt.Default
case *survey.Input:
message = pt.Message
defaultValue = pt.Default
case *survey.Select:
message = pt.Message
options = pt.Options
case *survey.MultiSelect:
message = pt.Message
options = pt.Options
case *survey.Password:
message = pt.Message
case *surveyext.GhEditor:
message = pt.Message
defaultValue = pt.Default
default:
return fmt.Errorf("prompt type %T is not supported by the stubber", pt)
}
var stub *QuestionStub
for _, s := range as.stubs {
if !s.matched && (s.message == "" && strings.EqualFold(s.Name, fieldName) || s.message == message) {
stub = s
stub.matched = true
break
}
}
if stub == nil {
return fmt.Errorf("no prompt stub for %q", message)
}
if len(stub.options) > 0 {
if err := compareOptions(stub.options, options); err != nil {
return fmt.Errorf("stubbed options mismatch for %q: %v", message, err)
}
}
userValue := stub.Value
if stringValue, ok := stub.Value.(string); ok && len(options) > 0 {
foundIndex := -1
for i, o := range options {
if o == stringValue {
foundIndex = i
break
}
}
if foundIndex < 0 {
return fmt.Errorf("answer %q not found in options for %q: %v", stringValue, message, options)
}
userValue = core.OptionAnswer{
Value: stringValue,
Index: foundIndex,
}
}
if stub.Default {
if defaultIndex, ok := defaultValue.(int); ok && len(options) > 0 {
userValue = core.OptionAnswer{
Value: options[defaultIndex],
Index: defaultIndex,
}
} else if defaultValue == nil && len(options) > 0 {
userValue = core.OptionAnswer{
Value: options[0],
Index: 0,
}
} else {
userValue = defaultValue
}
}
if err := core.WriteAnswer(response, fieldName, userValue); err != nil {
topic := fmt.Sprintf("field %q", fieldName)
if fieldName == "" {
topic = fmt.Sprintf("%q", message)
}
return fmt.Errorf("AskStubber failed writing the answer for %s: %w", topic, err)
}
return nil
}
SurveyAskOne = func(p survey.Prompt, response interface{}, opts ...survey.AskOpt) error {
return answerFromStub(p, "", response)
}
SurveyAsk = func(qs []*survey.Question, response interface{}, opts ...survey.AskOpt) error {
as.Asks = append(as.Asks, qs)
count := as.Count
as.Count += 1
if count >= len(as.Stubs) {
panic(fmt.Sprintf("more asks than stubs. most recent call: %#v", qs))
}
// actually set response
stubbedQuestions := as.Stubs[count]
if len(stubbedQuestions) != len(qs) {
panic(fmt.Sprintf("asked questions: %d; stubbed questions: %d", len(qs), len(stubbedQuestions)))
}
for i, sq := range stubbedQuestions {
q := qs[i]
if q.Name != sq.Name {
panic(fmt.Sprintf("stubbed question mismatch: %s != %s", q.Name, sq.Name))
}
if sq.Default {
defaultValue := reflect.ValueOf(q.Prompt).Elem().FieldByName("Default")
_ = core.WriteAnswer(response, q.Name, defaultValue)
} else {
_ = core.WriteAnswer(response, q.Name, sq.Value)
for _, q := range qs {
if err := answerFromStub(q.Prompt, q.Name, response); err != nil {
return err
}
}
return nil
}
teardown := func() {
SurveyAsk = origSurveyAsk
SurveyAskOne = origSurveyAskOne
@ -76,30 +146,59 @@ func InitAskStubber() (*AskStubber, func()) {
return &as, teardown
}
type PromptStub struct {
Value interface{}
Default bool
}
type QuestionStub struct {
Name string
Value interface{}
Default bool
matched bool
message string
options []string
}
// AssertOptions asserts the options presented to the user in Selects and MultiSelects.
func (s *QuestionStub) AssertOptions(opts []string) *QuestionStub {
s.options = opts
return s
}
// AnswerWith defines an answer for the given stub.
func (s *QuestionStub) AnswerWith(v interface{}) *QuestionStub {
s.Value = v
return s
}
// AnswerDefault marks the current stub to be answered with the default value for the prompt question.
func (s *QuestionStub) AnswerDefault() *QuestionStub {
s.Default = true
return s
}
// Deprecated: use StubPrompt
func (as *AskStubber) StubOne(value interface{}) {
as.StubOnes = append(as.StubOnes, &PromptStub{
Value: value,
})
}
func (as *AskStubber) StubOneDefault() {
as.StubOnes = append(as.StubOnes, &PromptStub{
Default: true,
})
as.Stub([]*QuestionStub{{Value: value}})
}
// Deprecated: use StubPrompt
func (as *AskStubber) Stub(stubbedQuestions []*QuestionStub) {
// A call to .Ask takes a list of questions; a stub is then a list of questions in the same order.
as.Stubs = append(as.Stubs, stubbedQuestions)
as.stubs = append(as.stubs, stubbedQuestions...)
}
// StubPrompt records a stub for an interactive prompt matched by its message.
func (as *AskStubber) StubPrompt(msg string) *QuestionStub {
stub := &QuestionStub{message: msg}
as.stubs = append(as.stubs, stub)
return stub
}
func compareOptions(expected, got []string) error {
if len(expected) != len(got) {
return fmt.Errorf("expected %v, got %v (length mismatch)", expected, got)
}
for i, v := range expected {
if v != got[i] {
return fmt.Errorf("expected %v, got %v", expected, got)
}
}
return nil
}