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