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 = ""
|
|
|
|
|
proc eventHandler(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
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)
|
|
|
|
|
|
2025-02-13 14:55:45 +01:00
|
|
|
test "Multiple events":
|
|
|
|
|
var counter = 0
|
|
|
|
|
proc eventHandler(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
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 = ""
|
|
|
|
|
proc eventHandler1(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
data1 = e.s
|
|
|
|
|
success()
|
|
|
|
|
|
|
|
|
|
proc eventHandler2(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
data2 = e.s
|
|
|
|
|
success()
|
|
|
|
|
|
|
|
|
|
proc eventHandler3(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
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":
|
|
|
|
|
proc eventHandler(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
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 = ""
|
|
|
|
|
|
|
|
|
|
proc handler1(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
data1 = e.s
|
|
|
|
|
success()
|
2025-02-10 15:34:41 +01:00
|
|
|
|
2025-02-10 13:51:26 +01:00
|
|
|
proc handler2(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
data2 = e.s
|
|
|
|
|
success()
|
2025-02-10 15:34:41 +01:00
|
|
|
|
2025-02-10 13:51:26 +01:00
|
|
|
proc handler3(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
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":
|
|
|
|
|
proc doNothing() {.async, closure.} =
|
|
|
|
|
await sleepAsync(1.millis)
|
|
|
|
|
|
|
|
|
|
var callback = doNothing
|
|
|
|
|
|
|
|
|
|
proc eventHandler(e: ExampleData): Future[?!void] {.async.} =
|
|
|
|
|
await callback()
|
|
|
|
|
success()
|
|
|
|
|
|
|
|
|
|
let s = event.subscribe(eventHandler)
|
|
|
|
|
|
|
|
|
|
proc doUnsubscribe() {.async.} =
|
|
|
|
|
await event.unsubscribe(s)
|
|
|
|
|
|
|
|
|
|
callback = doUnsubscribe
|
|
|
|
|
|
|
|
|
|
check:
|
|
|
|
|
isOK(await event.fire(ExampleData(s: msg)))
|
|
|
|
|
|
|
|
|
|
await event.unsubscribe(s)
|