// 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, "") }