Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Add macros and interceptors to snapshot testing #954

Closed

Conversation

gehrisandro
Copy link
Contributor

@gehrisandro gehrisandro commented Sep 7, 2023

What:

  • Bug Fix
  • New Feature

Description:

The primary purpose of this PR is to ensure snapshot testing works with CSRF tokens and other random data.

As discussed here the goal is handle common types of random data (CSRF token, Livewire wire:id, etc.) within Pest respectively within the Plugin it belongs to.
Besides that the new API is public allowing users to add their own macros and interceptors.

There are two related plugin PRs:

Intercept

This allows to intercept the toMatchSnapshot method for custom classes. This wouldn't be necessary to achieve the main goal but it makes the handling easier in the Plugins.

Example from the Laravel plugin PestServiceProvider. See this PR.

Snapshot::intercept(TestResponse::class, function (TestResponse $response): string {
    return $response->getContent();
});

Example for a custom interceptor:

test('create custom interceptor', function () {
    Snapshot::intercept(Color::class, function (Color $color): string {
        return $color->getStyle();
    });

    expect(new Color(255, 0, 0))
        ->toMatchSnapshot();
});

Nice side effect here, we can get rid of this unrelated TestResponse within the Pest core:

$this->value instanceof \Illuminate\Testing\TestResponse => $this->value->getContent(), // @phpstan-ignore-line

Macros

This allows to add macros to modify the snapshot string before the match is performed.

From the Livewire plugin PestServiceProvider. See this PR.

Snapshot::macro('livewire.wire-key', function (string $value) {
    return preg_replace('/wire:id="[0-9a-zA-Z]*"/', 'wire:id="..."', $value);
});

An example for a custom macro:

Snapshot::macro('time', function (string $value): string {
    return preg_replace('/[0-9]{2}:[0-9]{2}:[0-9]{2}/', '...', $value);
});

$value = 'The current time is '.now()->toTimeString();

expect($value)
    ->toMatchSnapshot();

Users can disable a Macro if they don't want to use it:

Snapshot::disableMacro('laravel.csrf');

Test repository

For an easy overview of all the new possibilities I've setup a test repository.

Documentation

For sure we have to update the documentation.
I am able to help there if you are happy with the decisions I made.

Draft

This and all related Plugin PRs are drafts. I have to clean them up and add more tests when you agree to the API suggested here.

Related:

#946

Copy link
Member

@owenvoke owenvoke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I love this and think it's really neat. 👍🏻 Will see what the others think though. 👀

@nunomaduro
Copy link
Member

Fixed here: pestphp/docs@a0b413c.

@nunomaduro nunomaduro closed this Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants