A clock for tests: the current time pinned in the calling process.
A test pins the time before it exercises code that reads the current
time through Tempo.utc_now/0, Tempo.now/1, Tempo.utc_today/0 or
Tempo.today/1:
test "renews a subscription at renewal time" do
Tempo.Clock.Test.put(~U[2026-06-15 12:00:00Z])
assert Subscription.should_renew?(subscription)
endput/1 makes this the clock of the calling process, so no
configuration is needed. A suite that names it in config/test.exs
(config :ex_tempo, clock: Tempo.Clock.Test), as Tempo 1.6 asked, is
read the same way, and a process that asks the time before it pins one
is a Tempo.ClockError rather than the system's time.
The time is held in the process dictionary, so each test has its own,
and tests run with async: true do not see one another's. advance/1
moves it on, and reset/0 clears it.
Summary
Functions
Moves the pinned time on by a number of seconds, or back for a negative number.
Pins the time of the calling process, and makes this its clock.
Clears the pinned time from the calling process, and with it this process's choice of this clock.
The time pinned in the calling process.
Functions
@spec advance(integer()) :: :ok
Moves the pinned time on by a number of seconds, or back for a negative number.
Arguments
secondsis an integer.
Returns
:ok. Raises aTempo.ClockErrorin a process that has pinned no time.
Examples
iex> Tempo.Clock.Test.put(~U[2026-06-15 12:00:00Z])
iex> Tempo.Clock.Test.advance(3600)
:ok
iex> Tempo.Clock.Test.utc_now()
~U[2026-06-15 13:00:00Z]
@spec put(DateTime.t()) :: :ok
Pins the time of the calling process, and makes this its clock.
Arguments
date_timeis aDateTime.t/0in any zone. It is held as the same instant inEtc/UTC.
Returns
:ok.
Examples
iex> Tempo.Clock.Test.put(~U[2026-06-15 12:00:00Z])
:ok
iex> Tempo.utc_now()
~o"2026-06-15T12:00:00Z"
@spec reset() :: :ok
Clears the pinned time from the calling process, and with it this process's choice of this clock.
Returns
:ok.
Examples
iex> Tempo.Clock.Test.put(~U[2026-06-15 12:00:00Z])
iex> Tempo.Clock.Test.reset()
:ok
iex> Tempo.Clock.clock()
Tempo.Clock.System
@spec utc_now() :: DateTime.t()
The time pinned in the calling process.
Returns
- The pinned
DateTime.t/0, inEtc/UTC. Raises aTempo.ClockErrorin a process that has pinned none.
Examples
iex> Tempo.Clock.Test.put(~U[2026-06-15 12:00:00Z])
iex> Tempo.Clock.Test.utc_now()
~U[2026-06-15 12:00:00Z]