-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "must" functions for tersely asserting function success #2
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,3 +133,56 @@ func ErrorIsAll(expected ...error) ErrorCheck { | |
} | ||
} | ||
} | ||
|
||
// Must can be used on a (value, error) pair to either get the value or | ||
// immediately fail the test if the error is non-nil. The T parameter is | ||
// curried, rather than passed as a third argument, so that (value, error) | ||
// function return values can be passed to Must directly, without assigning them | ||
// to intermediate variables. | ||
// | ||
// See also Must0, Must2, and Must3 for working with functions of other coarity. | ||
// | ||
// bytes := expect.Must(io.ReadAll(reader))(t) | ||
func Must[V any](value V, err error) func(T) V { | ||
return func(t T) V { | ||
t.Helper() | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %v", err) | ||
} | ||
return value | ||
} | ||
} | ||
|
||
// Must0 is similar to Must but for functions returning just an error, without a | ||
// value. | ||
func Must0(err error) func(T) { | ||
return func(t T) { | ||
t.Helper() | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %v", err) | ||
} | ||
} | ||
} | ||
|
||
// Must2 is similar to Must but for functions returning two values and an error. | ||
func Must2[V1 any, V2 any](value1 V1, value2 V2, err error) func(T) (V1, V2) { | ||
return func(t T) (V1, V2) { | ||
t.Helper() | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %v", err) | ||
} | ||
return value1, value2 | ||
} | ||
} | ||
|
||
// Must3 is similar to Must but for functions returning three values and an | ||
// error. | ||
func Must3[V1 any, V2 any, V3 any](value1 V1, value2 V2, value3 V3, err error) func(T) (V1, V2, V3) { | ||
Comment on lines
+178
to
+180
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to draw the line somewhere, and I stopped at three return values (plus the error). Anything over one or maybe two non-error return values is arguably already excessive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems reasonable - though we could go-generate |
||
return func(t T) (V1, V2, V3) { | ||
t.Helper() | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %v", err) | ||
} | ||
return value1, value2, value3 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function wouldn't have to be curried since a unary function call can be passed to another function directly even when there are other parameters. However, I opted to follow the pattern of the other functions for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely took me a minute to really understand why we're returning an unary function of T. But now I get it. I kinda long for a type-safe arg spread operator. this is a reasonably un-awkward solution.