AlecAivazis/survey: Difference between revisions
Jump to navigation
Jump to search
(Created page with "=External= =Internal= * Go") |
|||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | =External= | ||
* https://github.com/AlecAivazis/survey | |||
=Internal= | =Internal= | ||
* [[Go#Subjects|Go]] | * [[Go#Subjects|Go]] | ||
=<tt>go.mod</tt>= | |||
<syntaxhighlight lang='bash'> | |||
go get github.com/AlecAivazis/survey/v2@v2.3.7 | |||
</syntaxhighlight> | |||
=Concepts= | |||
=Unit Testing= | |||
Create a test <code>FileReader</code> and a test <code>terminal.Studio</code>: | |||
<syntaxhighlight lang='go'> | |||
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 | |||
} | |||
</syntaxhighlight> | |||
Then configure the <code>survey.AskOne</code> with the <code>Stdio</code> that returns "Y\n" or "N\n": | |||
<syntaxhighlight lang='go'> | |||
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) | |||
</syntaxhighlight> |
Latest revision as of 20:20, 6 November 2024
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)