Jest snapshot testing utilities that enable capturing component output, API responses, or any serializable values as snapshots for regression testing and change detection
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The SnapshotState class manages snapshot file operations, maintains test execution state, and handles the lifecycle of snapshot data including creation, updating, and cleanup of snapshot files.
Core class that manages snapshot operations for a single snapshot file, tracking test results and handling file I/O operations.
/**
* Manages snapshot operations for a single snapshot file
* @param snapshotPath - Path to the snapshot file
* @param options - Configuration options for snapshot behavior
*/
class SnapshotState {
constructor(snapshotPath: string, options: SnapshotStateOptions);
// State counters
added: number; // Number of snapshots added in this test run
matched: number; // Number of snapshots that matched existing ones
unmatched: number; // Number of snapshots that didn't match
updated: number; // Number of snapshots updated in this test run
// Configuration
expand: boolean; // Whether to expand diff output
snapshotFormat: SnapshotFormat; // Formatting options for snapshots
// Core methods
match(options: SnapshotMatchOptions): SnapshotReturnOptions;
fail(testName: string, received: unknown, key?: string): string;
save(): SaveStatus;
clear(): void;
getUncheckedCount(): number;
getUncheckedKeys(): Array<string>;
removeUncheckedKeys(): void;
markSnapshotsAsCheckedForTest(testName: string): void;
}Usage Examples:
import { SnapshotState } from "jest-snapshot";
// Create snapshot state for a test file
const snapshotState = new SnapshotState(
'/path/to/__snapshots__/test.spec.js.snap',
{
updateSnapshot: 'none', // 'all' | 'new' | 'none'
expand: false,
snapshotFormat: {
printWidth: 80,
tabWidth: 2,
useTabs: false
},
rootDir: '/project/root',
prettierPath: null
}
);
// Match a value against a snapshot
const result = snapshotState.match({
testName: 'should render component correctly',
received: '<div>Hello World</div>',
isInline: false
});
console.log(result.pass); // true if snapshot matches
console.log(result.actual); // serialized received value
console.log(result.expected); // existing snapshot content
// Save snapshots to file
const saveResult = snapshotState.save();
console.log(saveResult.saved); // true if snapshots were written
console.log(saveResult.deleted); // true if file was deletedThe match method compares received values against stored snapshots and handles snapshot creation or updates.
/**
* Matches a received value against a stored snapshot
* @param options - Match configuration including test name and received value
* @returns Match result with pass/fail status and snapshot content
*/
match(options: SnapshotMatchOptions): SnapshotReturnOptions;
interface SnapshotMatchOptions {
readonly testName: string; // Full test name including describe blocks
readonly received: unknown; // Value to compare against snapshot
readonly key?: string; // Optional custom snapshot key
readonly inlineSnapshot?: string; // Existing inline snapshot content
readonly isInline: boolean; // Whether this is an inline snapshot
readonly error?: Error; // Error context for better reporting
readonly testFailing?: boolean; // Whether the test is expected to fail
}
interface SnapshotReturnOptions {
readonly actual: string; // Serialized received value
readonly count: number; // Snapshot count for this test name
readonly expected?: string; // Existing snapshot content (undefined for new)
readonly key: string; // Generated snapshot key
readonly pass: boolean; // Whether the match succeeded
}Match Behavior:
// New snapshot (first time)
const result = snapshotState.match({
testName: 'new test',
received: { id: 1, name: 'John' },
isInline: false
});
// result.pass = true, result.expected = undefined, snapshotState.added++
// Existing snapshot (matches)
const result = snapshotState.match({
testName: 'existing test',
received: 'expected value',
isInline: false
});
// result.pass = true, result.expected = 'expected value', snapshotState.matched++
// Existing snapshot (doesn't match)
const result = snapshotState.match({
testName: 'existing test',
received: 'different value',
isInline: false
});
// result.pass = false, shows diff, snapshotState.unmatched++The fail method handles snapshot failures and generates unique keys for failed snapshots.
/**
* Records a snapshot failure and generates a unique key
* @param testName - Name of the failing test
* @param received - Value that failed to match
* @param key - Optional custom snapshot key
* @returns Unique snapshot key for the failure
*/
fail(testName: string, received: unknown, key?: string): string;Usage Example:
// Record a property matcher failure
const failKey = snapshotState.fail(
'user object test',
{ id: 123, name: 'John', timestamp: 1234567890 }
);
// Returns something like "user object test 1"
// Increments failure counter for this test nameSave snapshots to disk and manage unchecked snapshots.
/**
* Saves all snapshots to disk
* @returns Status indicating whether file was saved or deleted
*/
save(): SaveStatus;
/**
* Gets count of unchecked snapshots (snapshots not used in current test run)
* @returns Number of unchecked snapshots
*/
getUncheckedCount(): number;
/**
* Gets array of unchecked snapshot keys
* @returns Array of snapshot keys that weren't checked in current test run
*/
getUncheckedKeys(): Array<string>;
/**
* Removes unchecked snapshots from the snapshot data
*/
removeUncheckedKeys(): void;
/**
* Resets all counters and snapshot data to initial state
*/
clear(): void;
/**
* Marks all snapshots for a specific test as checked
* @param testName - Name of the test to mark snapshots as checked
*/
markSnapshotsAsCheckedForTest(testName: string): void;
interface SaveStatus {
deleted: boolean; // True if snapshot file was deleted (no snapshots)
saved: boolean; // True if snapshot file was written
}File Management Example:
// After running tests, save snapshots
const saveStatus = snapshotState.save();
if (saveStatus.saved) {
console.log('Snapshots saved to file');
}
if (saveStatus.deleted) {
console.log('Snapshot file deleted (no snapshots remaining)');
}
// Clean up unused snapshots
const uncheckedCount = snapshotState.getUncheckedCount();
if (uncheckedCount > 0) {
console.log(`${uncheckedCount} unused snapshots found`);
snapshotState.removeUncheckedKeys();
}Special handling for inline snapshots that are embedded in source code.
// Inline snapshot matching
const result = snapshotState.match({
testName: 'inline test',
received: 'test value',
isInline: true,
inlineSnapshot: '"test value"' // existing inline snapshot
});
// For new inline snapshots
const result = snapshotState.match({
testName: 'new inline test',
received: { data: 'value' },
isInline: true
// inlineSnapshot omitted for new snapshots
});interface SnapshotStateOptions {
readonly updateSnapshot: Config.SnapshotUpdateState; // 'all' | 'new' | 'none'
readonly prettierPath?: string | null; // Path to prettier for formatting
readonly expand?: boolean; // Expand diff output
readonly snapshotFormat: SnapshotFormat; // Snapshot serialization options
readonly rootDir: string; // Project root directory
}
type SnapshotFormat = Omit<PrettyFormatOptions, 'compareKeys'>;
// Update modes:
// 'all' - Update all snapshots (--updateSnapshot)
// 'new' - Only create new snapshots (--ci)
// 'none' - Don't update any snapshots (default)// Missing snapshot path
new SnapshotState('', options);
// Error: Invalid snapshot path
// Invalid update mode
new SnapshotState(path, { updateSnapshot: 'invalid' });
// Error: Invalid updateSnapshot value
// File system errors
snapshotState.save();
// May throw filesystem errors if directory not writable