Skip to content

Commit c4c967f

Browse files
committed
add AskStubber
1 parent ed8aaa8 commit c4c967f

File tree

2 files changed

+153
-13
lines changed

2 files changed

+153
-13
lines changed

command/pr_create_test.go

Lines changed: 144 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ package command
33
import (
44
"bytes"
55
"encoding/json"
6+
"fmt"
67
"io/ioutil"
8+
"reflect"
79
"strings"
810
"testing"
911

1012
"github.com/cli/cli/context"
1113
"github.com/cli/cli/utils"
14+
15+
"github.com/AlecAivazis/survey/v2"
16+
"github.com/AlecAivazis/survey/v2/core"
1217
)
1318

1419
func TestPRCreate(t *testing.T) {
@@ -215,10 +220,143 @@ func TestPRCreate_cross_repo_same_branch(t *testing.T) {
215220
it seems that each survey prompt needs to be an injectable hook.
216221
*/
217222

218-
func PRCreate_survey_preview_defaults(t *testing.T) {
219-
// there are going to be calls to:
220-
// - git status
221-
// - git push
222-
// - git rev-parse
223-
// - git log
223+
type askStubber struct {
224+
Asks [][]*survey.Question
225+
Count int
226+
Stubs [][]*QuestionStub
227+
}
228+
229+
func initAskStubber() (*askStubber, func()) {
230+
origSurveyAsk := SurveyAsk
231+
as := askStubber{}
232+
SurveyAsk = func(qs []*survey.Question, response interface{}, opts ...survey.AskOpt) error {
233+
as.Asks = append(as.Asks, qs)
234+
count := as.Count
235+
as.Count += 1
236+
if count >= len(as.Stubs) {
237+
panic(fmt.Sprintf("more asks than stubs. most recent call: %v", qs))
238+
}
239+
240+
// actually set response
241+
stubbedQuestions := as.Stubs[count]
242+
for i, sq := range stubbedQuestions {
243+
q := qs[i]
244+
if q.Name != sq.Name {
245+
panic(fmt.Sprintf("stubbed question mismatch: %s != %s", q.Name, sq.Name))
246+
}
247+
if sq.Default {
248+
defaultValue := reflect.ValueOf(q.Prompt).Elem().FieldByName("Default")
249+
core.WriteAnswer(response, q.Name, defaultValue)
250+
} else {
251+
core.WriteAnswer(response, q.Name, sq.Value)
252+
}
253+
}
254+
255+
return nil
256+
}
257+
teardown := func() {
258+
SurveyAsk = origSurveyAsk
259+
}
260+
return &as, teardown
261+
}
262+
263+
type QuestionStub struct {
264+
Name string
265+
Value interface{}
266+
Default bool
267+
}
268+
269+
func (as *askStubber) Stub(stubbedQuestions []*QuestionStub) {
270+
// A call to .Ask takes a list of questions; a stub is then a list of questions in the same order.
271+
as.Stubs = append(as.Stubs, stubbedQuestions)
272+
}
273+
274+
func (as *askStubber) StubWithDefaults() {
275+
as.Stubs = append(as.Stubs, nil)
276+
}
277+
278+
/*
279+
there are going to be calls to:
280+
- git status
281+
- git push
282+
- git rev-parse
283+
- git log
284+
285+
I can handle all that with the new CmdStubber.
286+
287+
For survey, there is going to be:
288+
- potentially template select Ask
289+
- title, body Ask
290+
- Confirm Action Ask
291+
292+
*/
293+
func TestPRCreate_survey_preview_defaults(t *testing.T) {
294+
initBlankContext("OWNER/REPO", "feature")
295+
http := initFakeHTTP()
296+
http.StubRepoResponse("OWNER", "REPO")
297+
http.StubResponse(200, bytes.NewBufferString(`
298+
{ "data": { "createPullRequest": { "pullRequest": {
299+
"URL": "https://github.com/OWNER/REPO/pull/12"
300+
} } } }
301+
`))
302+
303+
// TODO initCmdStubber in command/testing
304+
cs := CmdStubber{}
305+
cmdTeardown := utils.SetPrepareCmd(createStubbedPrepareCmd(&cs))
306+
defer cmdTeardown()
307+
308+
cs.Stub("") // git status
309+
cs.Stub("1234567890,commit 0\n2345678901,commit 1") // git log
310+
cs.Stub("") // git rev-parse
311+
cs.Stub("") // git push
312+
313+
as, surveyTeardown := initAskStubber()
314+
defer surveyTeardown()
315+
316+
// so here is a problem: we lose survey's default detection. This works for specifying what a user
317+
// has typed in, but not for simulating when a user inputs nothing.
318+
// so; how to simulate when a user inputs nothing? can have a special method for that--even just
319+
// "all defaults" would be ok -- but need to figure out if we can even /access/ what the default
320+
// values would be.
321+
as.Stub([]*QuestionStub{
322+
&QuestionStub{
323+
Name: "title",
324+
Default: true,
325+
},
326+
&QuestionStub{
327+
Name: "body",
328+
Default: true,
329+
},
330+
})
331+
as.Stub([]*QuestionStub{
332+
&QuestionStub{
333+
Name: "confirmation",
334+
Value: 1,
335+
},
336+
})
337+
338+
output, err := RunCommand(prCreateCmd, `pr create`)
339+
eq(t, err, nil)
340+
341+
bodyBytes, _ := ioutil.ReadAll(http.Requests[1].Body)
342+
reqBody := struct {
343+
Variables struct {
344+
Input struct {
345+
RepositoryID string
346+
Title string
347+
Body string
348+
BaseRefName string
349+
HeadRefName string
350+
}
351+
}
352+
}{}
353+
json.Unmarshal(bodyBytes, &reqBody)
354+
355+
eq(t, reqBody.Variables.Input.RepositoryID, "REPOID")
356+
eq(t, reqBody.Variables.Input.Title, "my title")
357+
eq(t, reqBody.Variables.Input.Body, "my body lies")
358+
eq(t, reqBody.Variables.Input.BaseRefName, "master")
359+
eq(t, reqBody.Variables.Input.HeadRefName, "feature")
360+
361+
eq(t, output.String(), "https://github.com/OWNER/REPO/pull/12\n")
224362
}

command/title_body_survey.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ const (
2323
CancelAction
2424
)
2525

26+
var SurveyAsk = func(qs []*survey.Question, response interface{}, opts ...survey.AskOpt) error {
27+
return survey.Ask(qs, response, opts...)
28+
}
29+
2630
var ConfirmSubmission = func() (Action, error) {
2731
confirmAnswers := struct {
2832
Confirmation int
@@ -41,11 +45,13 @@ var ConfirmSubmission = func() (Action, error) {
4145
},
4246
}
4347

44-
err := survey.Ask(confirmQs, &confirmAnswers)
48+
err := SurveyAsk(confirmQs, &confirmAnswers)
4549
if err != nil {
4650
return -1, fmt.Errorf("could not prompt: %w", err)
4751
}
4852

53+
fmt.Printf("GOTTA NUMBER %d\n", confirmAnswers.Confirmation)
54+
4955
return Action(confirmAnswers.Confirmation), nil
5056
}
5157

@@ -68,7 +74,7 @@ var SelectTemplate = func(templatePaths []string) (string, error) {
6874
},
6975
},
7076
}
71-
if err := survey.Ask(selectQs, &templateResponse); err != nil {
77+
if err := SurveyAsk(selectQs, &templateResponse); err != nil {
7278
return "", fmt.Errorf("could not prompt: %w", err)
7379
}
7480
}
@@ -77,10 +83,6 @@ var SelectTemplate = func(templatePaths []string) (string, error) {
7783
return string(templateContents), nil
7884
}
7985

80-
var SurveyAsk = func(qs []*survey.Question, response interface{}, opts ...survey.AskOpt) error {
81-
return survey.Ask(qs, response, opts...)
82-
}
83-
8486
func titleBodySurvey(cmd *cobra.Command, providedTitle, providedBody string, defs defaults, templatePaths []string) (*titleBody, error) {
8587
var inProgress titleBody
8688
inProgress.Title = defs.Title
@@ -127,7 +129,7 @@ func titleBodySurvey(cmd *cobra.Command, providedTitle, providedBody string, def
127129
qs = append(qs, bodyQuestion)
128130
}
129131

130-
err := survey.Ask(qs, &inProgress)
132+
err := SurveyAsk(qs, &inProgress)
131133
if err != nil {
132134
return nil, fmt.Errorf("could not prompt: %w", err)
133135
}

0 commit comments

Comments
 (0)