Skip to content

Commit

Permalink
Merge pull request #27 from ericjaystevens/feature_handlers
Browse files Browse the repository at this point in the history
Feature handlers
  • Loading branch information
ericjaystevens committed Aug 5, 2020
2 parents a72d3d7 + 8c916f4 commit 1402172
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 19 deletions.
77 changes: 64 additions & 13 deletions slashparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type SlashCommand struct {
Description string `yaml:"description" json:"description"`
Arguments []Argument `yaml:"arguments" json:"arguments,omitempty"`
SubCommands []SubCommand `yaml:"subcommands" json:"subcommands"`
handler func(map[string]string) (string, error)
}

//SubCommand defines a command that proceeded the slash command
Expand Down Expand Up @@ -92,26 +93,38 @@ func (s *SubCommand) getCommandPath() string {
// SetHandler sets the function that should be called based on the set of slash command and subcommands
func (s *SlashCommand) SetHandler(commandString string, handler func(map[string]string) (string, error)) error {

if strings.EqualFold(commandString, s.Name) {
s.handler = handler
}

for i, subCommand := range s.SubCommands {
commandPath := subCommand.getCommandPath() //throws panic
commandPath := subCommand.getCommandPath()

if strings.EqualFold(commandString, commandPath) {
s.SubCommands[i].handler = handler
}

for subSubCommandPostion, subSubCommand := range subCommand.SubCommands {
subSubcommandPath := subSubCommand.getCommandPath()
if strings.EqualFold(commandString, subSubcommandPath) {
s.SubCommands[i].SubCommands[subSubCommandPostion].handler = handler
}
}
}
return nil
}

func (s *SlashCommand) invokeHandler(commandString string, args map[string]string) (string, error) {
if strings.EqualFold(commandString, s.Name) {
return s.handler(args)
}

for _, subCommand := range s.SubCommands {
commandPath := subCommand.getCommandPath()

if strings.EqualFold(commandString, commandPath) {
return subCommand.handler(args)
}
subCommand, err := s.getSubCommand(commandString)
if err != nil {
return "", err
}
return "", errors.New("Unable to invoke handler")

return subCommand.handler(args)
}

//GetSlashHelp returns a markdown formated help for a slash command
Expand Down Expand Up @@ -163,12 +176,30 @@ func (s *SlashCommand) getValues(CommandAndArgs string) (map[string]string, erro
// need to go ordered here?
positionalArgs := GetPositionalArgs(args)

for _, slashArg := range s.Arguments {
if strings.EqualFold(command, s.Name) {
for _, slashArg := range s.Arguments {
position := slashArg.Position
if len(positionalArgs) >= position {
m[slashArg.Name] = positionalArgs[position-1]
}
}

return m, nil
}

subCommand, err := s.getSubCommand(command)
if err != nil {
return m, err
}

for _, slashArg := range subCommand.Arguments {
position := slashArg.Position
if len(positionalArgs) >= position {
m[slashArg.Name] = positionalArgs[position-1]
m[slashArg.Name] = positionalArgs[position]
}

}

return m, nil
}

Expand All @@ -183,19 +214,18 @@ func (s *SlashCommand) getCommandString(args string) (commandString string, err
command := strings.Replace(argsSplit[0], "/", "", 1)
args = strings.Replace(args, "/", "", 1)

//i hate this, regex might be better
//check each subcommand
for _, subCommand := range s.SubCommands {

for _, subSubCommand := range subCommand.SubCommands {
subCommandString := s.Name + " " + subCommand.Name + " " + subSubCommand.Name
if len(args) >= len(subCommandString) {
if strings.EqualFold(args[:len(subCommandString)], subCommandString) {
return subCommandString, nil
}
}

}

//check each sub sub command
subCommandString := s.Name + " " + subCommand.Name
if len(args) >= len(subCommandString) {
if strings.EqualFold(args[:len(subCommandString)], subCommandString) {
Expand Down Expand Up @@ -300,3 +330,24 @@ func validateSlashDefinition(slashCommandDef *SlashCommand) (err error) {
}
return errors.New("Slash Command Definition is not valid")
}

func (s *SlashCommand) getSubCommand(commandString string) (SubCommand, error) {

for _, subCommand := range s.SubCommands {

for _, path := range subCommand.commandPaths {
if strings.EqualFold(commandString, path) {
return subCommand, nil
}
}

for _, subSubCommand := range subCommand.SubCommands {
for _, path := range subSubCommand.commandPaths {
if strings.EqualFold(commandString, path) {
return subSubCommand, nil
}
}
}
}
return SubCommand{}, errors.New("Unable to find mathing subcommand")
}
76 changes: 70 additions & 6 deletions slashparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package slashparse

import (
"io/ioutil"
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -360,14 +361,77 @@ func TestInvokeHandler(t *testing.T) {

}

type executeTests struct {
name string
commandString string
want string
}

func TestExecute(t *testing.T) {
commandString := "/print reverse deep"

tests := []executeTests{
{
name: "slashCommand Test",
commandString: "/print echo",
want: "print called with argument echo",
},
{
name: "subcommand Test",
commandString: "/print reverse deep",
want: "reverseHandler called with text set as deep",
},
{
name: "sub sub command Test",
commandString: "/print quote author Shakespeare",
want: "quoteAuthorHandler called with authorName set as Shakespeare",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
newSlash, _ := NewSlashCommand(SimpleDef)

newSlash.SetHandler("print quote author", func(args map[string]string) (string, error) {
return "quoteAuthorHandler called with authorName set as " + args["authorName"], nil
})

newSlash.SetHandler("print reverse", func(args map[string]string) (string, error) {
return "reverseHandler called with text set as " + args["text"], nil
})

newSlash.SetHandler("print", func(args map[string]string) (string, error) {
return "print called with argument " + args["text"], nil
})

got, _ := newSlash.Execute(test.commandString)
assert.Equal(t, test.want, got)

})
}

}

func TestGetSubCommand(t *testing.T) {
newSlash, _ := NewSlashCommand(SimpleDef)
newSlash.SetHandler("print reverse", func(args map[string]string) (string, error) {
return "reverseHandler called with text set as " + args["text"], nil
})
commandString := "print quote random"
got, _ := newSlash.getSubCommand(commandString)
want := SubCommand{
Name: "random",
Description: "print a random quote from the a random author",
Arguments: []Argument(nil),
SubCommands: []SubCommand(nil),
commandPaths: []string{"Print quote random"},
}
assert.Equal(t, want, got)

}

want := "reverseHandler called with text set as deep"
func TestGetSlashHelp(t *testing.T) {
newSlash, _ := NewSlashCommand(SimpleDef)
commandString := "print help"
got, _ := newSlash.Execute(commandString)
assert.Equal(t, want, got)

//just test the first line, to avoid so this doesn't have to be maintained while features are changeing so rapidly
firstLine := strings.Split(got, "\n")[0]
assert.Equal(t, firstLine, "#### /Print Help")
}

0 comments on commit 1402172

Please sign in to comment.