diff --git a/goerrors.go b/goerrors.go index dd24bb6..b08ba51 100644 --- a/goerrors.go +++ b/goerrors.go @@ -7,6 +7,8 @@ package goerrors import ( "fmt" "os" + + "github.com/pat42smith/gotest" ) // OrPanic panics with e if e is not nil. @@ -47,3 +49,76 @@ func OrExit2[T1, T2 any](t1 T1, t2 T2, e error) (T1, T2) { OrExit(e) return t1, t2 } + +// OrError(e)(r) calls r.Error(e) if e is not nil. +// +// This is intended for use in test cases; r will usually be a *testing.T. +func OrError(e error) func(r gotest.Reporter) { + if e == nil { + return func(gotest.Reporter) {} + } else { + return func(r gotest.Reporter) { + r.Helper() + r.Error(e) + } + } +} + +// OrError1(t, e)(r) is like OrError(e)(r), but returns t. +func OrError1[T any](t T, e error) func(gotest.Reporter) T { + return func(r gotest.Reporter) T { + if e != nil { + r.Helper() + r.Error(e) + } + return t + } +} + +// OrError2(t1, t2, e)(r) is like OrError(e)(r), but returns (t1, t2). +func OrError2[T1, T2 any](t1 T1, t2 T2, e error) func(gotest.Reporter) (T1, T2) { + return func(r gotest.Reporter) (T1, T2) { + if e != nil { + r.Helper() + r.Error(e) + } + return t1, t2 + } +} + +// OrFatal(e)(r) calls r.Fatal(e) if e is not nil. +// +// This is intended for use in test cases; r will usually be a *testing.T, +// in which case OrFatal(e)(r) will not return when e != nil. +func OrFatal(e error) func(r gotest.Reporter) { + if e == nil { + return func(gotest.Reporter) {} + } else { + return func(r gotest.Reporter) { + r.Helper() + r.Fatal(e) + } + } +} + +// OrFatal1(t, e)(r) is like OrFatal(e)(r), but returns t when e != nil or r.Fatal() returns. +func OrFatal1[T any](t T, e error) func(gotest.Reporter) T { + return func(r gotest.Reporter) T { + if e != nil { + r.Helper() + r.Fatal(e) + } + return t + } +} + +// OrFatal2(t1, t2, e)(r) is like OrFatal(e)(r), but returns (t1, t2) when e != nil or r.Fatal() returns. +func OrFatal2[T1, T2 any](t1 T1, t2 T2, e error) func(gotest.Reporter) (T1, T2) { + return func(r gotest.Reporter) (T1, T2) { + if e != nil { + r.Helper() + r.Fatal(e) + } + return t1, t2 + } +} diff --git a/goerrors_test.go b/goerrors_test.go index f092500..6500fda 100644 --- a/goerrors_test.go +++ b/goerrors_test.go @@ -4,6 +4,7 @@ package goerrors import ( + "errors" "fmt" "io" "os/exec" @@ -103,3 +104,107 @@ func TestExits(t *testing.T) { } } } + +func TestOrError(t *testing.T) { + var sr gotest.StubReporter + OrError(nil)(&sr) + sr.Expect(t, false, false, "", "") + + OrError(errors.New("problem"))(&sr) + sr.Expect(t, true, false, "problem\n", "") +} + +func TestOrError1(t *testing.T) { + var sr gotest.StubReporter + x := OrError1(99.0, nil)(&sr) + sr.Expect(t, false, false, "", "") + gotest.Expect(t, 99.0, x) + + c := OrError1(rune('日'), errors.New("disaster"))(&sr) + sr.Expect(t, true, false, "disaster\n", "") + gotest.Expect(t, rune('日'), c) + + var sr1 gotest.StubReporter + foo := func() (string, error) { + return "doughnuts", errors.New("donuts") + } + s := OrError1(foo())(&sr1) + sr1.Expect(t, true, false, "donuts\n", "") + gotest.Expect(t, "doughnuts", s) +} + +func TestOrError2(t *testing.T) { + x := "seventeen" + y := 3.7 + var sr gotest.StubReporter + u, v := OrError2(x, y, nil)(&sr) + sr.Expect(t, false, false, "", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) + + u, v = OrError2(x, y, errors.New("falling"))(&sr) + sr.Expect(t, true, false, "falling\n", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) + + var sr1 gotest.StubReporter + foo := func() (string, float64, error) { + return x, y, nil + } + u, v = OrError2(foo())(&sr1) + sr1.Expect(t, false, false, "", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) +} + +func TestOrFatal(t *testing.T) { + var sr gotest.StubReporter + OrFatal(nil)(&sr) + sr.Expect(t, false, false, "", "") + + OrFatal(errors.New("problem"))(&sr) + sr.Expect(t, true, true, "problem\n", "") +} + +func TestOrFatal1(t *testing.T) { + var sr gotest.StubReporter + x := OrFatal1(99.0, nil)(&sr) + sr.Expect(t, false, false, "", "") + gotest.Expect(t, 99.0, x) + + c := OrFatal1(rune('日'), errors.New("disaster"))(&sr) + sr.Expect(t, true, true, "disaster\n", "") + gotest.Expect(t, rune('日'), c) + + var sr1 gotest.StubReporter + foo := func() (string, error) { + return "doughnuts", errors.New("donuts") + } + s := OrFatal1(foo())(&sr1) + sr1.Expect(t, true, true, "donuts\n", "") + gotest.Expect(t, "doughnuts", s) +} + +func TestOrFatal2(t *testing.T) { + x := "seventeen" + y := 3.7 + var sr gotest.StubReporter + u, v := OrFatal2(x, y, nil)(&sr) + sr.Expect(t, false, false, "", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) + + u, v = OrFatal2(x, y, errors.New("falling"))(&sr) + sr.Expect(t, true, true, "falling\n", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) + + var sr1 gotest.StubReporter + foo := func() (string, float64, error) { + return x, y, nil + } + u, v = OrFatal2(foo())(&sr1) + sr1.Expect(t, false, false, "", "") + gotest.Expect(t, x, u) + gotest.Expect(t, y, v) +}