From 19e79b11e46387e9d1dd839778a4ffe2ad14afcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Pritchett=20=E2=9A=A1?= Date: Fri, 15 Nov 2024 11:57:27 -0600 Subject: [PATCH] fix(confirm): `--timeout` was being ignored (#697) * fix(confirm) Options.Timeout was ignored, now works as documented * Streamlines command.go per PR feedback --- confirm/command.go | 14 ++++++++++- confirm/command_test.go | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 confirm/command_test.go diff --git a/confirm/command.go b/confirm/command.go index 30fd51dfe..87f606583 100644 --- a/confirm/command.go +++ b/confirm/command.go @@ -1,6 +1,7 @@ package confirm import ( + "errors" "fmt" "os" @@ -26,12 +27,15 @@ func (o Options) Run() error { Value(&choice), ), ). + WithTimeout(o.Timeout). WithTheme(theme). WithShowHelp(o.ShowHelp). Run() if err != nil { - return fmt.Errorf("unable to run confirm: %w", err) + if !o.errIsValidTimeout(err) { + return fmt.Errorf("unable to run confirm: %w", err) + } } if !choice { @@ -40,3 +44,11 @@ func (o Options) Run() error { return nil } + +// errIsValidTimeout returns false unless 1) the user has specified a nonzero timeout and 2) the error is a huh.ErrTimeout. +func (o Options) errIsValidTimeout(err error) bool { + errWasTimeout := errors.Is(err, huh.ErrTimeout) + timeoutsExpected := o.Timeout > 0 + + return errWasTimeout && timeoutsExpected +} diff --git a/confirm/command_test.go b/confirm/command_test.go new file mode 100644 index 000000000..314a3b6d7 --- /dev/null +++ b/confirm/command_test.go @@ -0,0 +1,54 @@ +package confirm + +import ( + "fmt" + "github.com/charmbracelet/huh" + "testing" + "time" +) + +func TestOptions_errIsValidTimeout(t *testing.T) { + type testCase struct { + Description string + GivenTimeout time.Duration + GivenError error + ExpectedResult bool + } + + cases := []testCase{ + { + Description: "timeout is positive, err is a timeout", + GivenTimeout: time.Second, + GivenError: huh.ErrTimeout, + ExpectedResult: true, + }, + { + Description: "timeout is zero, err is a timeout", + GivenTimeout: 0, + GivenError: huh.ErrTimeout, + ExpectedResult: false, + }, + { + Description: "timeout is positive, err is not a timeout", + GivenTimeout: 1, + GivenError: fmt.Errorf("i'm not a timeout"), + ExpectedResult: false, + }, + { + Description: "timeout is zero, err is not a timeout", + GivenTimeout: 0, + GivenError: fmt.Errorf("i'm not a timeout"), + ExpectedResult: false, + }, + } + + for _, testCase := range cases { + t.Run(testCase.Description, func(t *testing.T) { + sut := Options{Timeout: testCase.GivenTimeout} + actualResult := sut.errIsValidTimeout(testCase.GivenError) + if actualResult != testCase.ExpectedResult { + t.Errorf("got: %v, want: %v", actualResult, testCase.ExpectedResult) + } + }) + } +}