Skip to content

Commit c73869d

Browse files
freekmurzeclaude
andcommitted
Fix BC break in getSnapshotId() from named snapshots feature
Restore getSnapshotId() to its original no-parameter signature so users who override it (as documented in the README) are not broken. The incrementor bump is moved back to the call site via a new resolveSnapshotId() method. Also adds README docs for named snapshots. Fixes #237 (comment) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1313616 commit c73869d

File tree

3 files changed

+39
-25
lines changed

3 files changed

+39
-25
lines changed

README.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,16 @@ composer require --dev spatie/phpunit-snapshot-assertions
9898

9999
To make snapshot assertions, use the `Spatie\Snapshots\MatchesSnapshots` trait in your test case class. This adds a set of assertion methods to the class:
100100

101-
- `assertMatchesSnapshot($actual)`
102-
- `assertMatchesFileHashSnapshot($actual)`
103-
- `assertMatchesFileSnapshot($actual)`
104-
- `assertMatchesHtmlSnapshot($actual)`
105-
- `assertMatchesJsonSnapshot($actual)`
106-
- `assertMatchesObjectSnapshot($actual)`
107-
- `assertMatchesTextSnapshot($actual)`
108-
- `assertMatchesXmlSnapshot($actual)`
109-
- `assertMatchesYamlSnapshot($actual)`
110-
- `assertMatchesImageSnapshot($actual)`
101+
- `assertMatchesSnapshot($actual, $driver, $id)`
102+
- `assertMatchesFileHashSnapshot($filePath, $id)`
103+
- `assertMatchesFileSnapshot($file, $id)`
104+
- `assertMatchesHtmlSnapshot($actual, $id)`
105+
- `assertMatchesJsonSnapshot($actual, $id)`
106+
- `assertMatchesObjectSnapshot($actual, $id)`
107+
- `assertMatchesTextSnapshot($actual, $id)`
108+
- `assertMatchesXmlSnapshot($actual, $id)`
109+
- `assertMatchesYamlSnapshot($actual, $id)`
110+
- `assertMatchesImageSnapshot($actual, $threshold, $includeAa, $id)`
111111

112112
### Snapshot Testing 101
113113

@@ -202,6 +202,17 @@ $this->assertMatchesImageSnapshot($imagePath, 0.1);
202202
```
203203

204204

205+
### Named Snapshots
206+
207+
By default, snapshots are identified by an auto-incrementing number. You can pass an explicit `$id` to any assertion method to use a named snapshot instead:
208+
209+
```php
210+
$this->assertMatchesJsonSnapshot($order->toJson(), 'order-json');
211+
$this->assertMatchesTextSnapshot($output, 'cli-output');
212+
```
213+
214+
Named snapshots use a `s-` prefix internally to avoid collisions with auto-incremented ids. Named and auto-incremented snapshots can be mixed freely within a single test — named snapshots don't affect the auto-increment counter.
215+
205216
### Customizing Snapshot Ids and Directories
206217

207218
Snapshot ids are generated via the `getSnapshotId` method on the `MatchesSnapshot` trait. Override the method to customize the id. By default, a snapshot id exists of the test name, the test case name and an incrementing value, e.g. `Test__my_test_case__1`.

src/Concerns/SnapshotIdAware.php

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,11 @@ public function setUpSnapshotIncrementor()
2121
/*
2222
* Determines the snapshot's id. By default, the test case's class and
2323
* method names are used.
24-
*
25-
* If an explicit `$id` is provided, it will be prefixed with 's-' to
26-
* distinguish it from auto-generated incrementor-based IDs. This avoids
27-
* conflicts, should an explicit `$id` be numeric.
2824
*/
29-
protected function getSnapshotId(?string $id = null): string
25+
protected function getSnapshotId(): string
3026
{
31-
if ($id !== null) {
32-
$suffix = 's-'.$id;
33-
} else {
34-
$this->snapshotIncrementor++;
35-
$suffix = $this->snapshotIncrementor;
36-
}
37-
3827
return (new ReflectionClass($this))->getShortName().'__'.
3928
$this->nameWithDataSet().'__'.
40-
$suffix;
29+
$this->snapshotIncrementor;
4130
}
4231
}

src/MatchesSnapshots.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPUnit\Framework\Attributes\PostCondition;
66
use PHPUnit\Framework\ExpectationFailedException;
7+
use ReflectionClass;
78
use ReflectionObject;
89
use Spatie\Snapshots\Concerns\PhpUnitCompatibility;
910
use Spatie\Snapshots\Concerns\SnapshotDirectoryAware;
@@ -161,10 +162,23 @@ protected function shouldCreateSnapshots(): bool
161162
&& getenv('CREATE_SNAPSHOTS') !== 'false';
162163
}
163164

165+
protected function resolveSnapshotId(?string $id = null): string
166+
{
167+
if ($id !== null) {
168+
return (new ReflectionClass($this))->getShortName().'__'.
169+
$this->nameWithDataSet().'__'.
170+
's-'.$id;
171+
}
172+
173+
$this->snapshotIncrementor++;
174+
175+
return $this->getSnapshotId();
176+
}
177+
164178
protected function doSnapshotAssertion(mixed $actual, Driver $driver, ?string $id = null)
165179
{
166180
$snapshot = Snapshot::forTestCase(
167-
$this->getSnapshotId($id),
181+
$this->resolveSnapshotId($id),
168182
$this->getSnapshotDirectory(),
169183
$driver
170184
);
@@ -209,7 +223,7 @@ protected function doFileSnapshotAssertion(string $filePath, ?string $id = null)
209223

210224
$fileSystem = Filesystem::inDirectory($this->getFileSnapshotDirectory());
211225

212-
$snapshotId = $this->getSnapshotId($id).'.'.$fileExtension;
226+
$snapshotId = $this->resolveSnapshotId($id).'.'.$fileExtension;
213227
$snapshotId = Filename::cleanFilename($snapshotId);
214228

215229
// If $filePath has a different file extension than the snapshot, the test should fail

0 commit comments

Comments
 (0)