This repository has been archived by the owner on Dec 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dispatcher_test.go
196 lines (161 loc) · 5.37 KB
/
dispatcher_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package drouter_test
import (
"bytes"
"fmt"
"github.com/NyanKiyoshi/disgord-plugin-router"
"github.com/NyanKiyoshi/disgord-plugin-router/mocks/mocked_disgord"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"log"
"os"
"testing"
)
var routerDefinitionFindTests = []struct {
name string
in []string
shouldReturnRootCommand bool
shouldReturnSubCommand bool
}{
{"valid root command", []string{"?color"}, true, false},
{"valid root command (alias)", []string{"?colour"}, true, false},
{"invalid root command", []string{"?no"}, false, false},
{"valid sub command", []string{"?color", "blue"}, false, true},
{"invalid sub command => should invoke root", []string{"?color", "black"}, true, false},
{"no arguments", []string{}, false, false},
{"whitespace only", []string{" "}, false, false},
{"prefix only", []string{"?"}, false, false},
{"invalid prefix", []string{"!color"}, false, false},
}
func TestRouterDefinition_Find(t *testing.T) {
var (
foundCommand *drouter.Command
prefix string
)
router := createTestRouter()
plugin := router.Plugin(_myModuleInternalType{}, "color", "colour").SetPrefix("?")
// Should return nil as the plugin is not yet enabled
prefix, foundCommand = router.Find("color")
assert.Nil(t, foundCommand, "plugin should not be enabled")
assert.Empty(t, prefix, "prefix of a non found command should be empty")
// Add dummy commands
plugin.Command("red")
subCommand := plugin.Command("blue")
// Enable the plugin
plugin.Activate()
for _, tt := range routerDefinitionFindTests {
t.Run(fmt.Sprintf("%s: %s", tt.name, tt.in), func(t *testing.T) {
prefix, foundCommand = router.Find(tt.in...)
if tt.shouldReturnRootCommand {
assert.Equal(t, &plugin.RootCommand, foundCommand, "expected root command")
assert.Equal(t, "?", prefix)
} else if tt.shouldReturnSubCommand {
assert.Equal(t, subCommand, foundCommand, "expected sub command")
assert.Equal(t, "?", prefix)
} else {
assert.Nil(t, foundCommand, "expected nil, command should'nt because found")
assert.Empty(t, prefix, "prefix of a non found command should be empty")
}
})
}
}
func TestDispatchMessage_EverythingValid(t *testing.T) {
var (
WrapperCalled bool
CommandHandlerCalled bool
)
// Create a dummy command
command := createDummyCommand()
// Add a non-errored wrapper that we will check if it gets called
command.Use(func(ctx *drouter.Context) error {
WrapperCalled = true
return nil
})
// Add a non-errored command handler that we will check if it gets called
command.Handler(func(ctx *drouter.Context) error {
CommandHandlerCalled = true
return nil
})
// Execute the dispatcher, it is expected to succeed
isSuccessChan := make(chan bool, 1)
drouter.DispatchMessage(&drouter.Context{
Command: command,
}, isSuccessChan)
// Check if it was successful, as we expect
assert.True(t, <-isSuccessChan)
// Check if the wrapper and command handler were called
assert.True(t, WrapperCalled, "the command wrapper was not called")
assert.True(t, CommandHandlerCalled, "the command handler was not called")
}
func TestDispatchMessage_HandlesFuncErrors(t *testing.T) {
// Create a dummy command
command := createDummyCommand("ping")
var checkResultFunc = func(checkT *testing.T, discordAPIError error) {
// Create mocked session
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockedSession := mocked_disgord.NewMockrouterSession(mockCtrl)
// Create the test context
ctx := createDummyContext(mockedSession)
ctx.Command = command
ctx.MatchedPrefix = "!"
// Create the result channel
isSuccessChan := make(chan bool, 1)
// Prepare the mock
mockedSession.
EXPECT().
SendMsgString(channelID, successError.Error()).
Return(ctx.Message, discordAPIError)
// Execute the dispatcher, it is expected to succeed
drouter.DispatchMessage(ctx, isSuccessChan)
// Check if it was successful, as we expect
assert.False(checkT, <-isSuccessChan)
}
// Test wrapper errors are handled
t.Run("against wrapper", func(t *testing.T) {
oldWrappers := command.Wrappers
// Add a wrapper that will return an error
command.Use(func(ctx *drouter.Context) error {
return successError
})
checkResultFunc(t, nil)
command.Wrappers = oldWrappers
})
// Test command's handler errors are handled
t.Run("against command handler", func(t *testing.T) {
// Add a wrapper that will return an error
command.Handler(func(ctx *drouter.Context) error {
return successError
})
checkResultFunc(t, nil)
})
// Test if it failed to report an error to the user
// (e.g.: not enough permission), it reports to the logger instead.
t.Run("against discord API", func(t *testing.T) {
var dummyBuffer bytes.Buffer
log.SetOutput(&dummyBuffer)
defer log.SetOutput(os.Stderr)
checkResultFunc(t, successError)
// Check the error was sent
assert.Contains(
t, dummyBuffer.String(),
"failed to communicate prefix: ! / names: map[ping:{}]: success",
"wrong message error/ not called",
)
})
}
var parseMessageTests = []struct {
in string
out []string
}{
{"ping", []string{"ping"}},
{"ping pong", []string{"ping", "pong"}},
{" ", []string{}},
{"", []string{}},
}
func TestParseMessage(t *testing.T) {
for _, tt := range parseMessageTests {
t.Run(tt.in, func(t *testing.T) {
assert.EqualValues(t, tt.out, drouter.ParseMessage(tt.in))
})
}
}