Documentation
¶
Index ¶
- Constants
- type Closer
- type Responder
- func (r *Responder) AddConfirm(question string, answer confirmResponse) *Responder
- func (r *Responder) AddMultiSelect(question string, options []int) *Responder
- func (r *Responder) AddResponse(question string, answer string) *Responder
- func (r *Responder) AddSelect(question string, option int) *Responder
- func (r *Responder) Debug() *Responder
- func (r *Responder) MatchExact() *Responder
- func (r *Responder) MatchRegexp() *Responder
- func (r *Responder) RespondOnce() *Responder
- func (r *Responder) RespondTimes(times int) *Responder
- func (r *Responder) Start(t testingi.T, timeout time.Duration) (*io.PipeReader, *io.PipeWriter, Closer)
Examples ¶
Constants ¶
const ( // ConfirmAffirm is the 'yes' answer in a Confirm question ConfirmAffirm confirmResponse = "yes" // ConfirmAffirm is the 'no' answer in a Confirm question ConfirmNegative confirmResponse = "no" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Closer ¶
type Closer func()
Closer is returned from Start and should be called in a defer after calling Start
type Responder ¶
type Responder struct {
// contains filtered or unexported fields
}
Responder is a builder that allows you to put together a list of responses to questions asked in a form. Check out NewResponder for more information.
func NewResponder ¶
func NewResponder() *Responder
NewResponder instantiates a Responder that allows you to build responses to a commandline application. The Start() command should be called at the end of a chain to start a goroutine that will read and write using the returned io.Pipe objects.
For example:
stdIn, stdOut, cancel := NewResponder(). AddResponse(...), AddConfirm(...), Start() defer cancel() myForm.WithInput(stdIn).WithOutput(stdOut).Run()
Check out the individual method descriptions to learn more.
Example ¶
package main
import (
"fmt"
"strings"
"testing"
"time"
"github.com/charmbracelet/huh"
"github.com/stretchr/testify/require"
)
var t = new(testing.T)
func main() {
// Arrange
var (
howAreYouFeelingAnswer string
areYouReadyAnswer bool
sleptWellAnswer string
activitiesAnswer []string
)
myForm := huh.NewForm(
huh.NewGroup(
huh.NewInput().
Title("How Are You Feeling?").
Value(&howAreYouFeelingAnswer),
huh.NewConfirm().
Title("Are you ready?").
Value(&areYouReadyAnswer),
huh.NewSelect[string]().
Title("Have you slept well?").
Options(
huh.NewOption("Well!", "well"),
huh.NewOption("Terribly!", "terrible"),
huh.NewOption("It was OK!", "ok"),
).
Value(&sleptWellAnswer),
),
huh.NewGroup(
huh.NewMultiSelect[string]().
Title("What are your favourite activities?").
Options(
huh.NewOption("Cycling", "bike"),
huh.NewOption("Sleeping", "sleep"),
huh.NewOption("Boating", "boat"),
huh.NewOption("Gaming", "game"),
huh.NewOption("Flying", "fly"),
).
Value(&activitiesAnswer),
),
)
stdin, stdout, cancel := NewResponder().
AddResponse("How Are You Feeling?", "Great").
AddConfirm("Are you ready?", ConfirmAffirm).
AddMultiSelect("activities", []int{1, 2, 4}).
AddSelect("Have you slept well", 2).
Start(t, 1*time.Second)
defer cancel()
// Act
err := myForm.WithInput(stdin).WithOutput(stdout).Run()
// Assert
require.NoError(t, err)
fmt.Println("How are you feeling?", howAreYouFeelingAnswer)
fmt.Println("Are you ready?", areYouReadyAnswer)
fmt.Println("Have you slept well?", sleptWellAnswer)
fmt.Println("What are your favourite activities?", strings.Join(activitiesAnswer, ", "))
}
Output: How are you feeling? Great Are you ready? true Have you slept well? ok What are your favourite activities? sleep, boat, fly
func NewResponderWith ¶
NewResponderWith is a lot like NewResponder, but initialises the given questions and responses automatically. This only works for simple responses, select, multi-select and confirms have to be added manually afterwards. Please refer to the documentation of NewResponder to learn more about its usages.
func (*Responder) AddConfirm ¶
AddConfirm adds a confirm response to the Responder. If the same question comes up multiple times, the same response will be returned by default. Use Times() or Once() to modify this behaviour and register an error.
Multiple answers to the same question can be added by repeating this call.
func (*Responder) AddMultiSelect ¶
AddMultiSelect adds a response that will navigate a multiple-choice list and pick the indexes of the given options. If the same question comes up multiple times, the same response will be returned by default. Use Times() or Once() to modify this behaviour and register an error.
Multiple answers to the same question can be added by repeating this call.
func (*Responder) AddResponse ¶
AddResponse adds a text-based response to the responder that will be returned if the question matches. If the same question comes up multiple times, the same response will be returned by default. Use Times() or Once() to modify this behaviour and register an error.
Multiple answers to the same question can be added by repeating this call.
func (*Responder) AddSelect ¶
AddSelect adds a response that will navigate a multiple-choice list and pick the index of the given option. If the same question comes up multiple times, the same response will be returned by default. Use Times() or Once() to modify this behaviour and register an error.
Multiple answers to the same question can be added by repeating this call.
func (*Responder) MatchExact ¶
MatchExact changes question matching to exactly match the output. This is only useful if you are 100% sure that the output line won't contain any formatting or flair,
func (*Responder) MatchRegexp ¶
MatchRegexp changes question matching to treat the question as a regex
func (*Responder) RespondOnce ¶
RespondOnce will make the test error if the question is posed more than 1 once, but it will still return an answer.
func (*Responder) RespondTimes ¶
RespondOnce will make the test error if the question is posed more than the specified amount of times, but it will still return an answer.
func (*Responder) Start ¶
func (r *Responder) Start(t testingi.T, timeout time.Duration) (*io.PipeReader, *io.PipeWriter, Closer)
Start will kick off the goroutine that will listen for inputs in the returned io.PipeWriter. It will then attempt to answer the incoming line with a registered response on the io.PipeReader. You're required to provide a timeout that will stop the reader and writer to prevent it from locking forever.
To stop the responder, you can call the returned cancel/close function that will close the readers and writers
Usage:
stdIn, stdOut, cancel := NewResponder(). AddResponse(...), AddConfirms(...), Start() defer cancel() myForm.WithInput(stdIn).WithOutput(stdOut).Run()