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

Commit

Permalink
Stricter error handling in tests (#404)
Browse files Browse the repository at this point in the history
* Appease the linter

* Transparently handle errors from go-expect calls

Tests that used to invoke methods on a `*expect.Console` instance now
invoke same-named methods that have error handling built in so that the
associated test is properly aborted if any of the methods happen to
fail. This kind of error handling was easier to add than adding explicit
error handling to every `c.Expect*()` and `c.Send*()` call site.

* Improve stack traces in test failures

* Upgrade go-expect and associated libraries (#405)

* Upgrade go-expect and associated libraries

* Explicitly test with supported Go versions

* Install a Go problem matcher

* Have skipped tests show up as warnings in Actions annotations

* Disable some flakey tests

* Re-arrange skipping tests

* skip a test flakey on macos-latest

The test fails with:

    select_test.go:209: SendLine("") = write /dev/ptmx: input/output error

I cannot reproduce this failure on macOS locally.
https://github.com/AlecAivazis/survey/runs/5222853435

* Few more linter cleanups

* Add more I/O error handling

* fix import

* windows err shadowing
  • Loading branch information
mislav committed Mar 8, 2022
1 parent 3cabaff commit bcabe24
Show file tree
Hide file tree
Showing 135 changed files with 16,907 additions and 1,452 deletions.
17 changes: 17 additions & 0 deletions .github/matchers.json
@@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "go",
"pattern": [
{
"regexp": "^\\s*(.+\\.go):(\\d+):(?:(\\d+):)? (?:(warning): )?(.*)",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
]
}
]
}
8 changes: 6 additions & 2 deletions .github/workflows/test.yml
Expand Up @@ -11,16 +11,20 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
go: ["1.17", "1.16"]
runs-on: ${{ matrix.platform }}
steps:
- name: Set up Go 1.13
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ^1.13
go-version: "${{ matrix.go }}"

- name: Check out code into the Go module directory
uses: actions/checkout@v2

- name: Add problem matcher
run: echo "::add-matcher::$PWD/.github/matchers.json"

- name: Run tests
run: go test -timeout 30s -v $(go list -v ./... | grep -vE '(tests|examples)$')
env:
Expand Down
8 changes: 4 additions & 4 deletions confirm.go
Expand Up @@ -49,8 +49,10 @@ func yesNo(t bool) string {
func (c *Confirm) getBool(showHelp bool, config *PromptConfig) (bool, error) {
cursor := c.NewCursor()
rr := c.NewRuneReader()
rr.SetTermMode()
defer rr.RestoreTermMode()
_ = rr.SetTermMode()
defer func() {
_ = rr.RestoreTermMode()
}()

// start waiting for input
for {
Expand Down Expand Up @@ -107,8 +109,6 @@ func (c *Confirm) getBool(showHelp bool, config *PromptConfig) (bool, error) {
}
return answer, nil
}
// should not get here
return c.Default, nil
}

/*
Expand Down
42 changes: 22 additions & 20 deletions confirm_test.go
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/AlecAivazis/survey/v2/core"
"github.com/AlecAivazis/survey/v2/terminal"
expect "github.com/Netflix/go-expect"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -59,26 +58,29 @@ func TestConfirmRender(t *testing.T) {
}

for _, test := range tests {
r, w, err := os.Pipe()
assert.Nil(t, err, test.title)
t.Run(test.title, func(t *testing.T) {
r, w, err := os.Pipe()
assert.NoError(t, err)

test.prompt.WithStdio(terminal.Stdio{Out: w})
test.data.Confirm = test.prompt
test.prompt.WithStdio(terminal.Stdio{Out: w})
test.data.Confirm = test.prompt

// set the runtime config
test.data.Config = defaultPromptConfig()
// set the runtime config
test.data.Config = defaultPromptConfig()

err = test.prompt.Render(
ConfirmQuestionTemplate,
test.data,
)
assert.Nil(t, err, test.title)
err = test.prompt.Render(
ConfirmQuestionTemplate,
test.data,
)
assert.NoError(t, err)

w.Close()
var buf bytes.Buffer
io.Copy(&buf, r)
assert.NoError(t, w.Close())
var buf bytes.Buffer
_, err = io.Copy(&buf, r)
assert.NoError(t, err)

assert.Contains(t, buf.String(), test.expected, test.title)
assert.Contains(t, buf.String(), test.expected)
})
}
}

Expand All @@ -89,7 +91,7 @@ func TestConfirmPrompt(t *testing.T) {
&Confirm{
Message: "Is pizza your favorite food?",
},
func(c *expect.Console) {
func(c expectConsole) {
c.ExpectString("Is pizza your favorite food? (y/N)")
c.SendLine("n")
c.ExpectEOF()
Expand All @@ -102,7 +104,7 @@ func TestConfirmPrompt(t *testing.T) {
Message: "Is pizza your favorite food?",
Default: true,
},
func(c *expect.Console) {
func(c expectConsole) {
c.ExpectString("Is pizza your favorite food? (Y/n)")
c.SendLine("")
c.ExpectEOF()
Expand All @@ -115,7 +117,7 @@ func TestConfirmPrompt(t *testing.T) {
Message: "Is pizza your favorite food?",
Default: true,
},
func(c *expect.Console) {
func(c expectConsole) {
c.ExpectString("Is pizza your favorite food? (Y/n)")
c.SendLine("n")
c.ExpectEOF()
Expand All @@ -128,7 +130,7 @@ func TestConfirmPrompt(t *testing.T) {
Message: "Is pizza your favorite food?",
Help: "It probably is",
},
func(c *expect.Console) {
func(c expectConsole) {
c.ExpectString(
fmt.Sprintf(
"Is pizza your favorite food? [%s for help] (y/N)",
Expand Down
10 changes: 5 additions & 5 deletions core/write.go
Expand Up @@ -178,7 +178,7 @@ func findField(s reflect.Value, name string) (reflect.Value, reflect.StructField
// then look for matching names
for _, f := range fields {
// if the name of the field matches what we're looking for
if strings.ToLower(f.fieldType.Name) == strings.ToLower(name) {
if strings.EqualFold(f.fieldType.Name, name) {
return f.value, f.fieldType, nil
}
}
Expand All @@ -197,9 +197,7 @@ func flattenFields(s reflect.Value) []reflectField {

if field.Kind() == reflect.Struct && fieldType.Anonymous {
// field is a promoted structure
for _, f := range flattenFields(field) {
fields = append(fields, f)
}
fields = append(fields, flattenFields(field)...)
continue
}
fields = append(fields, reflectField{field, fieldType})
Expand Down Expand Up @@ -361,7 +359,9 @@ func copy(t reflect.Value, v reflect.Value) (err error) {
// otherwise it could be an array
case reflect.Array:
// set the index to the appropriate value
copy(t.Slice(i, i+1).Index(0), v.Index(i))
if err := copy(t.Slice(i, i+1).Index(0), v.Index(i)); err != nil {
return err
}
}
}
} else {
Expand Down

0 comments on commit bcabe24

Please sign in to comment.