Timer control for deterministic timeout testing.
This namespace provides utilities for mocking and controlling timers in Fulcro tests. This is particularly useful for testing:
com.fulcrologic.fulcro.algorithms.scheduling/deferExample:
(with-mock-timers
(uism/begin! app LoginMachine ::login {:actor/form LoginForm} {})
(uism/trigger! app ::login :submit {:username "test"})
;; Advance time to trigger timeout
(advance-time! 5001)
;; Timer callbacks have now fired
(is (= :error (uism/get-active-state app ::login))))
Timer control for deterministic timeout testing.
This namespace provides utilities for mocking and controlling timers
in Fulcro tests. This is particularly useful for testing:
- UI State Machine timeouts
- Dynamic routing delay/error timers
- Debounced operations
- Any code that uses `com.fulcrologic.fulcro.algorithms.scheduling/defer`
Example:
```clojure
(with-mock-timers
(uism/begin! app LoginMachine ::login {:actor/form LoginForm} {})
(uism/trigger! app ::login :submit {:username "test"})
;; Advance time to trigger timeout
(advance-time! 5001)
;; Timer callbacks have now fired
(is (= :error (uism/get-active-state app ::login))))
```When bound, holds the current mock time in milliseconds.
When bound, holds the current mock time in milliseconds.
When bound, holds an atom containing pending timer entries. Each entry: {:id unique-id :fire-at ms :callback fn :active volatile}
When bound, holds an atom containing pending timer entries.
Each entry: {:id unique-id :fire-at ms :callback fn :active volatile}Counter for generating unique timer IDs.
Counter for generating unique timer IDs.
(advance-time! ms)Advance the mock time by the given number of milliseconds. Fires any timers whose time has come.
Returns the new mock time.
Advance the mock time by the given number of milliseconds. Fires any timers whose time has come. Returns the new mock time.
(advance-to-next-timer!)Advance time to the next pending timer and fire it. Returns the new mock time, or nil if no timers pending.
Advance time to the next pending timer and fire it. Returns the new mock time, or nil if no timers pending.
(clear-timers!)Cancel and remove all pending timers without firing them.
Returns the number of timers cleared.
Cancel and remove all pending timers without firing them. Returns the number of timers cleared.
(fire-all-timers!)Fire all pending timers immediately, regardless of their scheduled time. Timers are fired in order of their scheduled time.
Returns the number of timers fired.
Fire all pending timers immediately, regardless of their scheduled time. Timers are fired in order of their scheduled time. Returns the number of timers fired.
(has-timer-with-delay? delay-ms & {:keys [tolerance] :or {tolerance 10}})Check if there's a pending timer with approximately the given delay. Useful for verifying the correct timeout was scheduled.
Check if there's a pending timer with approximately the given delay. Useful for verifying the correct timeout was scheduled.
(mock-time)Get the current mock time, or real time if not mocking.
Get the current mock time, or real time if not mocking.
(next-timer-at)Get the fire-at time of the next pending timer, or nil if none.
Get the fire-at time of the next pending timer, or nil if none.
(pending-timer-count)Get the count of pending timers.
Get the count of pending timers.
(pending-timers)Get all pending timers when in mock mode. Returns nil if not in mock mode.
Get all pending timers when in mock mode. Returns nil if not in mock mode.
(set-time! ms)Set the mock time to an absolute value. Fires any timers whose time has come.
Returns the new mock time.
Set the mock time to an absolute value. Fires any timers whose time has come. Returns the new mock time.
(timer-info)Get information about pending timers. Returns a sequence of maps with :delay-ms and :fire-at keys.
Get information about pending timers. Returns a sequence of maps with :delay-ms and :fire-at keys.
(with-mock-timers & body)Execute body with mocked timers.
Within this block:
sched/defer are captured instead of actually schedulingadvance-time! to move time forward and trigger timersfire-all-timers! to fire all pending timers immediatelypending-timers to inspect what's scheduledExample:
(with-mock-timers
;; Start something that sets a timeout
(uism/trigger! app ::login :submit {})
;; Check that a timer was scheduled
(is (= 1 (pending-timer-count)))
;; Advance time to fire the timer
(advance-time! 5000)
;; Timer callback has now executed
(is (= :timeout-state (uism/get-active-state app ::login))))
Execute body with mocked timers.
Within this block:
- All calls to `sched/defer` are captured instead of actually scheduling
- Use `advance-time!` to move time forward and trigger timers
- Use `fire-all-timers!` to fire all pending timers immediately
- Use `pending-timers` to inspect what's scheduled
Example:
```clojure
(with-mock-timers
;; Start something that sets a timeout
(uism/trigger! app ::login :submit {})
;; Check that a timer was scheduled
(is (= 1 (pending-timer-count)))
;; Advance time to fire the timer
(advance-time! 5000)
;; Timer callback has now executed
(is (= :timeout-state (uism/get-active-state app ::login))))
```(with-mock-timers-from start-time & body)Like with-mock-timers but starts at a specific time.
Example:
(with-mock-timers-from 1000
(advance-time! 500)
(is (= 1500 (mock-time))))
Like `with-mock-timers` but starts at a specific time. Example: ```clojure (with-mock-timers-from 1000 (advance-time! 500) (is (= 1500 (mock-time)))) ```
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |