Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
Prompt again (#165)
Browse files Browse the repository at this point in the history
* survey: pass previous invalid value to Prompt

Support different behavior after a validation error in repeated prompts.

Signed-off-by: Mate Ory <mate.ory@banzaicloud.com>

* editor: recall previous invalid input

Recall the previous invalid input in the repeated prompt so the user
doesn't have to start over typing the answer.

Signed-off-by: Mate Ory <mate.ory@banzaicloud.com>

* survey_test: check recalling invalid Editor input

* tests: add prompt-again editor manual test
  • Loading branch information
orymate authored and AlecAivazis committed Dec 11, 2018
1 parent fb519f8 commit e205523
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 59 deletions.
21 changes: 16 additions & 5 deletions editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,20 @@ func init() {
}
}

func (e *Editor) PromptAgain(invalid interface{}, err error) (interface{}, error) {
initialValue := invalid.(string)
return e.prompt(initialValue)
}

func (e *Editor) Prompt() (interface{}, error) {
initialValue := ""
if e.Default != "" && e.AppendDefault {
initialValue = e.Default
}
return e.prompt(initialValue)
}

func (e *Editor) prompt(initialValue string) (interface{}, error) {
// render the template
err := e.Render(
EditorQuestionTemplate,
Expand Down Expand Up @@ -134,11 +147,9 @@ func (e *Editor) Prompt() (interface{}, error) {
return "", err
}

// write default value
if e.Default != "" && e.AppendDefault {
if _, err := f.WriteString(e.Default); err != nil {
return "", err
}
// write initial value
if _, err := f.WriteString(initialValue); err != nil {
return "", err
}

// close the fd to prevent the editor unable to save file
Expand Down
11 changes: 10 additions & 1 deletion survey.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ type Prompt interface {
Error(error) error
}

// PromptAgainer Interface for Prompts that support prompting again after invalid input
type PromptAgainer interface {
PromptAgain(invalid interface{}, err error) (interface{}, error)
}

// AskOpt allows setting optional ask options.
type AskOpt func(options *AskOptions) error

Expand Down Expand Up @@ -157,7 +162,11 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error {
}

// ask for more input
ans, err = q.Prompt.Prompt()
if promptAgainer, ok := q.Prompt.(PromptAgainer); ok {
ans, err = promptAgainer.PromptAgain(ans, invalid)
} else {
ans, err = q.Prompt.Prompt()
}
// if there was a problem
if err != nil {
return err
Expand Down
50 changes: 39 additions & 11 deletions survey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package survey

import (
"fmt"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -63,6 +64,19 @@ func TestAsk(t *testing.T) {
Message: "Edit git commit message",
},
},
{
Name: "commit-message-validated",
Prompt: &Editor{
Message: "Edit git commit message",
},
Validate: func(v interface{}) error {
s := v.(string)
if strings.Contains(s, "invalid") {
return fmt.Errorf("invalid error message")
}
return nil
},
},
{
Name: "name",
Prompt: &Input{
Expand Down Expand Up @@ -98,11 +112,24 @@ func TestAsk(t *testing.T) {
// Editor
c.ExpectString("Edit git commit message [Enter to launch editor]")
c.SendLine("")
go func() {
time.Sleep(time.Millisecond)
c.Send("iAdd editor prompt tests\x1b")
c.SendLine(":wq!")
}()
time.Sleep(time.Millisecond)
c.Send("iAdd editor prompt tests\x1b")
c.SendLine(":wq!")

// Editor validated
c.ExpectString("Edit git commit message [Enter to launch editor]")
c.SendLine("")
time.Sleep(time.Millisecond)
c.Send("i invalid input first try\x1b")
c.SendLine(":wq!")
time.Sleep(time.Millisecond)
c.ExpectString("invalid error message")
c.ExpectString("Edit git commit message [Enter to launch editor]")
c.SendLine("")
time.Sleep(time.Millisecond)
c.ExpectString("first try")
c.Send("ccAdd editor prompt tests\x1b")
c.SendLine(":wq!")

// Input
c.ExpectString("What is your name?")
Expand All @@ -129,12 +156,13 @@ func TestAsk(t *testing.T) {
c.ExpectEOF()
},
map[string]interface{}{
"pizza": true,
"commit-message": "Add editor prompt tests\n",
"name": "Johnny Appleseed",
"day": []string{"Monday", "Wednesday"},
"password": "secret",
"color": "yellow",
"pizza": true,
"commit-message": "Add editor prompt tests\n",
"commit-message-validated": "Add editor prompt tests\n",
"name": "Johnny Appleseed",
"day": []string{"Monday", "Wednesday"},
"password": "secret",
"color": "yellow",
},
},
{
Expand Down
10 changes: 5 additions & 5 deletions tests/confirm.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,30 @@ var goodTable = []TestUtil.TestTableEntry{
{
"Enter 'yes'", &survey.Confirm{
Message: "yes:",
}, &answer,
}, &answer, nil,
},
{
"Enter 'no'", &survey.Confirm{
Message: "yes:",
}, &answer,
}, &answer, nil,
},
{
"default", &survey.Confirm{
Message: "yes:",
Default: true,
}, &answer,
}, &answer, nil,
},
{
"not recognized (enter random letter)", &survey.Confirm{
Message: "yes:",
Default: true,
}, &answer,
}, &answer, nil,
},
{
"no help - type '?'", &survey.Confirm{
Message: "yes:",
Default: true,
}, &answer,
}, &answer, nil,
},
}

Expand Down
27 changes: 23 additions & 4 deletions tests/editor.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package main

import (
"fmt"
"strings"

"gopkg.in/AlecAivazis/survey.v1"
"gopkg.in/AlecAivazis/survey.v1/tests/util"
)
Expand All @@ -11,27 +14,43 @@ var goodTable = []TestUtil.TestTableEntry{
{
"should open in editor", &survey.Editor{
Message: "should open",
}, &answer,
}, &answer, nil,
},
{
"has help", &survey.Editor{
Message: "press ? to see message",
Help: "Does this work?",
}, &answer,
}, &answer, nil,
},
{
"should not include the default value in the prompt", &survey.Editor{
Message: "the default value 'Hello World' should not include in the prompt",
HideDefault: true,
Default: "Hello World",
}, &answer,
}, &answer, nil,
},
{
"should write the default value to the temporary file before the launch of the editor", &survey.Editor{
Message: "the default value 'Hello World' is written to the temporary file before the launch of the editor",
AppendDefault: true,
Default: "Hello World",
}, &answer,
}, &answer, nil,
},
{
Name: "should print the validation error, and recall the submitted invalid value instead of the default",
Prompt: &survey.Editor{
Message: "the default value 'Hello World' is written to the temporary file before the launch of the editor",
AppendDefault: true,
Default: `this is the default value. change it to something containing "invalid" (in vi type "ccinvalid<Esc>ZZ")`,
},
Value: &answer,
Validate: func(v interface{}) error {
s := v.(string)
if strings.Contains(s, "invalid") {
return fmt.Errorf(`this is the error message. change the input to something not containing "invalid"`)
}
return nil
},
},
}

Expand Down
10 changes: 5 additions & 5 deletions tests/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,35 @@ var goodTable = []TestUtil.TestTableEntry{
"confirm", &survey.Confirm{
Message: "Is it raining?",
Help: "Go outside, if your head becomes wet the answer is probably 'yes'",
}, &confirmAns,
}, &confirmAns, nil,
},
{
"input", &survey.Input{
Message: "What is your phone number:",
Help: "Phone number should include the area code, parentheses optional",
}, &inputAns,
}, &inputAns, nil,
},
{
"select", &survey.MultiSelect{
Message: "What days are you available:",
Help: "We are closed weekends and avaibility is limited on Wednesday",
Options: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"},
Default: []string{"Monday", "Tuesday", "Thursday", "Friday"},
}, &multiselectAns,
}, &multiselectAns, nil,
},
{
"select", &survey.Select{
Message: "Choose a color:",
Help: "Blue is the best color, but it is your choice",
Options: []string{"red", "blue", "green"},
Default: "blue",
}, &selectAns,
}, &selectAns, nil,
},
{
"password", &survey.Password{
Message: "Enter a secret:",
Help: "Don't really enter a secret, this is just for testing",
}, &passwordAns,
}, &passwordAns, nil,
},
}

Expand Down
12 changes: 6 additions & 6 deletions tests/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ var val = ""

var table = []TestUtil.TestTableEntry{
{
"no default", &survey.Input{Message: "Hello world"}, &val,
"no default", &survey.Input{Message: "Hello world"}, &val, nil,
},
{
"default", &survey.Input{Message: "Hello world", Default: "default"}, &val,
"default", &survey.Input{Message: "Hello world", Default: "default"}, &val, nil,
},
{
"no help, send '?'", &survey.Input{Message: "Hello world"}, &val,
"no help, send '?'", &survey.Input{Message: "Hello world"}, &val, nil,
},
{
"Home, End Button test in random location", &survey.Input{Message: "Hello world"}, &val,
"Home, End Button test in random location", &survey.Input{Message: "Hello world"}, &val, nil,
}, {
"Delete and forward delete test at random location (test if screen overflows)", &survey.Input{Message: "Hello world"}, &val,
"Delete and forward delete test at random location (test if screen overflows)", &survey.Input{Message: "Hello world"}, &val, nil,
}, {
"Moving around lines with left & right arrow keys", &survey.Input{Message: "Hello world"}, &val,
"Moving around lines with left & right arrow keys", &survey.Input{Message: "Hello world"}, &val, nil,
},
}

Expand Down
10 changes: 5 additions & 5 deletions tests/multiselect.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@ var table = []TestUtil.TestTableEntry{
"standard", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
}, &answer,
}, &answer, nil,
},
{
"default (sunday, tuesday)", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
Default: []string{"Sunday", "Tuesday"},
}, &answer,
}, &answer, nil,
},
{
"default not found", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
Default: []string{"Sundayaa"},
}, &answer,
}, &answer, nil,
},
{
"no help - type ?", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
Default: []string{"Sundayaa"},
}, &answer,
}, &answer, nil,
},
{
"can navigate with j/k", &survey.MultiSelect{
Message: "What days do you prefer:",
Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
Default: []string{"Sundayaa"},
}, &answer,
}, &answer, nil,
},
}

Expand Down
6 changes: 3 additions & 3 deletions tests/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ var value = ""

var table = []TestUtil.TestTableEntry{
{
"standard", &survey.Password{Message: "Please type your password:"}, &value,
"standard", &survey.Password{Message: "Please type your password:"}, &value, nil,
},
{
"please make sure paste works", &survey.Password{Message: "Please paste your password:"}, &value,
"please make sure paste works", &survey.Password{Message: "Please paste your password:"}, &value, nil,
},
{
"no help, send '?'", &survey.Password{Message: "Please type your password:"}, &value,
"no help, send '?'", &survey.Password{Message: "Please type your password:"}, &value, nil,
},
}

Expand Down

0 comments on commit e205523

Please sign in to comment.