emote: add emote parsing engine
This commit is contained in:
111
emote/emote_test.go
Normal file
111
emote/emote_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package emote_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.sunturtle.xyz/zephyr/kaiyan/emote"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
emotes []string
|
||||
text string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
emotes: strings.Fields("bocchi ryō nijika kita"),
|
||||
text: "",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "none",
|
||||
emotes: nil,
|
||||
text: "bocchi ryō nijika kita",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "all",
|
||||
emotes: strings.Fields("bocchi ryō nijika kita"),
|
||||
text: "bocchi ryō nijika kita",
|
||||
want: strings.Fields("bocchi ryō nijika kita"),
|
||||
},
|
||||
{
|
||||
name: "some",
|
||||
emotes: strings.Fields("bocchi nijika"),
|
||||
text: "bocchi ryō nijika kita",
|
||||
want: strings.Fields("bocchi nijika"),
|
||||
},
|
||||
{
|
||||
name: "others",
|
||||
emotes: strings.Fields("ryō kita"),
|
||||
text: "bocchi ryō nijika kita",
|
||||
want: strings.Fields("ryō kita"),
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
// Convert the emote names to emotes proper.
|
||||
e := make([]emote.Emote, len(c.emotes))
|
||||
for i, w := range c.emotes {
|
||||
e[i] = emote.Emote{ID: w, Name: w, Source: c.name}
|
||||
}
|
||||
p := emote.NewParser(e...)
|
||||
var got []string
|
||||
text := c.text
|
||||
for {
|
||||
name, id, rest := p.Next(text)
|
||||
if id == "" {
|
||||
break
|
||||
}
|
||||
if name != id {
|
||||
// Not normally the case, but this test is constructed
|
||||
// so that it is.
|
||||
t.Errorf("wrong id %q for name %q", id, name)
|
||||
}
|
||||
got = append(got, name)
|
||||
text = rest
|
||||
}
|
||||
if diff := cmp.Diff(c.want, got); diff != "" {
|
||||
t.Errorf("wrong emotes (-want/+got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser(b *testing.B) {
|
||||
e := []emote.Emote{
|
||||
{ID: "bocchi", Name: "bocchi"},
|
||||
{ID: "ryō", Name: "ryō"},
|
||||
{ID: "nijika", Name: "nijika"},
|
||||
{ID: "kita", Name: "kita"},
|
||||
{ID: "seika", Name: "seika"},
|
||||
{ID: "kikuri", Name: "kikuri"},
|
||||
{ID: "eliza", Name: "eliza"},
|
||||
{ID: "shima", Name: "shima"},
|
||||
}
|
||||
p := emote.NewParser(e...)
|
||||
texts := []struct {
|
||||
name string
|
||||
text string
|
||||
}{
|
||||
{"none-short", "none"},
|
||||
{"none-long", strings.TrimSpace(strings.Repeat("none ", 100))},
|
||||
{"single", "bocchi"},
|
||||
{"natural", strings.TrimSpace(strings.Repeat("kessoku band is bocchi ryō nijika kita starry is seika PA-san sickhack is kikuri eliza shima ", 5))},
|
||||
}
|
||||
for _, c := range texts {
|
||||
b.Run(c.name, func(b *testing.B) {
|
||||
b.SetBytes(int64(len(c.text)))
|
||||
for b.Loop() {
|
||||
text := c.text
|
||||
for text != "" {
|
||||
_, _, text = p.Next(text)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user