go-scopes/testing/testing.go

104 lines
2 KiB
Go

// Package testing provides a testing object T
// with functions for classical unit testing.
package testing
import (
"fmt"
"regexp"
"testing"
"time"
"git.sr.ht/~cco/go-scopes/app"
"git.sr.ht/~cco/go-scopes/lib"
"git.sr.ht/~cco/go-scopes/lib/context"
"git.sr.ht/~cco/go-scopes/lib/message"
)
func Start(ctx lib.Context) {
app.Start(ctx)
}
// definitions
type Map map[string]interface{}
type T struct {
Base *testing.T
Ctx lib.Context
}
func MakeT(tbase *testing.T) *T {
return &T{
Base: tbase,
}
}
func SetUp(tbase *testing.T) *T {
t := MakeT(tbase)
return t
}
func SetUpApp(tbase *testing.T, cfg lib.Config) *T {
t := SetUp(tbase)
t.Ctx = context.AppContext(cfg)
cfg.Starter()(t.Ctx)
time.Sleep(100 * time.Millisecond)
return t
}
func (t *T) TearDownApp() {
// give actors time to recieve all messages:
time.Sleep(100 * time.Millisecond)
//t.Check()
t.Ctx.Services()["testing"].Mailbox() <- message.StrMessage("quit")
fmt.Println("teardown ", t.Ctx.WaitGroup())
t.Ctx.WaitGroup().Wait()
//t.AssertNoUncheckedMessages()
}
// testing methods
func (t *T) Run(name string, f func(*T)) bool {
return t.Base.Run(name, func(_ *testing.T) {
f(t)
})
}
func (t *T) LogErr(txt string, fields Map) {
t.Base.Helper()
t.Base.Errorf("%v, %+v", txt, fields)
}
func (t *T) AssertEqual(have interface{}, want interface{}) {
t.Base.Helper()
if have != want {
t.LogErr("AssertEqual", Map{"have": have, "want": want})
}
}
func (t *T) AssertMatch(have string, want string) {
t.Base.Helper()
match, _ := regexp.MatchString(Normalize(want), Normalize(have))
if !match {
t.LogErr("AssertMatch", Map{"have": have, "want": want})
}
}
// testing functions: generic functions may not be methods
func AssertOneOf[V comparable](t *T, have V, want []V) {
t.Base.Helper()
for _, w := range want {
if have == w {
return
}
}
t.LogErr("AssertOneOf", Map{"have": have, "want": want})
}
// helpers
func Normalize(s string) string {
re, _ := regexp.Compile(`\s*`)
return re.ReplaceAllString(s, "")
}