snapshots code cleanup

This commit is contained in:
Fabio Ivona
2023-07-27 11:16:27 +02:00
parent 39e0d61dec
commit b60d21dfe2
4 changed files with 48 additions and 53 deletions

View File

@ -805,6 +805,11 @@ final class Expectation
*/ */
public function toMatchSnapshot(string $message = ''): self public function toMatchSnapshot(string $message = ''): self
{ {
$snapshots = TestSuite::getInstance()->snapshots;
$testCase = TestSuite::getInstance()->test;
assert($testCase instanceof TestCase);
$string = match (true) { $string = match (true) {
is_string($this->value) => $this->value, is_string($this->value) => $this->value,
is_object($this->value) && method_exists($this->value, '__toString') => $this->value->__toString(), is_object($this->value) && method_exists($this->value, '__toString') => $this->value->__toString(),
@ -817,12 +822,8 @@ final class Expectation
default => InvalidExpectationValue::expected('array|object|string'), default => InvalidExpectationValue::expected('array|object|string'),
}; };
$testCase = TestSuite::getInstance()->test; if ($snapshots->has()) {
assert($testCase instanceof TestCase); [$filename, $content] = $snapshots->get();
$snapshots = TestSuite::getInstance()->snapshots;
if ($snapshots->has($testCase, $string)) {
[$filename, $content] = $snapshots->get($testCase, $string);
Assert::assertSame( Assert::assertSame(
$content, $content,
@ -830,7 +831,7 @@ final class Expectation
$message === '' ? "Failed asserting that the string value matches its snapshot ($filename)." : $message $message === '' ? "Failed asserting that the string value matches its snapshot ($filename)." : $message
); );
} else { } else {
$filename = $snapshots->save($testCase, $string); $filename = $snapshots->save($string);
$testCase::markTestIncomplete('Snapshot created at ['.$filename.'].'); $testCase::markTestIncomplete('Snapshot created at ['.$filename.'].');
} }

View File

@ -5,8 +5,7 @@ declare(strict_types=1);
namespace Pest\Repositories; namespace Pest\Repositories;
use Pest\Exceptions\ShouldNotHappen; use Pest\Exceptions\ShouldNotHappen;
use Pest\Support\Str; use Pest\TestSuite;
use PHPUnit\Framework\TestCase;
/** /**
* @internal * @internal
@ -25,11 +24,9 @@ final class SnapshotRepository
/** /**
* Checks if the snapshot exists. * Checks if the snapshot exists.
*/ */
public function has(TestCase $testCase, string $description): bool public function has(): bool
{ {
[$filename, $description] = $this->getFilenameAndDescription($testCase); return file_exists($this->getSnapshotFilename());
return file_exists($this->getSnapshotFilename($filename, $description));
} }
/** /**
@ -39,11 +36,9 @@ final class SnapshotRepository
* *
* @throws ShouldNotHappen * @throws ShouldNotHappen
*/ */
public function get(TestCase $testCase, string $description): array public function get(): array
{ {
[$filename, $description] = $this->getFilenameAndDescription($testCase); $contents = file_get_contents($snapshotFilename = $this->getSnapshotFilename());
$contents = file_get_contents($snapshotFilename = $this->getSnapshotFilename($filename, $description));
if ($contents === false) { if ($contents === false) {
throw ShouldNotHappen::fromMessage('Snapshot file could not be read.'); throw ShouldNotHappen::fromMessage('Snapshot file could not be read.');
@ -57,11 +52,9 @@ final class SnapshotRepository
/** /**
* Saves the given snapshot for the given test case. * Saves the given snapshot for the given test case.
*/ */
public function save(TestCase $testCase, string $snapshot): string public function save(string $snapshot): string
{ {
[$filename, $description] = $this->getFilenameAndDescription($testCase); $snapshotFilename = $this->getSnapshotFilename();
$snapshotFilename = $this->getSnapshotFilename($filename, $description);
if (! file_exists(dirname($snapshotFilename))) { if (! file_exists(dirname($snapshotFilename))) {
mkdir(dirname($snapshotFilename), 0755, true); mkdir(dirname($snapshotFilename), 0755, true);
@ -103,33 +96,16 @@ final class SnapshotRepository
} }
} }
/**
* Gets the snapshot's "filename" and "description".
*
* @return array{0: string, 1: string}
*/
private function getFilenameAndDescription(TestCase $testCase): array
{
$filename = (fn () => self::$__filename)->call($testCase, $testCase::class); // @phpstan-ignore-line
$description = str_replace('__pest_evaluable_', '', $testCase->name());
$datasetAsString = str_replace('__pest_evaluable_', '', Str::evaluable($testCase->dataSetAsStringWithData()));
$description = str_replace(' ', '_', $description.$datasetAsString);
return [$filename, $description];
}
/** /**
* Gets the snapshot's "filename". * Gets the snapshot's "filename".
*/ */
private function getSnapshotFilename(string $filename, string $description): string private function getSnapshotFilename(): string
{ {
$relativePath = str_replace($this->testsPath, '', $filename); $relativePath = str_replace($this->testsPath, '', TestSuite::getInstance()->getFilename());
// remove extension from filename // remove extension from filename
$relativePath = substr($relativePath, 0, (int) strrpos($relativePath, '.')); $relativePath = substr($relativePath, 0, (int) strrpos($relativePath, '.'));
return sprintf('%s/%s.snap', $this->testsPath.'/'.$this->snapshotsPath.$relativePath, $description); return sprintf('%s/%s.snap', $this->testsPath.'/'.$this->snapshotsPath.$relativePath, TestSuite::getInstance()->getDescription());
} }
} }

View File

@ -11,6 +11,7 @@ use Pest\Repositories\BeforeAllRepository;
use Pest\Repositories\BeforeEachRepository; use Pest\Repositories\BeforeEachRepository;
use Pest\Repositories\SnapshotRepository; use Pest\Repositories\SnapshotRepository;
use Pest\Repositories\TestRepository; use Pest\Repositories\TestRepository;
use Pest\Support\Str;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
/** /**
@ -105,4 +106,21 @@ final class TestSuite
return self::$instance; return self::$instance;
} }
public function getFilename(): string
{
assert($this->test instanceof TestCase);
return (fn () => self::$__filename)->call($this->test, $this->test::class); // @phpstan-ignore-line
}
public function getDescription(): string
{
assert($this->test instanceof TestCase);
$description = str_replace('__pest_evaluable_', '', $this->test->name());
$datasetAsString = str_replace('__pest_evaluable_', '', Str::evaluable($this->test->dataSetAsStringWithData()));
return str_replace(' ', '_', $description.$datasetAsString);
}
} }

View File

@ -16,13 +16,13 @@ beforeEach(function () {
}); });
test('pass', function () { test('pass', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
expect($this->snapshotable)->toMatchSnapshot(); expect($this->snapshotable)->toMatchSnapshot();
}); });
test('pass with `__toString`', function () { test('pass with `__toString`', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
$object = new class($this->snapshotable) $object = new class($this->snapshotable)
{ {
@ -40,7 +40,7 @@ test('pass with `__toString`', function () {
}); });
test('pass with `toString`', function () { test('pass with `toString`', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
$object = new class($this->snapshotable) $object = new class($this->snapshotable)
{ {
@ -58,8 +58,8 @@ test('pass with `toString`', function () {
}); });
test('pass with dataset', function ($data) { test('pass with dataset', function ($data) {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
[$filename] = TestSuite::getInstance()->snapshots->get($this, $this->snapshotable); [$filename] = TestSuite::getInstance()->snapshots->get();
expect($filename)->toEndWith('pass_with_dataset_with_data_set____my_datas_set_value______my_datas_set_value__.snap') expect($filename)->toEndWith('pass_with_dataset_with_data_set____my_datas_set_value______my_datas_set_value__.snap')
->and($this->snapshotable)->toMatchSnapshot(); ->and($this->snapshotable)->toMatchSnapshot();
@ -67,8 +67,8 @@ test('pass with dataset', function ($data) {
describe('within describe', function () { describe('within describe', function () {
test('pass with dataset', function ($data) { test('pass with dataset', function ($data) {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
[$filename] = TestSuite::getInstance()->snapshots->get($this, $this->snapshotable); [$filename] = TestSuite::getInstance()->snapshots->get();
expect($filename)->toEndWith('pass_with_dataset_with_data_set____my_datas_set_value______my_datas_set_value__.snap') expect($filename)->toEndWith('pass_with_dataset_with_data_set____my_datas_set_value______my_datas_set_value__.snap')
->and($this->snapshotable)->toMatchSnapshot(); ->and($this->snapshotable)->toMatchSnapshot();
@ -76,7 +76,7 @@ describe('within describe', function () {
})->with(['my-datas-set-value']); })->with(['my-datas-set-value']);
test('pass with `toArray`', function () { test('pass with `toArray`', function () {
TestSuite::getInstance()->snapshots->save($this, json_encode(['key' => $this->snapshotable], JSON_PRETTY_PRINT)); TestSuite::getInstance()->snapshots->save(json_encode(['key' => $this->snapshotable], JSON_PRETTY_PRINT));
$object = new class($this->snapshotable) $object = new class($this->snapshotable)
{ {
@ -96,7 +96,7 @@ test('pass with `toArray`', function () {
}); });
test('pass with array', function () { test('pass with array', function () {
TestSuite::getInstance()->snapshots->save($this, json_encode(['key' => $this->snapshotable], JSON_PRETTY_PRINT)); TestSuite::getInstance()->snapshots->save(json_encode(['key' => $this->snapshotable], JSON_PRETTY_PRINT));
expect([ expect([
'key' => $this->snapshotable, 'key' => $this->snapshotable,
@ -104,19 +104,19 @@ test('pass with array', function () {
}); });
test('failures', function () { test('failures', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
expect('contain that does not match snapshot')->toMatchSnapshot(); expect('contain that does not match snapshot')->toMatchSnapshot();
})->throws(ExpectationFailedException::class, 'Failed asserting that two strings are identical.'); })->throws(ExpectationFailedException::class, 'Failed asserting that two strings are identical.');
test('failures with custom message', function () { test('failures with custom message', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
expect('contain that does not match snapshot')->toMatchSnapshot('oh no'); expect('contain that does not match snapshot')->toMatchSnapshot('oh no');
})->throws(ExpectationFailedException::class, 'oh no'); })->throws(ExpectationFailedException::class, 'oh no');
test('not failures', function () { test('not failures', function () {
TestSuite::getInstance()->snapshots->save($this, $this->snapshotable); TestSuite::getInstance()->snapshots->save($this->snapshotable);
expect($this->snapshotable)->not->toMatchSnapshot(); expect($this->snapshotable)->not->toMatchSnapshot();
})->throws(ExpectationFailedException::class); })->throws(ExpectationFailedException::class);