package sqlitestore_test import ( "fmt" "slices" "strings" "testing" "time" "git.sunturtle.xyz/zephyr/kaiyan/emote" "git.sunturtle.xyz/zephyr/kaiyan/emote/sqlitestore" "github.com/google/go-cmp/cmp" "zombiezen.com/go/sqlite" "zombiezen.com/go/sqlite/sqlitex" ) func testDB(name string) *sqlitex.Pool { opts := sqlitex.PoolOptions{ Flags: sqlite.OpenCreate | sqlite.OpenReadWrite | sqlite.OpenMemory | sqlite.OpenSharedCache | sqlite.OpenURI, } pool, err := sqlitex.NewPool(fmt.Sprintf("file:%s.db?mode=memory&cache=shared", name), opts) if err != nil { panic(err) } return pool } func TestStore(t *testing.T) { ems := []struct { channel, message, sender string ts int64 emotes []emote.Emote }{ { channel: "kessoku", message: "1", sender: "ryo", ts: 1000, emotes: []emote.Emote{ {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, }, }, { channel: "kessoku", message: "2", sender: "seika", ts: 2000, emotes: []emote.Emote{ {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, }, }, { channel: "sickhack", message: "3", sender: "ryo", ts: 1500, emotes: []emote.Emote{ {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, {ID: "nijika", Name: "nijika"}, {ID: "kita", Name: "kita"}, }, }, } st, err := sqlitestore.Open(t.Context(), testDB("TestStore")) if err != nil { t.Fatal(err) } for _, m := range ems { err := st.Record(t.Context(), m.channel, m.message, m.sender, time.Unix(m.ts, 0), m.emotes) if err != nil { t.Errorf("couldn't record message %s: %v", m.message, err) } } cases := []struct { name string channel string start, end int64 want []emote.Metric }{ { name: "channel", channel: "kessoku", start: 0, end: 1e6, want: []emote.Metric{ { Emote: emote.Emote{ID: "kita", Name: "kita"}, Tokens: 4, Messages: 2, Users: 2, }, { Emote: emote.Emote{ID: "nijika", Name: "nijika"}, Tokens: 4, Messages: 2, Users: 2, }, }, }, { name: "time", channel: "kessoku", start: 1250, end: 1e6, want: []emote.Metric{ { Emote: emote.Emote{ID: "kita", Name: "kita"}, Tokens: 2, Messages: 1, Users: 1, }, { Emote: emote.Emote{ID: "nijika", Name: "nijika"}, Tokens: 2, Messages: 1, Users: 1, }, }, }, } for _, c := range cases { // Don't use Run because we have earlier t.Fails. got, err := st.Metrics(t.Context(), c.channel, time.Unix(c.start, 0), time.Unix(c.end, 0), nil) if err != nil { t.Error(err) } // Sort results by emote ID so we can easily diff. // In particular, we don't expect the store to sort for us. slices.SortFunc(got, func(a, b emote.Metric) int { return strings.Compare(a.Emote.ID, b.Emote.ID) }) if diff := cmp.Diff(c.want, got); diff != "" { t.Errorf("wrong results (+got/-want):\n%s", diff) } } }