AlecAivazis/survey

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

go.mod

go get github.com/AlecAivazis/survey/v2@v2.3.7

Concepts

Unit Testing

Create a test FileReader and a test terminal.Studio:

import (
	"fmt"
	"io"
	"os"

	"github.com/AlecAivazis/survey/v2"
	"github.com/AlecAivazis/survey/v2/terminal"
)

// NewTestTerminalStudio is a terminal.Studio constructor that builds terminal.Studio instances used in testing.
func NewTestTerminalStudio(input string) terminal.Stdio {
	return terminal.Stdio{
		In:  NewTestFileReader(input),
		Out: os.Stdout,
		Err: os.Stderr,
	}
}

// newTestFileReader is a testFileReader constructor that preconfigures the FileReader with
// expected terminal sequences, and then appends arbitrary "input" to test with.
func newTestFileReader(input string) *testFileReader {
	return &TestFileReader{
		sequences: []string{
			"\x1b[1;1R",
			"\x1b[0;0R",
			input},
	}
}

// testFileReader is a test FileReader that returns pre-programed "sequences" of characters.
type testFileReader struct {
	sequences []string
}

// Read is part of the FileReader implementation.
func (fr *TestFileReader) Read(p []byte) (n int, err error) {
	if len(fr.sequences) != 0 {
		seq := fr.sequences[0]
		fr.sequences = fr.sequences[1:]
		n = copy(p, seq)
		return n, nil
	}
	return 0, io.EOF
}

// Fd is part of the FileReader implementation.
func (fr *TestFileReader) Fd() uintptr {
	return 0
}


Then configure the survey.AskOne with the Stdio that returns "Y\n" or "N\n":

prompt := &survey.Confirm{
	Message: "Something",
	Default: false,
}
var accepted bool
err := survey.AskOne(prompt, &accepted, func(options *survey.AskOptions) error {
	options.Stdio = NewTestTerminalStudio("Y\n")
	return nil
})
if err != nil {
	panic(err)
}
fmt.Println(accepted)