Skip to main content

src/aion@testing@clock.erl

-module(aion@testing@clock).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aion/testing/clock.gleam").
-export([advance/2, current_time_milliseconds/1]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(
    " Simulated clock helpers for `aion/testing`.\n"
    "\n"
    " Advancing the clock updates process-scoped harness state only. It never uses\n"
    " wall-clock timers, so sleeps and durable timers exercised by workflow tests\n"
    " complete instantly under `gleam test`.\n"
).

-file("src/aion/testing/clock.gleam", 16).
?DOC(
    " Advance the current process's logical clock by `by`.\n"
    "\n"
    " The test FFI double marks any recorded sleeps or timers whose deadline is now\n"
    " reached as fired and returns immediately without wall-clock waiting.\n"
).
-spec advance(EIQ, aion@duration:duration()) -> {ok, EIQ} |
    {error, aion@error:engine_error()}.
advance(Env, By) ->
    Raw_duration = begin
        _pipe = By,
        _pipe@1 = aion@duration:to_milliseconds(_pipe),
        erlang:integer_to_binary(_pipe@1)
    end,
    case aion_flow_ffi:testing_advance(Raw_duration) of
        {ok, _} ->
            {ok, Env};

        {error, Raw_error} ->
            {error, {engine_failure, Raw_error}}
    end.

-file("src/aion/testing/clock.gleam", 35).
-spec parse_int(binary()) -> {ok, integer()} |
    {error, aion@error:engine_error()}.
parse_int(Raw) ->
    case gleam_stdlib:parse_int(Raw) of
        {ok, Value} ->
            {ok, Value};

        {error, _} ->
            {error,
                {engine_failure,
                    <<"Invalid test clock timestamp: "/utf8, Raw/binary>>}}
    end.

-file("src/aion/testing/clock.gleam", 28).
?DOC(" Return the current logical clock value for the current process.\n").
-spec current_time_milliseconds(any()) -> {ok, integer()} |
    {error, aion@error:engine_error()}.
current_time_milliseconds(_) ->
    case aion_flow_ffi:now() of
        {ok, Raw_timestamp} ->
            parse_int(Raw_timestamp);

        {error, Raw_error} ->
            {error, {engine_failure, Raw_error}}
    end.