// 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" "git.sr.ht/~cco/go-scopes/lib" ) func Start(ctx lib.Context) { scopes.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 = lib.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() <- "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, "") }