177 lines
3.9 KiB
Nim
Raw Normal View History

2025-02-10 13:51:26 +01:00
import pkg/chronos
import pkg/questionable
import pkg/questionable/results
import pkg/asynctest/chronos/unittest
import ../../../codexcrawler/utils/asyncdataevent
2025-02-10 15:34:41 +01:00
type ExampleData = object
s: string
2025-02-10 13:51:26 +01:00
suite "AsyncDataEvent":
var event: AsyncDataEvent[ExampleData]
let msg = "Yeah!"
setup:
event = newAsyncDataEvent[ExampleData]()
teardown:
await event.unsubscribeAll()
test "Successful event":
var data = ""
2025-06-02 16:16:41 +02:00
proc eventHandler(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-10 13:51:26 +01:00
data = e.s
success()
let s = event.subscribe(eventHandler)
check:
2025-02-10 15:34:41 +01:00
isOK(await event.fire(ExampleData(s: msg)))
2025-02-10 13:51:26 +01:00
data == msg
await event.unsubscribe(s)
test "Multiple events":
var counter = 0
2025-06-02 16:16:41 +02:00
proc eventHandler(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
inc counter
success()
let s = event.subscribe(eventHandler)
check:
isOK(await event.fire(ExampleData(s: msg)))
isOK(await event.fire(ExampleData(s: msg)))
isOK(await event.fire(ExampleData(s: msg)))
counter == 3
await event.unsubscribe(s)
test "Multiple subscribers":
var
data1 = ""
data2 = ""
data3 = ""
2025-06-02 16:16:41 +02:00
proc eventHandler1(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
data1 = e.s
success()
2025-06-02 16:16:41 +02:00
proc eventHandler2(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
data2 = e.s
success()
2025-06-02 16:16:41 +02:00
proc eventHandler3(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
data3 = e.s
success()
let
sub1 = event.subscribe(eventHandler1)
sub2 = event.subscribe(eventHandler2)
sub3 = event.subscribe(eventHandler3)
check:
isOK(await event.fire(ExampleData(s: msg)))
data1 == msg
data2 == msg
data3 == msg
await event.unsubscribe(sub1)
await event.unsubscribe(sub2)
await event.unsubscribe(sub3)
2025-02-10 13:51:26 +01:00
test "Failed event preserves error message":
2025-06-02 16:16:41 +02:00
proc eventHandler(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-10 13:51:26 +01:00
failure(msg)
let s = event.subscribe(eventHandler)
2025-02-10 15:34:41 +01:00
let fireResult = await event.fire(ExampleData(s: "a"))
2025-02-10 13:51:26 +01:00
check:
fireResult.isErr
fireResult.error.msg == msg
await event.unsubscribe(s)
test "Emits data to multiple subscribers":
var
data1 = ""
data2 = ""
data3 = ""
2025-06-02 16:16:41 +02:00
proc handler1(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-10 13:51:26 +01:00
data1 = e.s
success()
2025-02-10 15:34:41 +01:00
2025-06-02 16:16:41 +02:00
proc handler2(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-10 13:51:26 +01:00
data2 = e.s
success()
2025-02-10 15:34:41 +01:00
2025-06-02 16:16:41 +02:00
proc handler3(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-10 13:51:26 +01:00
data3 = e.s
success()
let
s1 = event.subscribe(handler1)
s2 = event.subscribe(handler2)
s3 = event.subscribe(handler3)
2025-02-10 15:34:41 +01:00
let fireResult = await event.fire(ExampleData(s: msg))
2025-02-10 13:51:26 +01:00
check:
fireResult.isOK
data1 == msg
data2 == msg
data3 == msg
await event.unsubscribe(s1)
await event.unsubscribe(s2)
await event.unsubscribe(s3)
2025-02-11 12:42:20 +01:00
2025-02-11 15:03:56 +01:00
test "Can fire and event without subscribers":
check:
isOK(await event.fire(ExampleData(s: msg)))
2025-02-11 12:42:20 +01:00
test "Can unsubscribe in handler":
2025-06-02 15:30:12 +02:00
proc doNothing() {.async: (raises: [CancelledError]), closure.} =
2025-02-11 12:42:20 +01:00
await sleepAsync(1.millis)
var callback = doNothing
2025-06-02 16:16:41 +02:00
proc eventHandler(
e: ExampleData
): Future[?!void] {.async: (raises: [CancelledError]).} =
2025-02-11 12:42:20 +01:00
await callback()
success()
let s = event.subscribe(eventHandler)
2025-06-02 15:30:12 +02:00
proc doUnsubscribe() {.async: (raises: [CancelledError]).} =
2025-02-11 12:42:20 +01:00
await event.unsubscribe(s)
callback = doUnsubscribe
check:
isOK(await event.fire(ExampleData(s: msg)))
await event.unsubscribe(s)