From a6847a996fcf9ac13f1a55a670147677992d8026 Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Mon, 1 Feb 2021 10:45:41 -0500 Subject: [PATCH] babbler: refactor --- bot/bot.go | 11 ++ bot/handlers.go | 16 +- bot/interfaces.go | 12 ++ bot/mock.go | 1 + plugins/babbler/babbler.go | 119 ++++++++----- plugins/babbler/babbler_test.go | 297 ++++++++++++++------------------ plugins/babbler/commands.go | 92 +++++----- 7 files changed, 277 insertions(+), 271 deletions(-) diff --git a/bot/bot.go b/bot/bot.go index 8f48c18..daa2179 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -230,6 +230,17 @@ func (b *bot) RegisterFilter(name string, f func(string) string) { b.filters[name] = f } +// RegisterTable registers multiple regex handlers at a time +func (b *bot) RegisterTable(p Plugin, handlers HandlerTable) { + for _, h := range handlers { + if h.IsCmd { + b.RegisterRegexCmd(p, h.Kind, h.Regex, h.Handler) + } else { + b.RegisterRegex(p, h.Kind, h.Regex, h.Handler) + } + } +} + // RegisterRegex does what register does, but with a matcher func (b *bot) RegisterRegex(p Plugin, kind Kind, r *regexp.Regexp, resp ResponseHandler) { t := reflect.TypeOf(p).String() diff --git a/bot/handlers.go b/bot/handlers.go index 7244adf..f5d9dbc 100644 --- a/bot/handlers.go +++ b/bot/handlers.go @@ -57,15 +57,15 @@ func (b *bot) runCallback(conn Connector, plugin Plugin, evt Kind, message msg.M t := reflect.TypeOf(plugin).String() for r, cbs := range b.callbacks[t][evt] { if r.MatchString(message.Body) { + req := Request{ + Conn: conn, + Kind: evt, + Msg: message, + Values: ParseValues(r, message.Body), + Args: args, + } for _, cb := range cbs { - resp := Request{ - Conn: conn, - Kind: evt, - Msg: message, - Values: ParseValues(r, message.Body), - Args: args, - } - if cb(resp) { + if cb(req) { return true } } diff --git a/bot/interfaces.go b/bot/interfaces.go index c9951e4..eeec7ed 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -61,6 +61,14 @@ type Callback func(Connector, Kind, msg.Message, ...interface{}) bool type ResponseHandler func(Request) bool type CallbackMap map[string]map[Kind]map[*regexp.Regexp][]ResponseHandler +type HandlerSpec struct { + Kind Kind + IsCmd bool + Regex *regexp.Regexp + Handler ResponseHandler +} +type HandlerTable []HandlerSpec + type RegexValues map[string]string // b interface serves to allow mocking of the actual bot @@ -90,6 +98,10 @@ type Bot interface { // The Kind arg should be one of bot.Message/Reply/Action/etc Receive(Connector, Kind, msg.Message, ...interface{}) bool + // Register a set of plugin callbacks + // Kind will be matched to the event for the callback + RegisterTable(Plugin, HandlerTable) + // Register a plugin callback // Kind will be matched to the event for the callback RegisterRegex(Plugin, Kind, *regexp.Regexp, ResponseHandler) diff --git a/bot/mock.go b/bot/mock.go index 49d2636..bbf9252 100644 --- a/bot/mock.go +++ b/bot/mock.go @@ -54,6 +54,7 @@ func (mb *MockBot) Send(c Connector, kind Kind, args ...interface{}) (string, er } func (mb *MockBot) AddPlugin(f Plugin) {} func (mb *MockBot) Register(p Plugin, kind Kind, cb Callback) {} +func (mb *MockBot) RegisterTable(p Plugin, hs HandlerTable) {} func (mb *MockBot) RegisterRegex(p Plugin, kind Kind, r *regexp.Regexp, h ResponseHandler) {} func (mb *MockBot) RegisterRegexCmd(p Plugin, kind Kind, r *regexp.Regexp, h ResponseHandler) {} func (mb *MockBot) RegisterWeb(_, _ string) {} diff --git a/plugins/babbler/babbler.go b/plugins/babbler/babbler.go index 2b3854e..f96a756 100644 --- a/plugins/babbler/babbler.go +++ b/plugins/babbler/babbler.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "math/rand" + "regexp" "strings" "github.com/rs/zerolog/log" @@ -26,6 +27,8 @@ type BabblerPlugin struct { Bot bot.Bot db *sqlx.DB WithGoRoutines bool + + handlers bot.HandlerTable } type Babbler struct { @@ -95,57 +98,87 @@ func New(b bot.Bot) *BabblerPlugin { plugin.createNewWord("") - b.Register(plugin, bot.Message, plugin.message) - b.Register(plugin, bot.Help, plugin.help) + plugin.register() return plugin } -func (p *BabblerPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool { - lowercase := strings.ToLower(message.Body) - tokens := strings.Fields(lowercase) - numTokens := len(tokens) +func (p *BabblerPlugin) register() { + p.handlers = bot.HandlerTable{ + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`(?i)^(?P\S+) says-bridge (?P.+)\|(?P.+)$`), + Handler: func(r bot.Request) bool { + who := r.Values["who"] + start := strings.Fields(strings.ToLower(r.Values["start"])) + end := strings.Fields(strings.ToLower(r.Values["end"])) + return p.sayIt(r, p.getBabbleWithBookends(who, start, end)) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`(?i)^(?P\S+) says-tail (?P.*)$`), + Handler: func(r bot.Request) bool { + who := r.Values["who"] + what := strings.Fields(strings.ToLower(r.Values["what"])) + return p.sayIt(r, p.getBabbleWithSuffix(who, what)) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`(?i)^(?P\S+) says-middle-out (?P.*)$`), + Handler: func(r bot.Request) bool { + who := r.Values["who"] + what := strings.ToLower(r.Values["what"]) + tokens := strings.Fields(what) + saidSomething := false + saidWhat := "" - saidSomething := false - saidWhat := "" - - if numTokens > 2 && tokens[1] == "says-bridge" && strings.Contains(lowercase, "|") { - split := strings.Split(lowercase, "|") - start := strings.Fields(split[0]) - end := strings.Fields(split[1]) - saidWhat, saidSomething = p.getBabbleWithBookends(start, end) - } else if numTokens >= 2 && tokens[1] == "says" { - saidWhat, saidSomething = p.getBabble(tokens) - } else if numTokens > 2 && tokens[1] == "says-tail" { - saidWhat, saidSomething = p.getBabbleWithSuffix(tokens) - } else if numTokens >= 2 && tokens[1] == "says-middle-out" { - saidWhatStart, saidSomethingStart := p.getBabbleWithSuffix(tokens) - neverSaidLooksLike := fmt.Sprintf("%s never said '%s'", tokens[0], strings.Join(tokens[2:], " ")) - if !saidSomethingStart || saidWhatStart == neverSaidLooksLike { - saidSomething = saidSomethingStart - saidWhat = saidWhatStart - } else { - saidWhatEnd, saidSomethingEnd := p.getBabble(tokens) - saidSomething = saidSomethingStart && saidSomethingEnd - if saidSomething { - saidWhat = saidWhatStart + " " + strings.Join(strings.Fields(saidWhatEnd)[len(tokens)-2:], " ") - } - } - } else if len(tokens) == 4 && strings.Index(lowercase, "initialize babbler for ") == 0 { - saidWhat, saidSomething = p.initializeBabbler(tokens) - } else if strings.Index(lowercase, "batch learn for ") == 0 { - saidWhat, saidSomething = p.batchLearn(tokens) - } else if len(tokens) == 5 && strings.Index(lowercase, "merge babbler") == 0 { - saidWhat, saidSomething = p.merge(tokens) - } else { - //this should always return "", false - saidWhat, saidSomething = p.addToBabbler(message.User.Name, lowercase) + saidWhatStart := p.getBabbleWithSuffix(who, tokens) + saidSomethingStart := saidWhatStart != "" + neverSaidLooksLike := fmt.Sprintf("%s never said", who) + if !saidSomethingStart || strings.HasPrefix(saidWhatStart, neverSaidLooksLike) { + saidSomething = saidSomethingStart + saidWhat = saidWhatStart + } else { + saidWhatEnd := p.getBabble(who, tokens) + saidSomethingEnd := saidWhatEnd != "" + saidSomething = saidSomethingStart && saidSomethingEnd + if saidSomething { + saidWhat = saidWhatStart + strings.TrimPrefix(saidWhatEnd, what) + } + } + return p.sayIt(r, saidWhat) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, Regex: regexp.MustCompile(`(?i)^(?P\S+) (says (?P.*)?|says)$`), + Handler: func(r bot.Request) bool { + who := r.Values["who"] + what := strings.Fields(strings.ToLower(r.Values["what"])) + return p.sayIt(r, p.getBabble(who, what)) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`(?i)^initialize babbler for (?P\S+)$`), + Handler: func(r bot.Request) bool { + who := r.Values["who"] + return p.sayIt(r, p.initializeBabbler(who)) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`(?i)^merge babbler (?P\S+) into (?P\S+)$`), + Handler: func(r bot.Request) bool { + from, to := r.Values["from"], r.Values["to"] + return p.sayIt(r, p.merge(from, to)) + }}, + bot.HandlerSpec{Kind: bot.Message, IsCmd: false, + Regex: regexp.MustCompile(`.*`), + Handler: func(r bot.Request) bool { + p.addToBabbler(r.Msg.User.Name, strings.ToLower(r.Msg.Body)) + return false + }}, } + p.Bot.RegisterTable(p, p.handlers) + p.Bot.Register(p, bot.Help, p.help) +} - if saidSomething { - p.Bot.Send(c, bot.Message, message.Channel, saidWhat) +func (p *BabblerPlugin) sayIt(r bot.Request, what string) bool { + if what != "" { + p.Bot.Send(r.Conn, bot.Message, r.Msg.Channel, what) } - return saidSomething + return what != "" } func (p *BabblerPlugin) help(c bot.Connector, kind bot.Kind, msg msg.Message, args ...interface{}) bool { diff --git a/plugins/babbler/babbler_test.go b/plugins/babbler/babbler_test.go index 0239396..e3eb061 100644 --- a/plugins/babbler/babbler_test.go +++ b/plugins/babbler/babbler_test.go @@ -3,27 +3,34 @@ package babbler import ( - "github.com/velour/catbase/plugins/cli" + "regexp" "strings" "testing" + "github.com/velour/catbase/plugins/cli" + "github.com/stretchr/testify/assert" "github.com/velour/catbase/bot" "github.com/velour/catbase/bot/msg" "github.com/velour/catbase/bot/user" ) -func makeMessage(payload string) (bot.Connector, bot.Kind, msg.Message) { +func makeMessage(payload string, r *regexp.Regexp) bot.Request { c := &cli.CliPlugin{} isCmd := strings.HasPrefix(payload, "!") if isCmd { payload = payload[1:] } - return c, bot.Message, msg.Message{ - User: &user.User{Name: "tester"}, - Channel: "test", - Body: payload, - Command: isCmd, + return bot.Request{ + Conn: c, + Kind: bot.Message, + Values: bot.ParseValues(r, payload), + Msg: msg.Message{ + User: &user.User{Name: "tester"}, + Channel: "test", + Body: payload, + Command: isCmd, + }, } } @@ -39,11 +46,23 @@ func newBabblerPlugin(mb *bot.MockBot) *BabblerPlugin { return bp } +func testMessage(p *BabblerPlugin, msg string) bool { + for _, h := range p.handlers { + if h.Regex.MatchString(msg) { + req := makeMessage(msg, h.Regex) + if h.Handler(req) { + return true + } + } + } + return false +} + func TestBabblerNoBabbler(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - bp.message(makeMessage("!seabass2 says")) + testMessage(bp, "!seabass2 says") res := assert.Len(t, mb.Messages, 0) assert.True(t, res) // assert.Contains(t, mb.Messages[0], "seabass2 babbler not found") @@ -53,229 +72,176 @@ func TestBabblerNothingSaid(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - res := bp.message(makeMessage("initialize babbler for seabass")) + res := testMessage(bp, "initialize babbler for seabass") assert.True(t, res) - res = bp.message(makeMessage("!seabass says")) + res = testMessage(bp, "seabass says") assert.True(t, res) - assert.Len(t, mb.Messages, 2) - assert.Contains(t, mb.Messages[0], "okay.") - assert.Contains(t, mb.Messages[1], "seabass hasn't said anything yet.") + if assert.Len(t, mb.Messages, 2) { + assert.Contains(t, mb.Messages[0], "okay.") + assert.Contains(t, mb.Messages[1], "seabass hasn't said anything yet.") + } } func TestBabbler(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "This is another message" - res = bp.message(c, k, seabass) - seabass.Body = "This is a long message" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says")) - assert.Len(t, mb.Messages, 1) + testMessage(bp, "!initialize babbler for tester") + testMessage(bp, "This is a message") + testMessage(bp, "This is another message") + testMessage(bp, "This is a long message") + res := testMessage(bp, "!tester says") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "this is") - assert.Contains(t, mb.Messages[0], "message") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "this is") + assert.Contains(t, mb.Messages[0], "message") + } } func TestBabblerSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "This is another message" - res = bp.message(c, k, seabass) - seabass.Body = "This is a long message" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says long")) - assert.Len(t, mb.Messages, 1) + + testMessage(bp, "This is a message") + testMessage(bp, "This is another message") + testMessage(bp, "This is a long message") + res := testMessage(bp, "tester says long") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "long message") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "long message") + } } func TestBabblerMultiSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "This is another message" - res = bp.message(c, k, seabass) - seabass.Body = "This is a long message" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says This is a long")) - assert.Len(t, mb.Messages, 1) - assert.True(t, res) - assert.Contains(t, mb.Messages[0], "this is a long message") -} -func TestBabblerMultiSeed2(t *testing.T) { - mb := bot.NewMockBot() - bp := newBabblerPlugin(mb) - assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "This is another message" - res = bp.message(c, k, seabass) - seabass.Body = "This is a long message" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says is a long")) - assert.Len(t, mb.Messages, 1) + testMessage(bp, "This is a message") + testMessage(bp, "This is another message") + testMessage(bp, "This is a long message") + res := testMessage(bp, "tester says is another") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "is a long message") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "is another") + } } func TestBabblerBadSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - bp.message(c, k, seabass) - seabass.Body = "This is another message" - bp.message(c, k, seabass) - seabass.Body = "This is a long message" - bp.message(c, k, seabass) - bp.message(makeMessage("!seabass says noooo this is bad")) - assert.Len(t, mb.Messages, 1) - assert.Contains(t, mb.Messages[0], "seabass never said 'noooo this is bad'") + + testMessage(bp, "This is a message") + testMessage(bp, "This is another message") + testMessage(bp, "This is a long message") + res := testMessage(bp, "tester says this is bad") + assert.True(t, res) + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "tester never said 'this is bad'") + } } func TestBabblerBadSeed2(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is a message") - seabass.User = &user.User{Name: "seabass"} - bp.message(c, k, seabass) - seabass.Body = "This is another message" - bp.message(c, k, seabass) - seabass.Body = "This is a long message" - bp.message(c, k, seabass) - bp.message(makeMessage("!seabass says This is a really")) - assert.Len(t, mb.Messages, 1) - assert.Contains(t, mb.Messages[0], "seabass never said 'this is a really'") + + testMessage(bp, "This is a message") + testMessage(bp, "This is another message") + testMessage(bp, "This is a long message") + res := testMessage(bp, "tester says This is a really") + assert.True(t, res) + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "tester never said 'this is a really'") + } } func TestBabblerSuffixSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is message one") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "It's easier to test with unique messages" - res = bp.message(c, k, seabass) - seabass.Body = "hi there" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-tail message one")) - res = bp.message(makeMessage("!seabass says-tail with unique")) - assert.Len(t, mb.Messages, 2) + + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + testMessage(bp, "tester says-tail message one") + res := testMessage(bp, "tester says-tail with unique") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "this is message one") - assert.Contains(t, mb.Messages[1], "it's easier to test with unique") + if assert.Len(t, mb.Messages, 2) { + assert.Contains(t, mb.Messages[0], "this is message one") + assert.Contains(t, mb.Messages[1], "it's easier to test with unique") + } } func TestBabblerBadSuffixSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("This is message one") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - seabass.Body = "It's easier to test with unique messages" - res = bp.message(c, k, seabass) - seabass.Body = "hi there" - res = bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-tail anything true")) - assert.Len(t, mb.Messages, 1) + + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + res := testMessage(bp, "tester says-tail anything true") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "seabass never said 'anything true'") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "tester never said 'anything true'") + } } func TestBabblerBookendSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("It's easier to test with unique messages") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-bridge It's easier | unique messages")) - assert.Len(t, mb.Messages, 1) - assert.True(t, res) - assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages") -} -func TestBabblerBookendSeedShort(t *testing.T) { - mb := bot.NewMockBot() - bp := newBabblerPlugin(mb) - assert.NotNil(t, bp) - c, k, seabass := makeMessage("It's easier to test with unique messages") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-bridge It's easier to test with | unique messages")) - assert.Len(t, mb.Messages, 1) + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + res := testMessage(bp, "tester says-bridge it's easier | unique messages") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages") + } } func TestBabblerBadBookendSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("It's easier to test with unique messages") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-bridge It's easier | not unique messages")) - assert.Len(t, mb.Messages, 1) + + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + res := testMessage(bp, "tester says-bridge says-bridge It's easier | not unique messages") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "seabass never said 'it's easier ... not unique messages'") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "tester never said 'it's easier ... not unique messages'") + } } func TestBabblerMiddleOutSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("It's easier to test with unique messages") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-middle-out test with")) - assert.Len(t, mb.Messages, 1) + + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + res := testMessage(bp, "tester says-middle-out test with") assert.True(t, res) - assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages") + } } func TestBabblerBadMiddleOutSeed(t *testing.T) { mb := bot.NewMockBot() bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage("It's easier to test with unique messages") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) - res = bp.message(makeMessage("!seabass says-middle-out anything true")) - assert.Len(t, mb.Messages, 1) - assert.True(t, res) - assert.Equal(t, mb.Messages[0], "seabass never said 'anything true'") -} -func TestBabblerBatch(t *testing.T) { - mb := bot.NewMockBot() - bp := newBabblerPlugin(mb) - assert.NotNil(t, bp) - c, k, seabass := makeMessage("batch learn for seabass This is a message! This is another message. This is not a long message? This is not a message! This is not another message. This is a long message?") - res := bp.message(c, k, seabass) - assert.Len(t, mb.Messages, 1) - res = bp.message(makeMessage("!seabass says")) - assert.Len(t, mb.Messages, 2) + testMessage(bp, "This is message one") + testMessage(bp, "It's easier to test with unique messages") + res := testMessage(bp, "tester says-middle-out anything true") assert.True(t, res) - assert.Contains(t, mb.Messages[1], "this is") - assert.Contains(t, mb.Messages[1], "message") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "tester never said 'anything true'") + } } func TestBabblerMerge(t *testing.T) { @@ -283,28 +249,23 @@ func TestBabblerMerge(t *testing.T) { bp := newBabblerPlugin(mb) assert.NotNil(t, bp) - c, k, seabass := makeMessage(" This is a message") - seabass.User = &user.User{Name: "seabass"} - res := bp.message(c, k, seabass) + testMessage(bp, " This is a message") assert.Len(t, mb.Messages, 0) - seabass.Body = " This is another message" - res = bp.message(c, k, seabass) - - seabass.Body = " This is a long message" - res = bp.message(c, k, seabass) - - res = bp.message(makeMessage("!merge babbler seabass into seabass2")) + testMessage(bp, " This is another message") + testMessage(bp, " This is a long message") + res := testMessage(bp, "merge babbler tester into tester2") assert.True(t, res) - assert.Len(t, mb.Messages, 1) - assert.Contains(t, mb.Messages[0], "mooooiggged") + if assert.Len(t, mb.Messages, 1) { + assert.Contains(t, mb.Messages[0], "mooooiggged") + } - res = bp.message(makeMessage("!seabass2 says")) + res = testMessage(bp, "!tester2 says") assert.True(t, res) - assert.Len(t, mb.Messages, 2) - - assert.Contains(t, mb.Messages[1], " this is") - assert.Contains(t, mb.Messages[1], "message") + if assert.Len(t, mb.Messages, 2) { + assert.Contains(t, mb.Messages[1], " this is") + assert.Contains(t, mb.Messages[1], "message") + } } func TestHelp(t *testing.T) { diff --git a/plugins/babbler/commands.go b/plugins/babbler/commands.go index 52291bf..6cf3ce5 100644 --- a/plugins/babbler/commands.go +++ b/plugins/babbler/commands.go @@ -5,117 +5,112 @@ import ( "strings" ) -func (p *BabblerPlugin) initializeBabbler(tokens []string) (string, bool) { - who := tokens[3] +func (p *BabblerPlugin) initializeBabbler(who string) string { _, err := p.getOrCreateBabbler(who) if err != nil { - return "babbler initialization failed.", true + return "babbler initialization failed." } - return "okay.", true + return "okay." } -func (p *BabblerPlugin) addToBabbler(babblerName, whatWasSaid string) (string, bool) { - babblerId, err := p.getOrCreateBabbler(babblerName) +func (p *BabblerPlugin) addToBabbler(babblerName, whatWasSaid string) { + babblerID, err := p.getOrCreateBabbler(babblerName) if err == nil { if p.WithGoRoutines { - go p.addToMarkovChain(babblerId, whatWasSaid) + go p.addToMarkovChain(babblerID, whatWasSaid) } else { - p.addToMarkovChain(babblerId, whatWasSaid) + p.addToMarkovChain(babblerID, whatWasSaid) } } - return "", false } -func (p *BabblerPlugin) getBabble(tokens []string) (string, bool) { - who := tokens[0] +func (p *BabblerPlugin) getBabble(who string, tokens []string) string { _, err := p.getBabbler(who) if err != nil { if err == NO_BABBLER { // return fmt.Sprintf("%s babbler not found.", who), true - return "", false + return "" } } else { var saying string - if len(tokens) == 2 { + if len(tokens) == 0 { saying, err = p.babble(who) } else { - saying, err = p.babbleSeed(who, tokens[2:]) + saying, err = p.babbleSeed(who, tokens) } if err != nil { if err == SAID_NOTHING { - return fmt.Sprintf("%s hasn't said anything yet.", who), true + return fmt.Sprintf("%s hasn't said anything yet.", who) } else if err == NEVER_SAID { - return fmt.Sprintf("%s never said '%s'", who, strings.Join(tokens[2:], " ")), true + return fmt.Sprintf("%s never said '%s'", who, strings.Join(tokens, " ")) } } else if saying != "" { - return saying, true + return saying } } - return "", false + return "" } -func (p *BabblerPlugin) getBabbleWithSuffix(tokens []string) (string, bool) { - who := tokens[0] +func (p *BabblerPlugin) getBabbleWithSuffix(who string, tokens []string) string { _, err := p.getBabbler(who) if err != nil { if err == NO_BABBLER { // return fmt.Sprintf("%s babbler not found.", who), true - return "", false + return "" } } else { - saying, err := p.babbleSeedSuffix(who, tokens[2:]) + saying, err := p.babbleSeedSuffix(who, tokens) if err != nil { if err == SAID_NOTHING { - return fmt.Sprintf("%s hasn't said anything yet.", who), true + return fmt.Sprintf("%s hasn't said anything yet.", who) } else if err == NEVER_SAID { - return fmt.Sprintf("%s never said '%s'", who, strings.Join(tokens[2:], " ")), true + return fmt.Sprintf("%s never said '%s'", who, strings.Join(tokens, " ")) } } else if saying != "" { - return saying, true + return saying } } - return "", false + return "" } -func (p *BabblerPlugin) getBabbleWithBookends(start, end []string) (string, bool) { - who := start[0] +func (p *BabblerPlugin) getBabbleWithBookends(who string, start, end []string) string { _, err := p.getBabbler(who) if err != nil { if err == NO_BABBLER { // return fmt.Sprintf("%s babbler not found.", who), true - return "", false + return "" } } else { - saying, err := p.babbleSeedBookends(who, start[2:], end) + saying, err := p.babbleSeedBookends(who, start, end) if err != nil { if err == SAID_NOTHING { - return fmt.Sprintf("%s hasn't said anything yet.", who), true + return fmt.Sprintf("%s hasn't said anything yet.", who) } else if err == NEVER_SAID { - seeds := append(start[2:], "...") + seeds := append(start[1:], "...") seeds = append(seeds, end...) - return fmt.Sprintf("%s never said '%s'", who, strings.Join(seeds, " ")), true + return fmt.Sprintf("%s never said '%s'", who, strings.Join(seeds, " ")) } } else if saying != "" { - return saying, true + return saying } } - return "", false + return "" } -func (p *BabblerPlugin) batchLearn(tokens []string) (string, bool) { +func (p *BabblerPlugin) batchLearn(tokens []string) string { who := tokens[3] babblerId, err := p.getOrCreateBabbler(who) if err != nil { - return "batch learn failed.", true + return "batch learn failed." } body := strings.Join(tokens[4:], " ") @@ -133,37 +128,30 @@ func (p *BabblerPlugin) batchLearn(tokens []string) (string, bool) { } } } - return "phew that was tiring.", true + return "phew that was tiring." } -func (p *BabblerPlugin) merge(tokens []string) (string, bool) { - if tokens[3] != "into" { - return "try using 'merge babbler [x] into [y]'", true - } - - who := tokens[2] - into := tokens[4] - +func (p *BabblerPlugin) merge(who, into string) string { if who == into { - return "that's annoying. stop it.", true + return "that's annoying. stop it." } whoBabbler, err := p.getBabbler(who) if err != nil { if err == NO_BABBLER { - return fmt.Sprintf("%s babbler not found.", who), true + return fmt.Sprintf("%s babbler not found.", who) } - return "merge failed.", true + return "merge failed." } intoBabbler, err := p.getOrCreateBabbler(into) if err != nil { - return "merge failed.", true + return "merge failed." } err = p.mergeBabblers(intoBabbler, whoBabbler, into, who) if err != nil { - return "merge failed.", true + return "merge failed." } - return "mooooiggged", true + return "mooooiggged" }