-module(dream_test@timing). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/dream_test/timing.gleam"). -export([format_duration_ms/1, format_duration_us/1, now_ms/0, now_us/0]). -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( " Human-readable duration formatting for test timing.\n" "\n" " Provides utilities for measuring and displaying test execution times\n" " in a human-friendly format that scales appropriately.\n" "\n" " ## Duration Scaling\n" "\n" " | Duration | Display Format |\n" " |-------------------|----------------|\n" " | < 1ms | `0.42ms` |\n" " | 1ms - 999ms | `42ms` |\n" " | 1s - 59s | `1.2s` |\n" " | 1m - 59m | `2m 30s` |\n" " | >= 1h | `1h 15m` |\n" "\n" " ## Example\n" "\n" " ```gleam\n" " timing.format_duration_ms(1500)\n" " |> should\n" " |> be_equal(\"1.5s\")\n" " |> or_fail_with(\"expected 1.5s\")\n" " ```\n" ). -file("src/dream_test/timing.gleam", 185). -spec format_hours_minutes(integer()) -> binary(). format_hours_minutes(Ms) -> Total_minutes = Ms div 60000, Hours = Total_minutes div 60, Minutes = Total_minutes rem 60, case Minutes of 0 -> <<(erlang:integer_to_binary(Hours))/binary, "h"/utf8>>; M -> <<<<<<(erlang:integer_to_binary(Hours))/binary, "h "/utf8>>/binary, (erlang:integer_to_binary(M))/binary>>/binary, "m"/utf8>> end. -file("src/dream_test/timing.gleam", 174). -spec format_minutes_seconds(integer()) -> binary(). format_minutes_seconds(Ms) -> Total_seconds = Ms div 1000, Minutes = Total_seconds div 60, Seconds = Total_seconds rem 60, case Seconds of 0 -> <<(erlang:integer_to_binary(Minutes))/binary, "m"/utf8>>; S -> <<<<<<(erlang:integer_to_binary(Minutes))/binary, "m "/utf8>>/binary, (erlang:integer_to_binary(S))/binary>>/binary, "s"/utf8>> end. -file("src/dream_test/timing.gleam", 211). -spec divide_by_ten(float()) -> float(). divide_by_ten(Value) -> Value / 10.0. -file("src/dream_test/timing.gleam", 196). -spec format_float_one_decimal(float()) -> binary(). format_float_one_decimal(Value) -> Rounded = begin _pipe = erlang:round(Value * 10.0), _pipe@1 = erlang:float(_pipe), divide_by_ten(_pipe@1) end, Whole = erlang:trunc(Rounded), Decimal = erlang:round((Rounded - erlang:float(Whole)) * 10.0), case Decimal of 10 -> <<(erlang:integer_to_binary(Whole + 1))/binary, ".0"/utf8>>; D -> <<<<(erlang:integer_to_binary(Whole))/binary, "."/utf8>>/binary, (erlang:integer_to_binary(D))/binary>> end. -file("src/dream_test/timing.gleam", 169). -spec format_seconds(integer()) -> binary(). format_seconds(Ms) -> Seconds_float = erlang:float(Ms) / 1000.0, <<(format_float_one_decimal(Seconds_float))/binary, "s"/utf8>>. -file("src/dream_test/timing.gleam", 61). ?DOC( " Format a duration in milliseconds as a human-readable string.\n" "\n" " Automatically scales to the most appropriate unit:\n" " - Milliseconds for durations under 1 second\n" " - Seconds (with decimal) for durations under 1 minute\n" " - Minutes and seconds for durations under 1 hour\n" " - Hours and minutes for longer durations\n" "\n" " ## Example\n" "\n" " ```gleam\n" " // Arrange & Act\n" " let ms = timing.format_duration_ms(42)\n" "\n" " // Assert\n" " ms\n" " |> should\n" " |> be_equal(\"42ms\")\n" " |> or_fail_with(\"expected 42ms\")\n" " ```\n" "\n" " ## Parameters\n" "\n" " - `duration_ms`: Duration in milliseconds\n" "\n" " ## Returns\n" "\n" " A human-readable duration string (for example `\"42ms\"` or `\"1.5s\"`).\n" ). -spec format_duration_ms(integer()) -> binary(). format_duration_ms(Duration_ms) -> case Duration_ms of Ms when Ms =< 0 -> <<"0ms"/utf8>>; Ms@1 when Ms@1 < 1000 -> <<(erlang:integer_to_binary(Ms@1))/binary, "ms"/utf8>>; Ms@2 when Ms@2 < 60000 -> format_seconds(Ms@2); Ms@3 when Ms@3 < 3600000 -> format_minutes_seconds(Ms@3); Ms@4 -> format_hours_minutes(Ms@4) end. -file("src/dream_test/timing.gleam", 164). -spec format_sub_millisecond(integer()) -> binary(). format_sub_millisecond(Us) -> Ms_float = erlang:float(Us) / 1000.0, <<(format_float_one_decimal(Ms_float))/binary, "ms"/utf8>>. -file("src/dream_test/timing.gleam", 101). ?DOC( " Format a duration in microseconds as a human-readable string.\n" "\n" " Similar to `format_duration_ms` but accepts microseconds.\n" " Useful when working with high-precision timing.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " timing.format_duration_us(500)\n" " |> should\n" " |> be_equal(\"0.5ms\")\n" " |> or_fail_with(\"expected 0.5ms\")\n" " ```\n" "\n" " ## Parameters\n" "\n" " - `duration_us`: Duration in microseconds\n" "\n" " ## Returns\n" "\n" " A human-readable duration string (for example `\"0.5ms\"` or `\"42ms\"`).\n" ). -spec format_duration_us(integer()) -> binary(). format_duration_us(Duration_us) -> case Duration_us of Us when Us < 1000 -> format_sub_millisecond(Us); Us@1 -> format_duration_ms(Us@1 div 1000) end. -file("src/dream_test/timing.gleam", 132). ?DOC( " Get the current monotonic time in milliseconds.\n" "\n" " Use this to measure elapsed time between two points.\n" " Monotonic time is not affected by system clock changes.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let t1 = timing.now_ms()\n" " let t2 = timing.now_ms()\n" " let ok = t2 >= t1\n" "\n" " ok\n" " |> should\n" " |> be_equal(True)\n" " |> or_fail_with(\"expected now_ms to be monotonic\")\n" " ```\n" "\n" " ## Returns\n" "\n" " A monotonic timestamp in milliseconds.\n" ). -spec now_ms() -> integer(). now_ms() -> dream_test_timing_ffi:monotonic_time_ms(). -file("src/dream_test/timing.gleam", 156). ?DOC( " Get the current monotonic time in microseconds.\n" "\n" " Higher precision version of `now_ms()` for sub-millisecond timing.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let t1 = timing.now_us()\n" " let t2 = timing.now_us()\n" " let ok = t2 >= t1\n" "\n" " ok\n" " |> should\n" " |> be_equal(True)\n" " |> or_fail_with(\"expected now_us to be monotonic\")\n" " ```\n" "\n" " ## Returns\n" "\n" " A monotonic timestamp in microseconds.\n" ). -spec now_us() -> integer(). now_us() -> dream_test_timing_ffi:monotonic_time_us().