From cf0a8d18c8220a743dac58c3420e948c4b030260 Mon Sep 17 00:00:00 2001 From: "Daniel J. Pritchett" Date: Thu, 31 Oct 2024 15:19:51 -0500 Subject: [PATCH] fix(confirm) Options.Timeout was ignored, now works as documented --- confirm/command.go | 15 +++++++++++- confirm/command_test.go | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 confirm/command_test.go diff --git a/confirm/command.go b/confirm/command.go index 30fd51dfe..cafb74e40 100644 --- a/confirm/command.go +++ b/confirm/command.go @@ -26,12 +26,17 @@ 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) + allowErr := o.errIsValidTimeout(err) + + if !allowErr { + return fmt.Errorf("unable to run confirm: %w", err) + } } if !choice { @@ -40,3 +45,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 := err.Error() == huh.ErrTimeout.Error() + 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) + } + }) + } +}