syrupy-project / syrupy

:pancakes: The sweeter pytest snapshot plugin
https://syrupy-project.github.io/syrupy/
Apache License 2.0
553 stars 36 forks source link

Multiple matchers in custom serializer #898

Open tylerlaprade opened 1 month ago

tylerlaprade commented 1 month ago

Hi, is it possible to use multiple matchers in a single custom serializer? Right now I have this, but I want to add another matcher for datetime fields without disrupting my number matcher:

        return self.serializer_class.serialize(
            data,
            exclude=exclude,
            include=include,
            matcher=path_type(types=(float, Decimal), replacer=number_normalizer),
        )

I'm not seeing anything about this in the README

noahnu commented 1 month ago

The matcher is just a function that takes the data and path and returns the transformed data. path_type is a factory function. You can see the implementation here: https://github.com/syrupy-project/syrupy/blob/809cdfcf8861e95a1c5539491bb8933c9ad4a8db/src/syrupy/matchers.py#L36

I'm open to the idea of an alternative API to provide some syntactic sugar for per type replacers. If you have a suggestion or would like to propose a PR, it'd be appreciated. Otherwise you can achieve your objective with a custom matcher function. I can provide an example at some point later this week.

tylerlaprade commented 1 month ago

Thanks @noahnu. So you're suggesting for now I would make it match both types, then filter inside the matcher by type for the different logic? I can work with that for now.

In the long run, I'd suggest matchers which would take an array of the current matcher object. Any that contain matching types should be applied, sequentially if multiple are matched.

tylerlaprade commented 1 month ago

Actually, thinking more on this, for my current usecase I think I'd be better off excluding entirely the audit timestamp fields, which I should be able to do with exclude. But I can see how I might need to match different types against different logic in the future.