Add `eventually` to wait for a condition to become true
This commit is contained in:
parent
a236a5f0f3
commit
c8d324cfa6
20
Readme.md
20
Readme.md
|
@ -58,6 +58,26 @@ last resort when setting up the test environment is very costly. Be careful that
|
||||||
the tests do not modify the environment that you set up, lest you introduce
|
the tests do not modify the environment that you set up, lest you introduce
|
||||||
dependencies between tests.
|
dependencies between tests.
|
||||||
|
|
||||||
|
check eventually
|
||||||
|
----------------
|
||||||
|
|
||||||
|
When you find yourself adding calls to `sleepAsync` to your tests, you might
|
||||||
|
want to consider using `check eventually` instead. It will repeatedly check
|
||||||
|
an expression until it becomes true. It has a built-in timeout of 5 seconds that
|
||||||
|
you can override.
|
||||||
|
|
||||||
|
```nim
|
||||||
|
var x: int
|
||||||
|
|
||||||
|
proc slowProcedure {.async.} =
|
||||||
|
# perform a slow operation
|
||||||
|
x = 42
|
||||||
|
|
||||||
|
let future = slowProcedure()
|
||||||
|
check eventually x == 42
|
||||||
|
await future
|
||||||
|
```
|
||||||
|
|
||||||
Unittest2
|
Unittest2
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import std/times
|
||||||
|
|
||||||
|
template eventually*(expression: untyped, timeout=5000): bool =
|
||||||
|
|
||||||
|
template sleep(millis: int): auto =
|
||||||
|
when compiles(await sleepAsync(millis.milliseconds)):
|
||||||
|
sleepAsync(millis.milliseconds) # chronos
|
||||||
|
else:
|
||||||
|
sleepAsync(millis) # asyncdispatch
|
||||||
|
|
||||||
|
proc eventually: Future[bool] {.async.} =
|
||||||
|
let endTime = getTime() + initDuration(milliseconds=timeout)
|
||||||
|
while not expression:
|
||||||
|
if endTime < getTime():
|
||||||
|
return false
|
||||||
|
await sleep(10)
|
||||||
|
return true
|
||||||
|
|
||||||
|
await eventually()
|
|
@ -1,4 +1,7 @@
|
||||||
import std/unittest
|
import std/unittest
|
||||||
|
import ./eventually
|
||||||
|
|
||||||
export unittest except suite, test
|
export unittest except suite, test
|
||||||
|
export eventually
|
||||||
|
|
||||||
include ./templates
|
include ./templates
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import pkg/unittest2
|
import pkg/unittest2
|
||||||
|
import ./eventually
|
||||||
|
|
||||||
export unittest2 except suite, test
|
export unittest2 except suite, test
|
||||||
|
export eventually
|
||||||
|
|
||||||
include ./templates
|
include ./templates
|
||||||
|
|
|
@ -16,7 +16,7 @@ suite "test async proc":
|
||||||
# invoke await in tests:
|
# invoke await in tests:
|
||||||
await someAsyncProc()
|
await someAsyncProc()
|
||||||
|
|
||||||
suite "test async setupAll and teardownAll, allow multiple suites":
|
suite "setupAll and teardownAll":
|
||||||
|
|
||||||
setupAll:
|
setupAll:
|
||||||
# invoke await in the test setup:
|
# invoke await in the test setup:
|
||||||
|
@ -29,3 +29,46 @@ suite "test async setupAll and teardownAll, allow multiple suites":
|
||||||
test "async test":
|
test "async test":
|
||||||
# invoke await in tests:
|
# invoke await in tests:
|
||||||
await someAsyncProc()
|
await someAsyncProc()
|
||||||
|
|
||||||
|
from std/os import sleep
|
||||||
|
|
||||||
|
suite "eventually":
|
||||||
|
|
||||||
|
test "becomes true":
|
||||||
|
|
||||||
|
var tries = 0
|
||||||
|
|
||||||
|
proc becomesTrue: bool =
|
||||||
|
inc tries
|
||||||
|
tries == 3
|
||||||
|
|
||||||
|
check eventually becomesTrue()
|
||||||
|
|
||||||
|
test "becomes false after timeout":
|
||||||
|
|
||||||
|
proc remainsFalse: bool = false
|
||||||
|
|
||||||
|
check not eventually(remainsFalse(), timeout=100)
|
||||||
|
|
||||||
|
test "becomes true during timeout":
|
||||||
|
|
||||||
|
proc slowTrue: bool =
|
||||||
|
sleep(100)
|
||||||
|
true
|
||||||
|
|
||||||
|
check eventually(slowTrue(), timeout=50)
|
||||||
|
|
||||||
|
test "works with async procedures":
|
||||||
|
|
||||||
|
var x: int
|
||||||
|
|
||||||
|
proc slowProcedure {.async.} =
|
||||||
|
when compiles(await sleepAsync(100.milliseconds)):
|
||||||
|
await sleepAsync(100.milliseconds) # chronos
|
||||||
|
else:
|
||||||
|
await sleepAsync(100) # asyncdispatch
|
||||||
|
x = 42
|
||||||
|
|
||||||
|
let future = slowProcedure()
|
||||||
|
check eventually x == 42
|
||||||
|
await future
|
||||||
|
|
Loading…
Reference in New Issue