-
Notifications
You must be signed in to change notification settings - Fork 36
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
Decouple different snapshot functionality #754
base: main
Are you sure you want to change the base?
Conversation
…ifferent parts of the extension interface separately.
This might be a very bad idea, but it also seems like it might be in line with the original plugin architecture intent. Curious your thoughts. |
Will give this more thought at some point this week. Initial thought is that this should be doable with a custom extension like so (not tested, but I think this should work) from syrupy.extensions.amber import AmberDataSerializer
from syrupy.extensions.single_file import SingleFileSnapshotExtension
class SingleFileAmberSnapshotExtension(SingleFileSnapshotExtension):
def serialize(self, data, **kwargs) -> "SerializedData":
return AmberDataSerializer.serialize(data, **kwargs) |
I think you're right but it's very confusing to me how the library is set up. It seems like there are two broad philosophies to plugins:
Inheriting from an extension and overriding seems weird to me because it's doing both. That said, there's a lot I don't understand about this codebase which prevents me from being confident in this PR:
|
I agree with that. There's definitely room to improve here. The codebase has already gone through several refactors, though it's pretty stable right now so I'd be hesitant to change anything too drastic without good reason. We also want to reduce the number of breaking changes if we can help it.
Amber is a custom format we built intended to reduce the size of diffs and be easy to review in pull requests. We don't need the ability to deserialize, only serialize. The name is a play on words with the theme of "syrupy" that used to be more prevalent in the codebase. There was a strong Jurassic Park theme (syrupy = amber / fossils etc). We've expunged most of this from the codebase to improve readability.
The extension defines an interface so to speak. It does not have any instance state.
There was some recent refactoring to support pytest-xdist. Moving off of instances made it a lot simpler to reason about. Helps with performance as well. We cache some function calls using the extension class type. Not something we could easily do if there was instance data we had to consider.
It lets you customize specific assertions. The post_assert resets the snapshot fixture in between assertions. Lets you do things like:
|
True, though that's beside the point. One place where this is awkward is with
This makes sense. Something I'll have to look into.
I see that. The more obvious way to do this seems to be to have def test_case(snapshot):
s = snapshot(exclude=props("a"))
assert x == s
assert y == s It might make sense to use |
Just posting to let you know I haven't forgotten about this. I do agree there's plenty of opportunity to simplify the architecture. I'd prefer to try more incremental changes in advance of any larger public API change (to reduce breaking changes and adoption pains). I'm not sure I have too much time over the next few months to support large scale changes though. FWIW, a lot of the initial implementation was based on attrs before dataclasses, and when we moved to dataclasses we only did the bare minimum so it was functional. Leaning on newer patterns to simplify the code and make it easier to contribute to is definitely something I'm interested in. And if you're curious, you were 100% right about the initial design for the extensions/plugins being closer to the |
Only |
The following snippet works beautifully: class SingleFileAmberSnapshotExtension(SingleFileSnapshotExtension):
_file_extension = 'ambr'
_write_mode = WriteMode.TEXT
def serialize(self, data, **kwargs):
return AmberDataSerializer.serialize(data, **kwargs) |
Decouple different snapshot functionality
Description
e.g. The plugin architecture is defined with multiple subparts. This plugin allows implementing those separately - e.g. you can use a different serializer from comparator.
Related Issues
Checklist
Additional Comments
No additional comments.