Table of Contents

Class Scrubbers

Namespace
SnapshotAssertions
Assembly
SnapshotAssertions.dll

Built-in SnapshotScrubber factory. Each property returns a stateless instance (state lives in the per-call SnapshotScrubberState), so the same property may be reused across tests without cross-test interference.

public static class Scrubbers
Inheritance
Scrubbers
Inherited Members

Remarks

The three indexed scrubbers (Guid, Iso8601Timestamp, UnixEpochMillis) all use the indexed-token format <kind:N>, where N is assigned by first-occurrence order within the snapshot, per kind. Recurring values map to the same N. The Default preset chains all three in the order Guid → Iso8601Timestamp → UnixEpochMillis (the order is deterministic but unobservable when the underlying patterns do not overlap).

The Pattern(Regex, string) overload accepts a pre-compiled Regex; the Pattern(string, string) overload compiles a NonBacktracking pattern internally. Both replace every match with the literal token; no indexing is applied.

The IndexedPattern(Regex, string) overload is the indexed counterpart to Pattern(Regex, string): it reuses the same SnapshotScrubberState indexed-token machinery the built-in scrubbers use, so recurring identical matched values share one index (<kind:0>) while distinct values get incrementing indices. Use it for a volatile value outside the built-in kinds when same-value correlation across the snapshot matters; use Pattern(Regex, string) when every match should collapse to a single literal token.

Properties

Common

Extended curated chain of Guid, GuidN, Iso8601Timestamp, UnixEpochMillis, and ElapsedMs. Superset of Default: adds GUID-N format coverage and elapsed-millisecond matching. Ordering follows the most-specific-first rule (canonical GUID before N-format to avoid hex-segment consumption; ISO 8601 before 13-digit numeric to avoid year-month component consumption).

public static SnapshotScrubber Common { get; }

Property Value

SnapshotScrubber

Default

Curated chain of Guid, Iso8601Timestamp, and UnixEpochMillis. Matches the most common volatile-value cases in a single composable scrubber.

public static SnapshotScrubber Default { get; }

Property Value

SnapshotScrubber

ElapsedMs

Replaces all elapsed-millisecond values (e.g. 42ms, 42 ms, 42.5ms, 1234.567 ms) with <elapsed-ms:N>. Recurring elapsed values share an index. Pattern is case-sensitive on the ms suffix (uppercase MS is not matched); use Pattern(string, string) for case-insensitive needs.

public static SnapshotScrubber ElapsedMs { get; }

Property Value

SnapshotScrubber

Guid

Replaces all GUIDs (8-4-4-4-12 hex format, case-insensitive) with <guid:N>; recurring GUIDs share an index. Comparison is case-insensitive (lower-case canonical form is used for index look-up).

[SuppressMessage("Naming", "CA1720:Identifier contains type name", Justification = "Domain term: this property identifies the GUID scrubber, not a System.Guid value. Renaming would obscure the family-wide API of one factory property per kind.")]
public static SnapshotScrubber Guid { get; }

Property Value

SnapshotScrubber

GuidN

Replaces all GUID-N format strings (32 contiguous hex chars, Guid.ToString("N")) with <guid:N>. Shares the "guid" kind-name with Guid, so the indexed-token counter is drawn from the same pool: across a snapshot containing both canonical and N-format GUID strings, indices increment in unified first-occurrence order across both formats. Recurring N-format values get the same index. Comparison is case-insensitive (lower-case canonical form is used for index look-up).

public static SnapshotScrubber GuidN { get; }

Property Value

SnapshotScrubber

Iso8601Timestamp

Replaces ISO 8601 timestamps (e.g. 2026-05-07T13:45:30Z, 2026-05-07T13:45:30.123+02:00) with <iso8601:N>; recurring timestamps share an index. Comparison is ordinal (different precisions or offsets get different indices).

public static SnapshotScrubber Iso8601Timestamp { get; }

Property Value

SnapshotScrubber

UnixEpochMillis

Replaces 13-digit Unix-epoch-milliseconds numbers (the post-2001 range, up to ~year 2286) with <unixms:N>; recurring numbers share an index.

public static SnapshotScrubber UnixEpochMillis { get; }

Property Value

SnapshotScrubber

Methods

Combine(params SnapshotScrubber[])

Combines the supplied scrubbers into a single scrubber that applies them left-to-right. All inner scrubbers share the SnapshotScrubberState passed to Apply(string, SnapshotScrubberState), so recurring volatile values keep stable indexed tokens across the combined pipeline.

public static SnapshotScrubber Combine(params SnapshotScrubber[] scrubbers)

Parameters

scrubbers SnapshotScrubber[]

The scrubbers to combine. Each element must be non-null.

Returns

SnapshotScrubber

An identity scrubber (returns input unchanged) when scrubbers is empty; the single element when the array has exactly one entry (no wrapper allocation); a chain over a defensive copy of the array otherwise. The defensive copy means later mutations of scrubbers do not affect the returned scrubber.

Exceptions

ArgumentNullException

scrubbers is null.

ArgumentException

An element of scrubbers is null.

IndexedPattern(string, string)

Compiles pattern with NonBacktracking (ReDoS-resistant) and replaces every match with an indexed token <kind:N>. Recurring identical matched values share the same index N. This is the indexed (correlated) counterpart to Pattern(string, string).

public static SnapshotScrubber IndexedPattern(string pattern, string kind)

Parameters

pattern string

The regex pattern source.

kind string

The kind namespace used in the emitted <kind:N> token and as the index-counter namespace on the shared state.

Returns

SnapshotScrubber

An indexed-pattern scrubber.

Exceptions

ArgumentNullException

A required argument is null.

ArgumentException

pattern is not a valid regex.

IndexedPattern(Regex, string)

Replaces every match of pattern with an indexed token <kind:N> (where kind is kind), reusing the same SnapshotScrubberState indexed-token machinery as the built-in scrubbers. Recurring identical matched values share the same index N; distinct values get incrementing indices in first-occurrence order. This is the indexed (correlated) counterpart to Pattern(Regex, string), which is flat (every match collapses to one literal token, losing correlation).

public static SnapshotScrubber IndexedPattern(Regex pattern, string kind)

Parameters

pattern Regex

The regex to match against. The entire match value is the correlation key; equality is ordinal (no case folding). Use a capture-narrowing pattern when only part of the match should drive correlation.

kind string

The kind namespace used in the emitted <kind:N> token and as the index-counter namespace on the shared state. Passing the same kind as a built-in scrubber (e.g. "guid") shares that built-in's index counter.

Returns

SnapshotScrubber

An indexed-pattern scrubber.

Exceptions

ArgumentNullException

A required argument is null.

Pattern(string, string)

Compiles pattern with NonBacktracking (ReDoS-resistant) and replaces every match with the literal token.

public static SnapshotScrubber Pattern(string pattern, string token)

Parameters

pattern string

The regex pattern source.

token string

The replacement string.

Returns

SnapshotScrubber

A pattern scrubber.

Exceptions

ArgumentNullException

A required argument is null.

ArgumentException

pattern is not a valid regex.

Pattern(Regex, string)

Replaces every match of pattern with the literal token. No indexing is applied; every match becomes the same token.

public static SnapshotScrubber Pattern(Regex pattern, string token)

Parameters

pattern Regex

The regex to match against.

token string

The replacement string. Note that regex backreferences (e.g. $1) are NOT interpreted: the literal characters are emitted.

Returns

SnapshotScrubber

A pattern scrubber.

Exceptions

ArgumentNullException

A required argument is null.