2025-11-13 14:01:30 -06:00
|
|
|
package waiterr_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/nalgeon/be"
|
|
|
|
|
|
|
|
|
|
"codeberg.org/danjones000/waiterr"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestGo(t *testing.T) {
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
err := errors.New("uh-oh")
|
|
|
|
|
var run bool
|
|
|
|
|
we.Go(func() error {
|
|
|
|
|
run = true
|
|
|
|
|
return err
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
be.Err(t, we.Wait(), err)
|
|
|
|
|
be.True(t, run)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestWait(t *testing.T) {
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
er1 := errors.New("uh-oh")
|
|
|
|
|
er2 := errors.New("oops")
|
|
|
|
|
we.Go(func() error { return er1 })
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
we.Go(func() error { return er2 })
|
|
|
|
|
|
|
|
|
|
err := we.Wait()
|
|
|
|
|
be.Err(t, err, er1, er2)
|
|
|
|
|
if ers, ok := err.(interface{ Unwrap() []error }); ok {
|
|
|
|
|
all := ers.Unwrap()
|
|
|
|
|
be.Equal(t, len(all), 2)
|
|
|
|
|
be.True(t, all[0] == er1 || all[0] == er2)
|
|
|
|
|
be.True(t, all[1] == er2 || all[1] == er1)
|
|
|
|
|
} else {
|
|
|
|
|
t.Fatal("Returned error should have Unwrap method")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestWaitForError(t *testing.T) {
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
er1 := errors.New("uh-oh")
|
|
|
|
|
er2 := errors.New("oops")
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
we.Go(func() error { return er1 })
|
|
|
|
|
we.Go(func() error { return er2 })
|
|
|
|
|
|
|
|
|
|
err := we.WaitForError()
|
|
|
|
|
// Due to how goroutines run, it is possible that either of those return first. This is an acceptable limitation
|
|
|
|
|
be.True(t, err == er1 || err == er2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestWaitForErrorNoErr(t *testing.T) {
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
|
|
|
|
|
err := we.WaitForError()
|
|
|
|
|
be.Err(t, err, nil)
|
|
|
|
|
}
|
2025-11-13 15:07:13 -06:00
|
|
|
|
|
|
|
|
func TestUnwrap(tt *testing.T) {
|
|
|
|
|
tt.Run("two errors", func(t *testing.T) {
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
er1 := errors.New("error one")
|
|
|
|
|
er2 := errors.New("error two")
|
|
|
|
|
|
|
|
|
|
we.Go(func() error { return er1 })
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
we.Go(func() error { return er2 })
|
|
|
|
|
we.Go(func() error { return nil })
|
|
|
|
|
|
|
|
|
|
_ = we.Wait() // Ensure all goroutines complete
|
|
|
|
|
|
|
|
|
|
unwrapped := we.Unwrap()
|
|
|
|
|
be.Equal(t, len(unwrapped), 2)
|
|
|
|
|
be.True(t, (unwrapped[0] == er1 && unwrapped[1] == er2) || (unwrapped[0] == er2 && unwrapped[1] == er1))
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
tt.Run("no errors", func(t *testing.T) {
|
|
|
|
|
weNoErr := new(waiterr.WaitErr)
|
|
|
|
|
weNoErr.Go(func() error { return nil })
|
|
|
|
|
weNoErr.Go(func() error { return nil })
|
|
|
|
|
_ = weNoErr.Wait()
|
|
|
|
|
be.Equal(t, weNoErr.Unwrap(), nil)
|
|
|
|
|
})
|
|
|
|
|
}
|
2025-11-13 15:23:18 -06:00
|
|
|
|
|
|
|
|
func TestWaitForErrorPanic(t *testing.T) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r == nil {
|
|
|
|
|
t.Errorf("The code did not panic")
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
we := new(waiterr.WaitErr)
|
|
|
|
|
_ = we.WaitForError()
|
|
|
|
|
}
|