package assert
import (
"context"
"fmt"
"reflect"
"time"
"unsafe"
)
func DifferentAddressRanges(t TestingT, a, b []byte) (ok bool) {
if h, ok := t.(tHelper); ok {
h.Helper()
}
if len(a) == 0 || len(b) == 0 {
return true
}
sliceAddrRange := func(b []byte) (uintptr, uintptr) {
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
return sh.Data, sh.Data + uintptr(sh.Cap-1)
}
aStart, aEnd := sliceAddrRange(a)
bStart, bEnd := sliceAddrRange(b)
if bStart > aEnd || aStart > bEnd {
return true
}
min := func(a, b uintptr) uintptr {
if a < b {
return a
}
return b
}
max := func(a, b uintptr) uintptr {
if a > b {
return a
}
return b
}
overlapLow := max(aStart, bStart)
overlapHigh := min(aEnd, bEnd)
t.Errorf("Byte slices point to the same underlying byte array:\n"+
"\ta addresses:\t%d ... %d\n"+
"\tb addresses:\t%d ... %d\n"+
"\toverlap:\t%d ... %d",
aStart, aEnd,
bStart, bEnd,
overlapLow, overlapHigh)
return false
}
func EqualBSON(t TestingT, expected, actual interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
return Equal(t,
expected,
actual,
`expected and actual BSON values do not match
As Extended JSON:
Expected: %s
Actual : %s`,
expected.(fmt.Stringer).String(),
actual.(fmt.Stringer).String())
}
func Soon(t TestingT, callback func(ctx context.Context), timeout time.Duration) {
if h, ok := t.(tHelper); ok {
h.Helper()
}
callbackCtx, cancel := context.WithCancel(context.Background())
defer cancel()
done := make(chan struct{})
fullCallback := func() {
callback(callbackCtx)
done <- struct{}{}
}
timer := time.NewTimer(timeout)
defer timer.Stop()
go fullCallback()
select {
case <-done:
return
case <-timer.C:
t.Errorf("timed out in %s waiting for callback", timeout)
}
}