Table of Contents

Class TimeRenderingHelpers

Namespace
TimeAssertions
Assembly
TimeAssertions.dll

Formatting utilities for rendering elapsed durations and timing budgets in human-readable form for assertion-failure messages. Pure; no I/O; allocation-conscious.

public static class TimeRenderingHelpers
Inheritance
TimeRenderingHelpers
Inherited Members

Methods

FormatActiveTimerAtLeastShortfall(IReadOnlyList<ActiveTimerInfo>, int)

Formats the failure message for HasActiveTimers() and HasAtLeastActiveTimerCount(count): the minimum that was required and the actual count, followed by each active timer's schedule in deterministic order (by due time, then period). When no timers are active the schedule list is omitted.

public static string FormatActiveTimerAtLeastShortfall(IReadOnlyList<ActiveTimerInfo> active, int minimum)

Parameters

active IReadOnlyList<ActiveTimerInfo>

The timers active when the assertion ran.

minimum int

The minimum active-timer count that was required. Must be non-negative.

Returns

string

A multi-line human-readable summary in InvariantCulture, with a grep-friendly (minimum=N, actual=M) trailer on the headline.

Exceptions

ArgumentNullException

active is null.

ArgumentOutOfRangeException

minimum is negative.

FormatActiveTimerCountMismatch(IReadOnlyList<ActiveTimerInfo>, int)

Formats the failure message for HasActiveTimerCount(expected): the expected and actual active-timer counts, followed by each active timer's schedule in deterministic order (by due time, then period). When no timers are active the schedule list is omitted.

public static string FormatActiveTimerCountMismatch(IReadOnlyList<ActiveTimerInfo> active, int expected)

Parameters

active IReadOnlyList<ActiveTimerInfo>

The timers active when the assertion ran.

expected int

The expected active-timer count that was not met. Must be non-negative.

Returns

string

A multi-line human-readable summary in InvariantCulture, with a grep-friendly (expected=N, actual=M) trailer on the headline.

Exceptions

ArgumentNullException

active is null.

ArgumentOutOfRangeException

expected is negative.

FormatActiveTimerLeak(IReadOnlyList<ActiveTimerInfo>)

Formats the failure message for HasNoActiveTimers(): names each timer that remained active by the schedule it was created with (or last changed to), so a leak failure reports which timers survived rather than a bare count. Survivors are listed in a deterministic order (by due time, then period) so the message is snapshot-stable.

public static string FormatActiveTimerLeak(IReadOnlyList<ActiveTimerInfo> survivors)

Parameters

survivors IReadOnlyList<ActiveTimerInfo>

The timers still active when the assertion ran. Expected non-empty: the assertion only renders a failure when at least one timer leaked.

Returns

string

A multi-line human-readable summary in InvariantCulture, with a grep-friendly (count=N) trailer on the headline.

Exceptions

ArgumentNullException

survivors is null.

FormatActiveTimerSurvivors(IReadOnlyList<ActiveTimerInfo>)

Formats the schedule list of the timers that survived a poll-until-clear deadline, for the failure message of HasNoActiveTimersEventually(...) / HasActiveTimerCountEventually(...). Returns each survivor's schedule on its own indented line, sorted by due time then period for deterministic (snapshot-stable) output, prefixed with a grep-friendly (count=N) trailer. The caller supplies the headline (which names the timeout); this renders only the survivor list.

public static string FormatActiveTimerSurvivors(IReadOnlyList<ActiveTimerInfo> survivors)

Parameters

survivors IReadOnlyList<ActiveTimerInfo>

The timers still active when the deadline elapsed.

Returns

string

A multi-line string in InvariantCulture beginning with the (count=N) trailer, followed by one indented schedule line per survivor. Empty survivors render the trailer alone.

Exceptions

ArgumentNullException

survivors is null.

FormatBudgetOverrun(TimeSpan, TimeSpan)

Formats a budget-overrun summary: actual elapsed, the budget that was exceeded, and the excess. Used in .WithinTimeBudget(...) failure messages.

public static string FormatBudgetOverrun(TimeSpan elapsed, TimeSpan budget)

Parameters

elapsed TimeSpan

The wall-clock duration the assertion's evaluator took.

budget TimeSpan

The configured timing budget.

Returns

string

A multi-line human-readable summary.

Remarks

The rendered string carries two forms in parallel: a human-readable prose (completed in 1.2s: exceeded budget of 500ms by 747ms) and a grep-friendly fixed-unit parenthetical ((elapsed=1247ms, budget=500ms, overrun=747ms)). The parenthetical lets CI log scrapers and triage tooling extract the three numbers without parsing the human-readable prose around them.

FormatDuration(TimeSpan)

Formats a TimeSpan as a compact human-readable duration string. Picks the most appropriate unit based on magnitude: sub-millisecond → microseconds (e.g. "123μs"), sub-second → milliseconds (e.g. "247ms"), sub-minute → seconds with one decimal (e.g. "1.2s"), otherwise → minutes:seconds (e.g. "1:30").

public static string FormatDuration(TimeSpan duration)

Parameters

duration TimeSpan

The duration to format.

Returns

string

A compact human-readable duration string in InvariantCulture.

FormatNextTimerDueMismatch(TimeSpan?, TimeSpan, TimeSpan)

Formats the failure message for HasNextTimerDueApproximately(expected, tolerance): the expected due time, the allowed tolerance, and either the observed next-timer due time and how far it fell outside tolerance, or a note that no enabled timer was pending.

public static string FormatNextTimerDueMismatch(TimeSpan? actual, TimeSpan expected, TimeSpan tolerance)

Parameters

actual TimeSpan?

The observed next-timer due time, or null when no enabled timer is pending.

expected TimeSpan

The expected next-timer due time.

tolerance TimeSpan

The allowed absolute tolerance around expected. Must be non-negative.

Returns

string

A single-line human-readable summary in InvariantCulture.

Remarks

The rendered shape pins a one-line headline followed by a grep-friendly fixed-unit parenthetical ((expected=Xms, tolerance=Yms, actual=Zms, delta=Wms)) so CI log scrapers can extract the numbers without parsing the prose, analogous to FormatBudgetOverrun(TimeSpan, TimeSpan). When no enabled timer is pending the parenthetical reads (expected=Xms, tolerance=Yms, actual=none).

Exceptions

ArgumentOutOfRangeException

tolerance is negative.

FormatNextTimerDueOutOfRange(TimeSpan?, TimeSpan, TimeSpan)

Formats the failure message for HasPendingTimerDueWithin(min, max): the inclusive range, and either the observed next-timer due time, or a note that no enabled timer was pending.

public static string FormatNextTimerDueOutOfRange(TimeSpan? actual, TimeSpan min, TimeSpan max)

Parameters

actual TimeSpan?

The observed next-timer due time, or null when no enabled timer is pending.

min TimeSpan

The inclusive lower bound of the expected due-time range.

max TimeSpan

The inclusive upper bound of the expected due-time range.

Returns

string

A single-line human-readable summary in InvariantCulture.

Remarks

The rendered shape pins a one-line headline followed by a grep-friendly fixed-unit parenthetical ((min=Xms, max=Yms, actual=Zms)); when no enabled timer is pending the parenthetical reads (min=Xms, max=Yms, actual=none).

FormatNoTimerFired(long, IReadOnlyList<ActiveTimerInfo>)

Formats the failure message for HasNoTimerFired(): the observed cumulative fire count that should have been zero, followed by the still-active timers with their per-timer fire counts (when any remain active).

public static string FormatNoTimerFired(long actual, IReadOnlyList<ActiveTimerInfo> active)

Parameters

actual long

The observed cumulative fire count. Expected greater than zero: the assertion only renders a failure when at least one callback fired.

active IReadOnlyList<ActiveTimerInfo>

The timers still active when the assertion ran.

Returns

string

A human-readable summary in InvariantCulture, with a grep-friendly (expected=0, actual=M) trailer on the headline.

Exceptions

ArgumentNullException

active is null.

FormatRateLimitViolation(IReadOnlyList<DateTimeOffset>, int, TimeSpan, TimeSpan)

Formats a rate-limit violation summary for the failure message of WasInvokedAtMostOncePer(...). Names the first violating consecutive pair by index, the observed gap, and the configured minimum interval.

public static string FormatRateLimitViolation(IReadOnlyList<DateTimeOffset> timestamps, int violatingIndex, TimeSpan gap, TimeSpan interval)

Parameters

timestamps IReadOnlyList<DateTimeOffset>

The invocation-timestamp sequence the assertion examined.

violatingIndex int

The zero-based index of the second timestamp in the violating pair. The pair is (timestamps[violatingIndex - 1], timestamps[violatingIndex]).

gap TimeSpan

The observed gap between the two timestamps.

interval TimeSpan

The configured minimum interval that was violated.

Returns

string

A multi-line human-readable summary in InvariantCulture.

Remarks

The rendered shape pins a one-line headline with the violation index and gap, followed by the two violating timestamps in ISO 8601 round-trip form, and a grep-friendly fixed-unit parenthetical (analogous to FormatBudgetOverrun(TimeSpan, TimeSpan)'s (elapsed=, budget=, overrun=) trailer) so CI log scrapers can extract the numbers without parsing the prose.

Exceptions

ArgumentNullException

timestamps is null.

ArgumentOutOfRangeException

violatingIndex is less than 1 or greater than or equal to timestamps.Count: the pair (timestamps[violatingIndex - 1], timestamps[violatingIndex]) must reference two in-range entries.

FormatTimerFireCountMismatch(long, int, IReadOnlyList<ActiveTimerInfo>)

Formats the failure message for HasTimerFiredCount(expected): the expected and actual cumulative fire counts across every timer the provider created, followed by the still-active timers with their per-timer fire counts (when any remain active). The count is cumulative and survives disposal, so a mismatch with an empty active list still reports the totals.

public static string FormatTimerFireCountMismatch(long actual, int expected, IReadOnlyList<ActiveTimerInfo> active)

Parameters

actual long

The observed cumulative fire count.

expected int

The expected fire count that was not met. Must be non-negative.

active IReadOnlyList<ActiveTimerInfo>

The timers still active when the assertion ran.

Returns

string

A human-readable summary in InvariantCulture, with a grep-friendly (expected=N, actual=M) trailer on the headline.

Exceptions

ArgumentNullException

active is null.

ArgumentOutOfRangeException

expected is negative.

FormatTimerFireShortfall(long, int, IReadOnlyList<ActiveTimerInfo>)

Formats the failure message for HasTimerFiredAtLeast(minimum): the required minimum and the actual cumulative fire count, followed by the still-active timers with their per-timer fire counts (when any remain active). The liveness counterpart used when timing jitter makes an exact fire count brittle.

public static string FormatTimerFireShortfall(long actual, int minimum, IReadOnlyList<ActiveTimerInfo> active)

Parameters

actual long

The observed cumulative fire count.

minimum int

The minimum fire count that was required. Must be non-negative.

active IReadOnlyList<ActiveTimerInfo>

The timers still active when the assertion ran.

Returns

string

A human-readable summary in InvariantCulture, with a grep-friendly (minimum=N, actual=M) trailer on the headline.

Exceptions

ArgumentNullException

active is null.

ArgumentOutOfRangeException

minimum is negative.