144 lines
2.8 KiB
Go
144 lines
2.8 KiB
Go
// Package testing provides a testing object T
|
|
// with functions for classical unit testing.
|
|
package testing
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
lib "git.sr.ht/~cco/go-scopes"
|
|
"git.sr.ht/~cco/go-scopes/app"
|
|
"git.sr.ht/~cco/go-scopes/core/context"
|
|
"git.sr.ht/~cco/go-scopes/core/message"
|
|
"git.sr.ht/~cco/go-scopes/logging"
|
|
)
|
|
|
|
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)
|
|
logging.SetDefault()
|
|
return t
|
|
}
|
|
|
|
func SetUpApp(tbase *testing.T, cfg lib.Config) *T {
|
|
appCfg := cfg.(*app.Cfg)
|
|
t := SetUp(tbase)
|
|
t.Ctx = context.AppContext(cfg).WithState(t)
|
|
logging.Setup(t.Ctx, appCfg.Logging, appCfg.Home)
|
|
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()
|
|
lib.Send(t.Ctx, message.SimpleAddress("testing"), message.Quit)
|
|
t.Ctx.WaitGroup().Wait()
|
|
//t.AssertNoUncheckedMessages()
|
|
}
|
|
|
|
func (t *T) LogCheck(pr bool) int {
|
|
count := 0
|
|
f, _ := os.Open("log/scopes.log")
|
|
defer f.Close()
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
count++
|
|
if pr {
|
|
txt := scanner.Text()
|
|
data := logging.Parse(txt)
|
|
level := data["level"]
|
|
message := data["message"]
|
|
delete(data, "level")
|
|
delete(data, "message")
|
|
delete(data, "time")
|
|
srv := "-"
|
|
if data["service"] != nil {
|
|
srv = data["service"].(string)
|
|
delete(data, "service")
|
|
}
|
|
dstr := ""
|
|
if len(data) > 0 {
|
|
dstr = fmt.Sprintf("; %+v", data)
|
|
}
|
|
fmt.Printf("%d: %s: %s - %s%s\n", count, level, srv, message, dstr)
|
|
//fmt.Println(scanner.Text())
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func GetT(ctx lib.Context) *T {
|
|
return ctx.Parent().State().(*T)
|
|
}
|
|
|
|
// 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, "")
|
|
}
|