Skip to content

Commit 31d94d6

Browse files
Merge pull request #94 from mathieutu/feat/no-create-snapshots
Add the ability to disable snapshots creation.
2 parents 808f7cf + 26d93c3 commit 31d94d6

File tree

4 files changed

+117
-14
lines changed

4 files changed

+117
-14
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,29 @@ Drivers can be used by passing them as `assertMatchesSnapshot`'s second argument
274274
$this->assertMatchesSnapshot($something->toYaml(), new MyYamlDriver());
275275
```
276276

277+
### Usage in CI
278+
279+
When running your tests in Continuous Integration you would possibly want to disable the creation of snapshots.
280+
281+
By using the `--no-create-snapshots` parameter, PHPUnit will fail if the snapshots don't exist.
282+
283+
```bash
284+
> ./vendor/bin/phpunit -d --no-create-snapshots
285+
286+
1) ExampleTest::test_it_matches_a_string
287+
Snapshot "ExampleTest__test_it_matches_a_string__1.txt" does not exist.
288+
You can automatically create it by removing `-d --no-create-snapshots` of PHPUnit's CLI arguments.
289+
290+
```
291+
292+
277293
## Changelog
278294
279295
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
280296
281297
## Testing
282298
283-
``` bash
299+
```bash
284300
composer test
285301
```
286302

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
"phpunit/phpunit": "^8.3|^9.0",
2727
"symfony/property-access": "^4.0|^5.0",
2828
"symfony/serializer": "^4.0|^5.0",
29-
"symfony/yaml": "^4.0|^5.0",
29+
"symfony/yaml": "^4.0|^5.0"
30+
},
31+
"require-dev": {
32+
"phpunit/phpunit": "^9.1.0"
3033
},
3134
"autoload": {
3235
"psr-4": {

src/MatchesSnapshots.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
namespace Spatie\Snapshots;
44

5+
use PHPUnit\Framework\ExpectationFailedException;
56
use ReflectionClass;
67
use ReflectionObject;
7-
use Spatie\Snapshots\Drivers\XmlDriver;
88
use Spatie\Snapshots\Drivers\HtmlDriver;
99
use Spatie\Snapshots\Drivers\JsonDriver;
10+
use Spatie\Snapshots\Drivers\ObjectDriver;
1011
use Spatie\Snapshots\Drivers\TextDriver;
12+
use Spatie\Snapshots\Drivers\XmlDriver;
1113
use Spatie\Snapshots\Drivers\YamlDriver;
12-
use Spatie\Snapshots\Drivers\ObjectDriver;
13-
use PHPUnit\Framework\ExpectationFailedException;
1414

1515
trait MatchesSnapshots
1616
{
@@ -152,6 +152,18 @@ protected function shouldUpdateSnapshots(): bool
152152
return in_array('--update-snapshots', $_SERVER['argv'], true);
153153
}
154154

155+
/*
156+
* Determines whether or not the snapshot should be created instead of
157+
* matched.
158+
*
159+
* Override this method if you want to use a different flag or mechanism
160+
* than `-d --without-creating-snapshots`.
161+
*/
162+
protected function shouldCreateSnapshots(): bool
163+
{
164+
return ! in_array('--without-creating-snapshots', $_SERVER['argv'], true);
165+
}
166+
155167
protected function doSnapshotAssertion($actual, Driver $driver)
156168
{
157169
$this->snapshotIncrementor++;
@@ -163,6 +175,8 @@ protected function doSnapshotAssertion($actual, Driver $driver)
163175
);
164176

165177
if (! $snapshot->exists()) {
178+
$this->assertSnapshotShouldBeCreated($snapshot->filename());
179+
166180
$this->createSnapshotAndMarkTestIncomplete($snapshot, $actual);
167181
}
168182

@@ -231,6 +245,8 @@ protected function doFileSnapshotAssertion(string $filePath): void
231245
}
232246

233247
if (! $fileSystem->has($snapshotId)) {
248+
$this->assertSnapshotShouldBeCreated($failedSnapshotId);
249+
234250
$fileSystem->copy($filePath, $snapshotId);
235251

236252
$this->registerSnapshotChange("File snapshot created for {$snapshotId}");
@@ -288,4 +304,17 @@ protected function registerSnapshotChange(string $message): void
288304
{
289305
$this->snapshotChanges[] = $message;
290306
}
307+
308+
protected function assertSnapshotShouldBeCreated(string $snapshotFileName): void
309+
{
310+
if ($this->shouldCreateSnapshots()) {
311+
return;
312+
}
313+
314+
$this->fail(
315+
"Snapshot \"$snapshotFileName\" does not exist.\n".
316+
'You can automatically create it by removing '.
317+
'`-d --without-creating-snapshots` of PHPUnit\'s CLI arguments.'
318+
);
319+
}
291320
}

tests/Integration/MatchesSnapshotTest.php

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\Snapshots\Test\Integration;
44

5+
use PHPUnit\Framework\AssertionFailedError;
56
use PHPUnit\Framework\ExpectationFailedException;
67
use PHPUnit\Framework\MockObject\MockObject;
78
use PHPUnit\Framework\TestCase;
@@ -18,10 +19,15 @@ public function setUp(): void
1819
$this->setUpComparesSnapshotFiles();
1920

2021
$updateArgument = array_search('--update-snapshots', $_SERVER['argv']);
22+
$withoutCreatingArgument = array_search('--without-creating-snapshots', $_SERVER['argv']);
2123

2224
if ($updateArgument) {
2325
unset($_SERVER['argv'][$updateArgument]);
2426
}
27+
28+
if ($withoutCreatingArgument) {
29+
unset($_SERVER['argv'][$withoutCreatingArgument]);
30+
}
2531
}
2632

2733
/** @test */
@@ -209,7 +215,10 @@ public function it_can_mismatch_a_file_snapshot()
209215
{
210216
$mockTrait = $this->getMatchesSnapshotMock();
211217

212-
$this->expectFail($mockTrait);
218+
$this->expectFail(
219+
$mockTrait,
220+
'File did not match snapshot (MatchesSnapshotTest__it_can_mismatch_a_file_snapshot__1.jpg)'
221+
);
213222

214223
$mockTrait->assertMatchesFileSnapshot(__DIR__.'/stubs/test_files/troubled_man.jpg');
215224
}
@@ -219,7 +228,10 @@ public function it_can_mismatch_a_file_snapshot_with_a_different_extension()
219228
{
220229
$mockTrait = $this->getMatchesSnapshotMock();
221230

222-
$this->expectFail($mockTrait);
231+
$this->expectFail(
232+
$mockTrait,
233+
'File did not match the snapshot file extension (expected: jpg, was: png)'
234+
);
223235

224236
$mockTrait->assertMatchesFileSnapshot(__DIR__.'/stubs/test_files/no_man.png');
225237
}
@@ -229,10 +241,14 @@ public function it_needs_a_file_extension_to_do_a_file_snapshot_assertion()
229241
{
230242
$mockTrait = $this->getMatchesSnapshotMock();
231243

232-
$this->expectFail($mockTrait);
233-
234244
$filePath = __DIR__.'/stubs/test_files/file_without_extension';
235245

246+
$this->expectFail(
247+
$mockTrait,
248+
'Unable to make a file snapshot, file does not have a file extension '.
249+
"($filePath)"
250+
);
251+
236252
$this->assertFileExists($filePath);
237253

238254
$mockTrait->assertMatchesFileSnapshot($filePath);
@@ -243,7 +259,10 @@ public function it_persists_the_failed_file_after_mismatching_a_file_snapshot()
243259
{
244260
$mockTrait = $this->getMatchesSnapshotMock();
245261

246-
$this->expectFail($mockTrait);
262+
$this->expectFail(
263+
$mockTrait,
264+
'File did not match snapshot (MatchesSnapshotTest__it_persists_the_failed_file_after_mismatching_a_file_snapshot__1.jpg)'
265+
);
247266

248267
$mismatchedFile = __DIR__.'/stubs/test_files/troubled_man.jpg';
249268

@@ -270,7 +289,7 @@ public function it_deletes_the_persisted_failed_file_before_a_file_snapshot_asse
270289

271290
$mockTrait->assertMatchesFileSnapshot(__DIR__.'/stubs/test_files/friendly_man.jpg');
272291

273-
$this->assertFileNotExists($persistedFailedFile);
292+
$this->assertFileDoesNotExist($persistedFailedFile);
274293
}
275294

276295
/** @test */
@@ -378,7 +397,7 @@ public function it_can_update_a_file_snapshot_with_a_different_extension()
378397
'file.png'
379398
);
380399

381-
$this->assertFileNotExists($oldSnapshot);
400+
$this->assertFileDoesNotExist($oldSnapshot);
382401
}
383402

384403
private function expectIncompleteMatchesSnapshotTest(MockObject $matchesSnapshotMock, callable $assertions)
@@ -392,11 +411,15 @@ private function expectIncompleteMatchesSnapshotTest(MockObject $matchesSnapshot
392411
$matchesSnapshotMock->markTestIncompleteIfSnapshotsHaveChanged();
393412
}
394413

395-
private function expectFail(MockObject $matchesSnapshotMock)
414+
private function expectFail(MockObject $matchesSnapshotMock, string $message)
396415
{
416+
$this->expectException(AssertionFailedError::class);
417+
397418
$matchesSnapshotMock
398419
->expects($this->once())
399-
->method('fail');
420+
->method('fail')
421+
->with($message)
422+
->willThrowException(new AssertionFailedError());
400423
}
401424

402425
private function expectFailedMatchesSnapshotTest()
@@ -441,4 +464,36 @@ private function getMatchesSnapshotMock(): MockObject
441464

442465
return $matchesSnapshotMock;
443466
}
467+
468+
/** @test */
469+
public function it_doesnt_create_a_regular_snapshot_and_mismatches_if_asked()
470+
{
471+
$_SERVER['argv'][] = '--without-creating-snapshots';
472+
473+
$mockTrait = $this->getMatchesSnapshotMock();
474+
475+
$this->expectFail(
476+
$mockTrait,
477+
"Snapshot \"MatchesSnapshotTest__it_doesnt_create_a_regular_snapshot_and_mismatches_if_asked__1.txt\" does not exist.\n".
478+
'You can automatically create it by removing `-d --without-creating-snapshots` of PHPUnit\'s CLI arguments.'
479+
);
480+
481+
$mockTrait->assertMatchesSnapshot('Bar');
482+
}
483+
484+
/** @test */
485+
public function it_doesnt_create_a_file_snapshot_and_mismatches_if_asked()
486+
{
487+
$_SERVER['argv'][] = '--without-creating-snapshots';
488+
489+
$mockTrait = $this->getMatchesSnapshotMock();
490+
491+
$this->expectFail(
492+
$mockTrait,
493+
"Snapshot \"MatchesSnapshotTest__it_doesnt_create_a_file_snapshot_and_mismatches_if_asked__1.jpg_failed.jpg\" does not exist.\n".
494+
'You can automatically create it by removing `-d --without-creating-snapshots` of PHPUnit\'s CLI arguments.'
495+
);
496+
497+
$mockTrait->assertMatchesFileSnapshot(__DIR__.'/stubs/test_files/friendly_man.jpg');
498+
}
444499
}

0 commit comments

Comments
 (0)