arikawa/utils/handler/handler_test.go

302 lines
5.4 KiB
Go
Raw Normal View History

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
"github.com/diamondburned/arikawa/discord"
2020-01-17 02:08:03 +00:00
"github.com/diamondburned/arikawa/gateway"
)
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)
h := &Handler{
handlers: map[uint64]handler{},
}
// Add handler test
rm := h.AddHandler(func(m *gateway.MessageCreateEvent) {
results <- m.Content
})
go h.Call(newMessage("hime arikawa"))
2020-01-17 05:20:09 +00:00
if r := <-results; r != "hime arikawa" {
2020-01-17 05:20:09 +00:00
t.Fatal("Returned results is wrong:", r)
}
// Delete handler test
2020-01-17 05:20:09 +00:00
rm()
go h.Call(newMessage("astolfo"))
2020-01-17 05:20:09 +00:00
select {
case <-results:
t.Fatal("Unexpected results")
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)
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"
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)
}
}
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)
}
}
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.
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{})
// Call in a goroutine, which would trigger a close.
2020-07-19 01:25:00 +00:00
go func() { h.call(msgV); die <- struct{}{} }()
// 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
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-01-17 05:17:46 +00:00
func TestHandlerInterface(t *testing.T) {
var results = make(chan interface{})
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"
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)
}
func TestHandlerWaitFor(t *testing.T) {
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
})
}()
// 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)
}
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)
}
}
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,
}
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
})
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) {
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)
}
}