Class SnapshotFileResolver
- Namespace
- SnapshotAssertions
- Assembly
- SnapshotAssertions.dll
Path resolution for snapshot files. Computes the expected file path given a directory and
either an explicit name or a (test class, test method) pair, plus the matching
.actual.txt sibling path.
public static class SnapshotFileResolver
- Inheritance
-
SnapshotFileResolver
- Inherited Members
Remarks
All paths returned are absolute. The resolver does not touch the filesystem; the caller is responsible for ensuring the directory exists when writing the actual file.
Fields
ActualExtension
The file extension used for transient actual content written on mismatch or no-baseline.
public const string ActualExtension = ".actual.txt"
Field Value
DefaultSnapshotsFolder
The default subdirectory (relative to the test binary's directory) where snapshot files are read from and written to.
public const string DefaultSnapshotsFolder = "Snapshots"
Field Value
ExpectedExtension
The file extension used for committed expected baselines.
public const string ExpectedExtension = ".expected.txt"
Field Value
Methods
GetDefaultSnapshotsDirectory(string)
Returns the default snapshots directory, derived as
{baseDirectory}/{DefaultSnapshotsFolder}.
public static string GetDefaultSnapshotsDirectory(string baseDirectory)
Parameters
baseDirectorystringThe directory the snapshots folder lives under (typically the test binary's
AppContext.BaseDirectory).
Returns
- string
The absolute path to the default snapshots directory.
Exceptions
- ArgumentNullException
baseDirectoryis null.
ResolveByFile(string)
Resolves the expected and actual file paths from an explicit absolute or relative file path to the expected file. The path is normalized to absolute form against the current working directory if relative.
public static SnapshotPaths ResolveByFile(string expectedFilePath)
Parameters
expectedFilePathstringThe path to the expected file (absolute or relative).
Returns
- SnapshotPaths
The expected and actual paths. The actual path is the expected path with the ExpectedExtension suffix replaced by ActualExtension; if the path does not end in the expected extension, ActualExtension is appended to the expected path's stem.
Exceptions
- ArgumentNullException
expectedFilePathis null.
ResolveByName(string, string)
Resolves the expected and actual file paths for a snapshot identified by an explicit
name, located under snapshotsDirectory.
public static SnapshotPaths ResolveByName(string snapshotsDirectory, string snapshotName)
Parameters
snapshotsDirectorystringThe absolute path to the directory containing snapshot files.
snapshotNamestringThe base name (without extension). Must be a valid file-name component on the host platform; path separators are rejected.
Returns
- SnapshotPaths
The expected and actual paths.
Exceptions
- ArgumentNullException
A required argument is null.
- ArgumentException
snapshotsDirectoryis empty or whitespace, orsnapshotNamecontains a path separator or is empty / whitespace.
ResolveByTest(string, string, string, IReadOnlyList<object?>?)
Resolves the expected and actual file paths for a snapshot identified by a (test class,
test method) pair, optionally augmented with a hash of the test method's arguments
for parameterized tests. The base name is constructed as
{testClassName}.{testMethodName} when testMethodArguments is
null or empty, or {testClassName}.{testMethodName}.{argsHash}
otherwise.
public static SnapshotPaths ResolveByTest(string snapshotsDirectory, string testClassName, string testMethodName, IReadOnlyList<object?>? testMethodArguments = null)
Parameters
snapshotsDirectorystringThe absolute path to the directory containing snapshot files.
testClassNamestringThe simple test class name (no namespace).
testMethodNamestringThe test method name.
testMethodArgumentsIReadOnlyList<object>The arguments passed to the parameterized test invocation, or null for non-parameterized tests. Each argument is stringified, the results joined with
"|", and hashed with SHA-256; the first 8 hex characters of the hash are appended to the base name. Stringification routes by type so the key stays stable and culture-independent: a string is taken verbatim, an IFormattable (numbers, DateTime, TimeSpan, etc.) is formatted with InvariantCulture, an IEnumerable is expanded element-by-element as[item1,item2,...](recursively, so nested collections expand too), and any other type falls back to ToString(object, IFormatProvider). The hash is stable across runs and machines for the same argument values, so each parameterized variant gets its own distinct snapshot file; changing a collection argument's elements changes the hash, and therefore the snapshot file.
Returns
- SnapshotPaths
The expected and actual paths.
Exceptions
- ArgumentNullException
A required argument is null.
- ArgumentException
testClassNameortestMethodNameis empty or contains invalid file-name characters.
TryResolveSourceSnapshotsDirectory(string)
Resolves the source-tree snapshots directory: the committable
Snapshots/ folder that lives next to the test project file, rather than the
runtime copy under bin/. Used by accept-mode so that an accepted baseline is
written where it is committed and read from, not into the build output where it is
discarded on the next clean.
public static string? TryResolveSourceSnapshotsDirectory(string startDirectory)
Parameters
startDirectorystringThe directory to start the upward search from (typically the test binary's
AppContext.BaseDirectory).
Returns
- string
The absolute path to the source-tree snapshots directory, or null if no ancestor project directory could be located.
Remarks
The read path resolves baselines from {AppContext.BaseDirectory}/Snapshots: the
build copies Snapshots/**/*.expected.txt from the project directory into
bin/ via the package's include glob. The accept write target is resolved by
walking up from startDirectory (typically
BaseDirectory) to the nearest ancestor that contains a
*.csproj file, then appending DefaultSnapshotsFolder. That ancestor
is the directory the build's include glob is relative to, so the accept write lands in
the exact folder the next build copies back into bin/.
When no ancestor project file can be found (for example, a single-file publish where the source tree is not present), the method returns null: the caller falls back to the runtime directory so accept-mode still produces a file, even if it is not in the source tree.
Exceptions
- ArgumentNullException
startDirectoryis null.