From 906706b966e2999e601d437fb3edd1a93d4f2fff Mon Sep 17 00:00:00 2001 From: Sandro Gehri Date: Thu, 7 Sep 2023 21:27:15 +0200 Subject: [PATCH] add macros and interceptors to snapshot testing --- composer.json | 1 + src/Mixins/Expectation.php | 7 ++- src/Plugins/Snapshot.php | 44 +++++++++++++++++-- .../Expect/toMatchSnapshot/custom_macro.snap | 1 + .../Expect/toMatchSnapshot/disable_macro.snap | 1 + .../Expect/toMatchSnapshot/intercept.snap | 1 + tests/.snapshots/success.txt | 5 ++- tests/Features/Expect/toMatchSnapshot.php | 31 +++++++++++++ tests/Fixtures/Snapshot/Color.php | 18 ++++++++ tests/Visual/Parallel.php | 2 +- 10 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 tests/.pest/snapshots/Features/Expect/toMatchSnapshot/custom_macro.snap create mode 100644 tests/.pest/snapshots/Features/Expect/toMatchSnapshot/disable_macro.snap create mode 100644 tests/.pest/snapshots/Features/Expect/toMatchSnapshot/intercept.snap create mode 100644 tests/Fixtures/Snapshot/Color.php diff --git a/composer.json b/composer.json index 778f92110..2e1ba7ff9 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ "Tests\\Fixtures\\Covers\\": "tests/Fixtures/Covers", "Tests\\Fixtures\\Inheritance\\": "tests/Fixtures/Inheritance", "Tests\\Fixtures\\Arch\\": "tests/Fixtures/Arch", + "Tests\\Fixtures\\Snapshot\\": "tests/Fixtures/Snapshot", "Tests\\": "tests/PHPUnit/" }, "files": [ diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 9145949b5..26b4198a0 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -13,6 +13,7 @@ use JsonSerializable; use Pest\Exceptions\InvalidExpectationValue; use Pest\Matchers\Any; +use Pest\Plugins\Snapshot; use Pest\Support\Arr; use Pest\Support\Exporter; use Pest\Support\NullClosure; @@ -844,9 +845,9 @@ public function toMatchSnapshot(string $message = ''): self $string = match (true) { is_string($this->value) => $this->value, + is_object($this->value) && array_key_exists($this->value::class, Snapshot::getInterceptors()) => Snapshot::getInterceptors()[$this->value::class]($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(), - $this->value instanceof \Illuminate\Testing\TestResponse => $this->value->getContent(), // @phpstan-ignore-line is_array($this->value) => json_encode($this->value, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), $this->value instanceof Traversable => json_encode(iterator_to_array($this->value), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), $this->value instanceof JsonSerializable => json_encode($this->value->jsonSerialize(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), @@ -854,6 +855,10 @@ public function toMatchSnapshot(string $message = ''): self default => InvalidExpectationValue::expected('array|object|string'), }; + foreach (Snapshot::getMacros() as $macro) { + $string = $macro($string); + } + if ($snapshots->has()) { [$filename, $content] = $snapshots->get(); diff --git a/src/Plugins/Snapshot.php b/src/Plugins/Snapshot.php index 717512c2f..1c5cc997f 100644 --- a/src/Plugins/Snapshot.php +++ b/src/Plugins/Snapshot.php @@ -8,13 +8,20 @@ use Pest\Exceptions\InvalidOption; use Pest\TestSuite; -/** - * @internal - */ final class Snapshot implements HandlesArguments { use Concerns\HandleArguments; + /** + * @var array + */ + private static array $macros = []; + + /** + * @var array + */ + private static array $interceptors = []; + /** * {@inheritDoc} */ @@ -32,4 +39,35 @@ public function handleArguments(array $arguments): array return $this->popArgument('--update-snapshots', $arguments); } + + public static function intercept(string $class, callable $callable): void + { + self::$interceptors[$class] = $callable; + } + + /** + * @return array + */ + public static function getInterceptors(): array + { + return self::$interceptors; + } + + public static function macro(string $key, callable $callable): void + { + self::$macros[$key] = $callable; + } + + public static function disableMacro(string $key): void + { + unset(self::$macros[$key]); + } + + /** + * @return array + */ + public static function getMacros(): array + { + return self::$macros; + } } diff --git a/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/custom_macro.snap b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/custom_macro.snap new file mode 100644 index 000000000..99faba772 --- /dev/null +++ b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/custom_macro.snap @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/disable_macro.snap b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/disable_macro.snap new file mode 100644 index 000000000..5cb78ffe4 --- /dev/null +++ b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/disable_macro.snap @@ -0,0 +1 @@ +
foo
\ No newline at end of file diff --git a/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/intercept.snap b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/intercept.snap new file mode 100644 index 000000000..6bd78ff2c --- /dev/null +++ b/tests/.pest/snapshots/Features/Expect/toMatchSnapshot/intercept.snap @@ -0,0 +1 @@ +rgba(255, 0, 0, 1) \ No newline at end of file diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 72376212d..4bb15487a 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -820,6 +820,9 @@ ✓ multiple snapshot expectations with repeat @ repetition 8 of 10 ✓ multiple snapshot expectations with repeat @ repetition 9 of 10 ✓ multiple snapshot expectations with repeat @ repetition 10 of 10 + ✓ custom macro + ✓ disable macro + ✓ intercept PASS Tests\Features\Expect\toStartWith ✓ pass @@ -1325,4 +1328,4 @@ WARN Tests\Visual\Version - visual snapshot of help command output - Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 939 passed (2220 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 942 passed (2223 assertions) \ No newline at end of file diff --git a/tests/Features/Expect/toMatchSnapshot.php b/tests/Features/Expect/toMatchSnapshot.php index ed5c8458b..b6899edcc 100644 --- a/tests/Features/Expect/toMatchSnapshot.php +++ b/tests/Features/Expect/toMatchSnapshot.php @@ -1,7 +1,9 @@ snapshotable = <<<'HTML' @@ -146,3 +148,32 @@ public function toArray() expect('foo bar 2')->toMatchSnapshot(); })->repeat(10); + +test('custom macro', function () { + Snapshot::macro('test', function (string $value) { + return preg_replace('/key="[0-9]*"/', 'key="..."', $value); + }); + + expect('
foo
') + ->toMatchSnapshot(); +}); + +test('disable macro', function () { + Snapshot::macro('test', function (string $value) { + return preg_replace('/key="[0-9]*"/', 'key="..."', $value); + }); + + Snapshot::disableMacro('test'); + + expect('
foo
') + ->toMatchSnapshot(); +}); + +test('intercept', function () { + Snapshot::intercept(Color::class, function (Color $color): string { + return $color->getStyle(); + }); + + expect(new Color(255, 0, 0)) + ->toMatchSnapshot(); +}); diff --git a/tests/Fixtures/Snapshot/Color.php b/tests/Fixtures/Snapshot/Color.php new file mode 100644 index 000000000..08b814069 --- /dev/null +++ b/tests/Fixtures/Snapshot/Color.php @@ -0,0 +1,18 @@ +red.', '.$this->green.', '.$this->blue.', 1)'; + } +} diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 3418753ad..8dec666f9 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -16,7 +16,7 @@ test('parallel', function () use ($run) { expect($run('--exclude-group=integration')) - ->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 928 passed (2205 assertions)') + ->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 931 passed (2208 assertions)') ->toContain('Parallel: 3 processes'); })->skipOnWindows();