2020-01-17 05:17:46 +00:00
|
|
|
package handler
|
2020-01-17 02:08:03 +00:00
|
|
|
|
|
|
|
import (
|
2020-02-05 04:30:17 +00:00
|
|
|
"context"
|
2020-01-17 02:08:03 +00:00
|
|
|
"reflect"
|
2020-01-17 05:20:09 +00:00
|
|
|
"strings"
|
2020-01-17 02:08:03 +00:00
|
|
|
"testing"
|
2020-01-17 05:20:09 +00:00
|
|
|
"time"
|
2020-01-17 02:08:03 +00:00
|
|
|
|
2020-10-28 22:39:59 +00:00
|
|
|
"github.com/diamondburned/arikawa/v2/discord"
|
|
|
|
"github.com/diamondburned/arikawa/v2/gateway"
|
2020-01-17 02:08:03 +00:00
|
|
|
)
|
|
|
|
|
2020-04-12 23:24:28 +00:00
|
|
|
func newMessage(content string) *gateway.MessageCreateEvent {
|
|
|
|
return &gateway.MessageCreateEvent{
|
|
|
|
Message: discord.Message{Content: content},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-17 05:20:09 +00:00
|
|
|
func TestCall(t *testing.T) {
|
|
|
|
var results = make(chan string)
|
|
|
|
|
2020-10-29 06:55:39 +00:00
|
|
|
h := &Handler{}
|
2020-01-17 05:20:09 +00:00
|
|
|
|
|
|
|
// Add handler test
|
|
|
|
rm := h.AddHandler(func(m *gateway.MessageCreateEvent) {
|
|
|
|
results <- m.Content
|
|
|
|
})
|
|
|
|
|
2020-04-12 23:24:28 +00:00
|
|
|
go h.Call(newMessage("hime arikawa"))
|
2020-01-17 05:20:09 +00:00
|
|
|
|
2020-04-12 23:24:28 +00:00
|
|
|
if r := <-results; r != "hime arikawa" {
|
2020-01-17 05:20:09 +00:00
|
|
|
t.Fatal("Returned results is wrong:", r)
|
|
|
|
}
|
|
|
|
|
2020-06-06 20:47:15 +00:00
|
|
|
// Delete handler test
|
2020-01-17 05:20:09 +00:00
|
|
|
rm()
|
|
|
|
|
2020-04-12 23:24:28 +00:00
|
|
|
go h.Call(newMessage("astolfo"))
|
2020-01-17 05:20:09 +00:00
|
|
|
|
|
|
|
select {
|
|
|
|
case <-results:
|
|
|
|
t.Fatal("Unexpected results")
|
2020-04-12 23:24:28 +00:00
|
|
|
case <-time.After(5 * time.Millisecond):
|
2020-01-17 05:20:09 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invalid type test
|
|
|
|
_, err := h.AddHandlerCheck("this should panic")
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("No errors found")
|
|
|
|
}
|
|
|
|
|
|
|
|
// We don't do anything with the returned callback, as there's none.
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "given interface is not a function") {
|
|
|
|
t.Fatal("Unexpected error:", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-17 05:17:46 +00:00
|
|
|
func TestHandler(t *testing.T) {
|
2020-01-17 02:08:03 +00:00
|
|
|
var results = make(chan string)
|
|
|
|
|
2020-07-15 06:57:50 +00:00
|
|
|
h, err := newHandler(func(m *gateway.MessageCreateEvent) {
|
2020-01-17 02:08:03 +00:00
|
|
|
results <- m.Content
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = "Hime Arikawa"
|
2020-04-12 23:24:28 +00:00
|
|
|
var msg = newMessage(result)
|
2020-01-17 02:08:03 +00:00
|
|
|
|
|
|
|
var msgV = reflect.ValueOf(msg)
|
|
|
|
var msgT = msgV.Type()
|
|
|
|
|
|
|
|
if h.not(msgT) {
|
|
|
|
t.Fatal("Event type mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
go h.call(msgV)
|
|
|
|
|
|
|
|
if results := <-results; results != result {
|
|
|
|
t.Fatal("Unexpected results:", results)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 06:57:50 +00:00
|
|
|
func TestHandlerChan(t *testing.T) {
|
|
|
|
var results = make(chan *gateway.MessageCreateEvent)
|
|
|
|
|
|
|
|
h, err := newHandler(results)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = "Hime Arikawa"
|
|
|
|
var msg = newMessage(result)
|
|
|
|
|
|
|
|
var msgV = reflect.ValueOf(msg)
|
|
|
|
var msgT = msgV.Type()
|
|
|
|
|
|
|
|
if h.not(msgT) {
|
|
|
|
t.Fatal("Event type mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
go h.call(msgV)
|
|
|
|
|
|
|
|
if results := <-results; results.Content != result {
|
|
|
|
t.Fatal("Unexpected results:", results)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-16 06:11:20 +00:00
|
|
|
func TestHandlerChanCancel(t *testing.T) {
|
2020-07-19 01:25:00 +00:00
|
|
|
// Never receive from this channel. It is important that this channel is
|
|
|
|
// unbuffered.
|
2020-07-16 06:11:20 +00:00
|
|
|
var results = make(chan *gateway.MessageCreateEvent)
|
|
|
|
|
|
|
|
h, err := newHandler(results)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = "Hime Arikawa"
|
|
|
|
var msg = newMessage(result)
|
|
|
|
|
|
|
|
var msgV = reflect.ValueOf(msg)
|
|
|
|
var msgT = msgV.Type()
|
|
|
|
|
|
|
|
if h.not(msgT) {
|
|
|
|
t.Fatal("Event type mismatch")
|
|
|
|
}
|
|
|
|
|
2020-07-19 01:25:00 +00:00
|
|
|
// Channel that waits for call() to die.
|
|
|
|
die := make(chan struct{})
|
|
|
|
|
2020-07-16 06:11:20 +00:00
|
|
|
// Call in a goroutine, which would trigger a close.
|
2020-07-19 01:25:00 +00:00
|
|
|
go func() { h.call(msgV); die <- struct{}{} }()
|
2020-07-16 06:11:20 +00:00
|
|
|
|
|
|
|
// Call the cleanup function, which should stop the send.
|
|
|
|
h.cleanup()
|
|
|
|
|
|
|
|
// Check if we still have things being sent.
|
|
|
|
select {
|
2020-07-19 01:25:00 +00:00
|
|
|
case <-die:
|
|
|
|
// pass
|
2020-07-16 06:11:20 +00:00
|
|
|
case <-time.After(200 * time.Millisecond):
|
2020-07-19 01:25:00 +00:00
|
|
|
t.Fatal("Timed out waiting for call routine to die.")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if we still receive something.
|
|
|
|
select {
|
|
|
|
case <-results:
|
|
|
|
t.Fatal("Unexpected results received.")
|
|
|
|
default:
|
|
|
|
// pass
|
2020-07-16 06:11:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-17 05:17:46 +00:00
|
|
|
func TestHandlerInterface(t *testing.T) {
|
|
|
|
var results = make(chan interface{})
|
|
|
|
|
2020-07-15 06:57:50 +00:00
|
|
|
h, err := newHandler(func(m interface{}) {
|
2020-01-17 05:17:46 +00:00
|
|
|
results <- m
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = "Hime Arikawa"
|
2020-04-12 23:24:28 +00:00
|
|
|
var msg = newMessage(result)
|
2020-01-17 05:17:46 +00:00
|
|
|
|
|
|
|
var msgV = reflect.ValueOf(msg)
|
|
|
|
var msgT = msgV.Type()
|
|
|
|
|
|
|
|
if h.not(msgT) {
|
|
|
|
t.Fatal("Event type mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
go h.call(msgV)
|
|
|
|
recv := <-results
|
|
|
|
|
|
|
|
if msg, ok := recv.(*gateway.MessageCreateEvent); ok {
|
|
|
|
if msg.Content == result {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Fatal("Content mismatch:", msg.Content)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Fatal("Assertion failed:", recv)
|
|
|
|
}
|
|
|
|
|
2020-07-15 06:57:50 +00:00
|
|
|
func TestHandlerWaitFor(t *testing.T) {
|
2020-03-04 02:51:24 +00:00
|
|
|
inc := make(chan interface{}, 1)
|
2020-02-05 04:30:17 +00:00
|
|
|
|
|
|
|
h := New()
|
|
|
|
|
|
|
|
wanted := &gateway.TypingStartEvent{
|
|
|
|
ChannelID: 123456,
|
|
|
|
}
|
|
|
|
|
|
|
|
evs := []interface{}{
|
|
|
|
&gateway.TypingStartEvent{},
|
|
|
|
&gateway.MessageCreateEvent{},
|
|
|
|
&gateway.ChannelDeleteEvent{},
|
|
|
|
wanted,
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
inc <- h.WaitFor(context.Background(), func(v interface{}) bool {
|
|
|
|
tp, ok := v.(*gateway.TypingStartEvent)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return tp.ChannelID == wanted.ChannelID
|
|
|
|
})
|
|
|
|
}()
|
|
|
|
|
2020-03-04 02:51:24 +00:00
|
|
|
// Wait for WaitFor to add its handler:
|
|
|
|
time.Sleep(time.Millisecond)
|
2020-02-05 04:30:17 +00:00
|
|
|
|
|
|
|
for _, ev := range evs {
|
|
|
|
h.Call(ev)
|
|
|
|
}
|
|
|
|
|
2020-03-04 02:51:24 +00:00
|
|
|
recv := <-inc
|
2020-02-05 04:30:17 +00:00
|
|
|
if recv != wanted {
|
|
|
|
t.Fatal("Unexpected receive:", recv)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Test timeout
|
|
|
|
v := h.WaitFor(ctx, func(v interface{}) bool {
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
if v != nil {
|
|
|
|
t.Fatal("Unexpected value:", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 06:57:50 +00:00
|
|
|
func TestHandlerChanFor(t *testing.T) {
|
2020-02-05 04:30:17 +00:00
|
|
|
h := New()
|
|
|
|
|
|
|
|
wanted := &gateway.TypingStartEvent{
|
|
|
|
ChannelID: 123456,
|
|
|
|
}
|
|
|
|
|
|
|
|
evs := []interface{}{
|
|
|
|
&gateway.TypingStartEvent{},
|
|
|
|
&gateway.MessageCreateEvent{},
|
|
|
|
&gateway.ChannelDeleteEvent{},
|
|
|
|
wanted,
|
|
|
|
}
|
|
|
|
|
2020-03-04 02:51:24 +00:00
|
|
|
inc, cancel := h.ChanFor(func(v interface{}) bool {
|
2020-02-05 04:30:17 +00:00
|
|
|
tp, ok := v.(*gateway.TypingStartEvent)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return tp.ChannelID == wanted.ChannelID
|
|
|
|
})
|
2020-03-04 02:51:24 +00:00
|
|
|
defer cancel()
|
2020-02-05 04:30:17 +00:00
|
|
|
|
|
|
|
for _, ev := range evs {
|
|
|
|
h.Call(ev)
|
|
|
|
}
|
|
|
|
|
|
|
|
recv := <-inc
|
|
|
|
if recv != wanted {
|
|
|
|
t.Fatal("Unexpected receive:", recv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-17 02:08:03 +00:00
|
|
|
func BenchmarkReflect(b *testing.B) {
|
2020-07-15 06:57:50 +00:00
|
|
|
h, err := newHandler(func(m *gateway.MessageCreateEvent) {})
|
2020-01-17 02:08:03 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var msg = &gateway.MessageCreateEvent{}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
var msgV = reflect.ValueOf(msg)
|
|
|
|
var msgT = msgV.Type()
|
|
|
|
|
|
|
|
if h.not(msgT) {
|
|
|
|
b.Fatal("Event type mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
h.call(msgV)
|
|
|
|
}
|
|
|
|
}
|