github.com/diamondburned/arikawa@v1.3.14/utils/handler/handler_test.go (about) 1 package handler 2 3 import ( 4 "context" 5 "reflect" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/diamondburned/arikawa/discord" 11 "github.com/diamondburned/arikawa/gateway" 12 ) 13 14 func newMessage(content string) *gateway.MessageCreateEvent { 15 return &gateway.MessageCreateEvent{ 16 Message: discord.Message{Content: content}, 17 } 18 } 19 20 func TestCall(t *testing.T) { 21 var results = make(chan string) 22 23 h := &Handler{ 24 handlers: map[uint64]handler{}, 25 } 26 27 // Add handler test 28 rm := h.AddHandler(func(m *gateway.MessageCreateEvent) { 29 results <- m.Content 30 }) 31 32 go h.Call(newMessage("hime arikawa")) 33 34 if r := <-results; r != "hime arikawa" { 35 t.Fatal("Returned results is wrong:", r) 36 } 37 38 // Delete handler test 39 rm() 40 41 go h.Call(newMessage("astolfo")) 42 43 select { 44 case <-results: 45 t.Fatal("Unexpected results") 46 case <-time.After(5 * time.Millisecond): 47 break 48 } 49 50 // Invalid type test 51 _, err := h.AddHandlerCheck("this should panic") 52 if err == nil { 53 t.Fatal("No errors found") 54 } 55 56 // We don't do anything with the returned callback, as there's none. 57 58 if !strings.Contains(err.Error(), "given interface is not a function") { 59 t.Fatal("Unexpected error:", err) 60 } 61 } 62 63 func TestHandler(t *testing.T) { 64 var results = make(chan string) 65 66 h, err := newHandler(func(m *gateway.MessageCreateEvent) { 67 results <- m.Content 68 }) 69 if err != nil { 70 t.Fatal(err) 71 } 72 73 const result = "Hime Arikawa" 74 var msg = newMessage(result) 75 76 var msgV = reflect.ValueOf(msg) 77 var msgT = msgV.Type() 78 79 if h.not(msgT) { 80 t.Fatal("Event type mismatch") 81 } 82 83 go h.call(msgV) 84 85 if results := <-results; results != result { 86 t.Fatal("Unexpected results:", results) 87 } 88 } 89 90 func TestHandlerChan(t *testing.T) { 91 var results = make(chan *gateway.MessageCreateEvent) 92 93 h, err := newHandler(results) 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 const result = "Hime Arikawa" 99 var msg = newMessage(result) 100 101 var msgV = reflect.ValueOf(msg) 102 var msgT = msgV.Type() 103 104 if h.not(msgT) { 105 t.Fatal("Event type mismatch") 106 } 107 108 go h.call(msgV) 109 110 if results := <-results; results.Content != result { 111 t.Fatal("Unexpected results:", results) 112 } 113 } 114 115 func TestHandlerChanCancel(t *testing.T) { 116 // Never receive from this channel. It is important that this channel is 117 // unbuffered. 118 var results = make(chan *gateway.MessageCreateEvent) 119 120 h, err := newHandler(results) 121 if err != nil { 122 t.Fatal(err) 123 } 124 125 const result = "Hime Arikawa" 126 var msg = newMessage(result) 127 128 var msgV = reflect.ValueOf(msg) 129 var msgT = msgV.Type() 130 131 if h.not(msgT) { 132 t.Fatal("Event type mismatch") 133 } 134 135 // Channel that waits for call() to die. 136 die := make(chan struct{}) 137 138 // Call in a goroutine, which would trigger a close. 139 go func() { h.call(msgV); die <- struct{}{} }() 140 141 // Call the cleanup function, which should stop the send. 142 h.cleanup() 143 144 // Check if we still have things being sent. 145 select { 146 case <-die: 147 // pass 148 case <-time.After(200 * time.Millisecond): 149 t.Fatal("Timed out waiting for call routine to die.") 150 } 151 152 // Check if we still receive something. 153 select { 154 case <-results: 155 t.Fatal("Unexpected results received.") 156 default: 157 // pass 158 } 159 } 160 161 func TestHandlerInterface(t *testing.T) { 162 var results = make(chan interface{}) 163 164 h, err := newHandler(func(m interface{}) { 165 results <- m 166 }) 167 if err != nil { 168 t.Fatal(err) 169 } 170 171 const result = "Hime Arikawa" 172 var msg = newMessage(result) 173 174 var msgV = reflect.ValueOf(msg) 175 var msgT = msgV.Type() 176 177 if h.not(msgT) { 178 t.Fatal("Event type mismatch") 179 } 180 181 go h.call(msgV) 182 recv := <-results 183 184 if msg, ok := recv.(*gateway.MessageCreateEvent); ok { 185 if msg.Content == result { 186 return 187 } 188 189 t.Fatal("Content mismatch:", msg.Content) 190 } 191 192 t.Fatal("Assertion failed:", recv) 193 } 194 195 func TestHandlerWaitFor(t *testing.T) { 196 inc := make(chan interface{}, 1) 197 198 h := New() 199 200 wanted := &gateway.TypingStartEvent{ 201 ChannelID: 123456, 202 } 203 204 evs := []interface{}{ 205 &gateway.TypingStartEvent{}, 206 &gateway.MessageCreateEvent{}, 207 &gateway.ChannelDeleteEvent{}, 208 wanted, 209 } 210 211 go func() { 212 inc <- h.WaitFor(context.Background(), func(v interface{}) bool { 213 tp, ok := v.(*gateway.TypingStartEvent) 214 if !ok { 215 return false 216 } 217 218 return tp.ChannelID == wanted.ChannelID 219 }) 220 }() 221 222 // Wait for WaitFor to add its handler: 223 time.Sleep(time.Millisecond) 224 225 for _, ev := range evs { 226 h.Call(ev) 227 } 228 229 recv := <-inc 230 if recv != wanted { 231 t.Fatal("Unexpected receive:", recv) 232 } 233 234 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 235 defer cancel() 236 237 // Test timeout 238 v := h.WaitFor(ctx, func(v interface{}) bool { 239 return false 240 }) 241 242 if v != nil { 243 t.Fatal("Unexpected value:", v) 244 } 245 } 246 247 func TestHandlerChanFor(t *testing.T) { 248 h := New() 249 250 wanted := &gateway.TypingStartEvent{ 251 ChannelID: 123456, 252 } 253 254 evs := []interface{}{ 255 &gateway.TypingStartEvent{}, 256 &gateway.MessageCreateEvent{}, 257 &gateway.ChannelDeleteEvent{}, 258 wanted, 259 } 260 261 inc, cancel := h.ChanFor(func(v interface{}) bool { 262 tp, ok := v.(*gateway.TypingStartEvent) 263 if !ok { 264 return false 265 } 266 267 return tp.ChannelID == wanted.ChannelID 268 }) 269 defer cancel() 270 271 for _, ev := range evs { 272 h.Call(ev) 273 } 274 275 recv := <-inc 276 if recv != wanted { 277 t.Fatal("Unexpected receive:", recv) 278 } 279 } 280 281 func BenchmarkReflect(b *testing.B) { 282 h, err := newHandler(func(m *gateway.MessageCreateEvent) {}) 283 if err != nil { 284 b.Fatal(err) 285 } 286 287 var msg = &gateway.MessageCreateEvent{} 288 289 b.ResetTimer() 290 291 for n := 0; n < b.N; n++ { 292 var msgV = reflect.ValueOf(msg) 293 var msgT = msgV.Type() 294 295 if h.not(msgT) { 296 b.Fatal("Event type mismatch") 297 } 298 299 h.call(msgV) 300 } 301 }