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

Ordering JSON keys of Python dictionary snapshots #618

Closed
willgdjones opened this issue Aug 18, 2022 · 7 comments · Fixed by #673
Closed

Ordering JSON keys of Python dictionary snapshots #618

willgdjones opened this issue Aug 18, 2022 · 7 comments · Fixed by #673

Comments

@willgdjones
Copy link

willgdjones commented Aug 18, 2022

Thanks for the great library!

We'd like to order the JSON keys alphabetically by information in the value, not just by the key. We are using the JSONSnapshotExtension. The reason is that we'd like to preserve sensible diffs in version control even if the names of the keys change, since the reordering appears as large deletions and additions of code.

For example, we'd like to make sure the snapshotted JSON is sorted by the value of the "Type" (first a, then b) etc...

{
  'b': {
    {
      "Type": "a",
      "Data": "X"
    },
  'a': {
    {
      "Type": "b",
      "Data": "Y"
    }
}

Not obvious how to do this because Python dictionaries are unordered, and using OrderedDict doesn't seem to preserve order.

Thanks!

@noahnu noahnu added the feature request New feature or request label Aug 18, 2022
@noahnu
Copy link
Collaborator

noahnu commented Aug 18, 2022

It looks like we don't treat OrderedDicts any differently from regular dicts. Arguably we should do an instanceof OrderedDict check and if it's ordered, preserve the original key order rather than apply our key sort: https://github.com/tophat/syrupy/blob/1d3ae5779e1a19f998895f3812187e0ddc57fd79/src/syrupy/extensions/amber/serializer.py#L172

This would be a breaking change though but I think it makes sense.

@noahnu noahnu added this to the v4.0.0 - Performance milestone Aug 18, 2022
@willgdjones
Copy link
Author

Makes sense! In the meantime, we have converted the dictionary to a list of key, value pairs, which seems to work ok. It would be cleaner to have it as JSON dictionary key, values but the workaround is ok for the time being.

Thanks for the help!

@willgdjones
Copy link
Author

Why would it be a breaking change?

@willgdjones
Copy link
Author

willgdjones commented Aug 18, 2022

This could be something that I can take a look at contributing too

@noahnu
Copy link
Collaborator

noahnu commented Aug 18, 2022

It'd be a breaking change to change the default snapshot behaviour because folks would have to run --snapshot-update to adopt the latest version of syrupy.

That being said, a non-breaking approach would be to extend the data serializer class or add a feature for custom key ordering.

@noahnu
Copy link
Collaborator

noahnu commented Dec 30, 2022

#673 will ensure OrderedDict keys are kept ordered which means you can either switch to using OrderedDict in your code, or just wrap the value in an OrderedDict prior to snapshoting. Something like:

assert snapshot == OrderedDict(sorted(original_dict.items(), key=lambda v: v["Type"]))

@tophat-opensource-bot
Copy link
Contributor

🎉 This issue has been resolved in version 4.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants