gotry/try/try_test.go
2021-10-10 19:52:10 +02:00

280 lines
4.7 KiB
Go

package try
/*
try is a fork of lainio's err2 package
Copyright (c) 2019 Lainio, MIT License
https://github.com/lainio/err2
*/
import (
"fmt"
"testing"
)
func throw() (string, error) {
return "", fmt.Errorf("this is an ERROR")
}
func twoStrNoThrow() (string, string, error) { return "test", "test", nil }
func noThrow() (string, error) { return "test", nil }
func wrongSignature() (int, int) { return 0, 0 }
func recursion(a int) int {
if a == 0 {
return 0
}
s, err := noThrow()
Check(err)
_ = s
return a + recursion(a-1)
}
func recursionWithErrorCheck(a int) (int, error) {
if a == 0 {
return 0, nil
}
s, err := noThrow()
if err != nil {
return 0, err
}
_ = s
v, err := recursionWithErrorCheck(a - 1)
if err != nil {
return 0, err
}
return a + v, nil
}
func noErr() error {
return nil
}
func TestAny_noError(t *testing.T) {
d := Any(noThrow())
if d[0].(string) != "test" {
t.Fail()
}
d = Any(twoStrNoThrow())
if d[0].(string) != "test" || d[1].(string) != "test" {
t.Fail()
}
}
func TestDefault_Error(t *testing.T) {
var err error
defer Return(&err)
Any(throw())
t.Fail() // If everything works we are never here
}
func TestAny_Error(t *testing.T) {
var err error
defer Handle(&err, func() {})
Any(throw())
t.Fail() // If everything works we are never here
}
func panickingHandle() {
var err error
defer Handle(&err, func() {})
Any(wrongSignature())
}
func TestPanickingCarryOn_Handle(t *testing.T) {
defer func() {
if recover() == nil {
t.Error("panics should went thru when not our errors")
}
}()
panickingHandle()
}
func panickingCatchAll() {
defer CatchAll(func(err error) {}, func(v interface{}) {})
Any(wrongSignature())
}
func TestPanickingCatchAll(t *testing.T) {
defer func() {
if recover() != nil {
t.Error("panics should not fly thru")
}
}()
panickingCatchAll()
}
func panickingCatchTrace() {
defer CatchTrace(func(err error) {})
Any(wrongSignature())
}
func TestPanickingCatchTrace(t *testing.T) {
defer func() {
if recover() != nil {
t.Error("panics should NOT carry on when tracing")
}
}()
panickingCatchTrace()
}
func panickingReturn() {
var err error
defer Return(&err)
Any(wrongSignature())
}
func TestPanicking_Return(t *testing.T) {
defer func() {
if recover() == nil {
t.Error("panics should carry on")
}
}()
panickingReturn()
}
func panickingCatch() {
defer Catch(func(err error) {})
Any(wrongSignature())
}
func TestPanicking_Catch(t *testing.T) {
defer func() {
if recover() == nil {
t.Error("panics should carry on")
}
}()
panickingCatch()
}
func TestCatch_Error(t *testing.T) {
defer Catch(func(err error) {
// fmt.Printf("error and defer handling:%s\n", err)
})
Any(throw())
t.Fail() // If everything works we are never here
}
func ExampleReturn() {
var err error
defer Return(&err)
Any(noThrow())
// Output:
}
func ExampleAnnotate() {
annotated := func() (err error) {
defer Annotate("annotated", &err)
Any(throw())
return err
}
err := annotated()
fmt.Printf("%v", err)
// Output: annotated: this is an ERROR
}
func ExampleReturnf() {
annotated := func() (err error) {
defer Returnf(&err, "annotated: %s", "err2")
Any(throw())
return err
}
err := annotated()
fmt.Printf("%v", err)
// Output: annotated: err2: this is an ERROR
}
func ExampleAnnotate_deferStack() {
annotated := func() (err error) {
defer Annotate("annotated 2nd", &err)
defer Annotate("annotated 1st", &err)
Any(throw())
return err
}
err := annotated()
fmt.Printf("%v", err)
// Output: annotated 2nd: annotated 1st: this is an ERROR
}
func ExampleHandle() {
doSomething := func(a, b int) (err error) {
defer Handle(&err, func() {
err = fmt.Errorf("error with (%d, %d): %w", a, b, err)
})
Any(throw())
return err
}
err := doSomething(1, 2)
fmt.Printf("%v", err)
// Output: error with (1, 2): this is an ERROR
}
func BenchmarkOldErrorCheckingWithIfClause(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := noThrow()
if err != nil {
return
}
}
}
func BenchmarkAny(b *testing.B) {
for n := 0; n < b.N; n++ {
Any(noThrow())
}
}
func BenchmarkAny_ErrVar(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := noThrow()
Any(err)
}
}
func BenchmarkCheckInsideCall(b *testing.B) {
for n := 0; n < b.N; n++ {
Check(noErr())
}
}
func BenchmarkCheckVarCall(b *testing.B) {
for n := 0; n < b.N; n++ {
err := noErr()
Check(err)
}
}
func BenchmarkCheck_ErrVar(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := noThrow()
Check(err)
}
}
func BenchmarkRecursionNoCheck_NotRelated(b *testing.B) {
for n := 0; n < b.N; n++ {
_ = recursion(100)
}
}
func BenchmarkRecursionWithErrorCheck_NotRelated(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := recursionWithErrorCheck(100)
if err != nil {
return
}
}
}