approvals / go-approval-tests

Apache License 2.0
86 stars 22 forks source link

Initial JSONPath scrubber #42

Open bardzusny opened 2 years ago

bardzusny commented 2 years ago

A proof-of-concept PR implementing https://github.com/approvals/go-approval-tests/issues/38 .

Ignore the implementation details for now, focus on the public API.

If it looks right then we can work on it! (I'll also happily rebase commits to fit the preferred notation.)

Description

Adds basic support for scrubbing values by passed JSONPath. To be used with approvals.VerifyJsonStruct(...) and approvals.VerifyJSONBytes(...).

Usage examples:

opts := approvals.Options().WithJSONPathScrubber("id", "<scrubbed_id>")

jb := []byte(`{ "id": 1 }`)
approvals.VerifyJSONBytes(t, jb, opts)

Also works for scrubbing properties in lists of objects:

 opts := approvals.Options().WithJSONPathScrubber("items[*].id", "<scrubbed_id>")

jb := []byte(`{ "items": [{ "id": 1 }, { "id": 2 }] }`)
approvals.VerifyJSONBytes(t, jb, opts)

The solution

What happens during scrubbing:

  1. The JSON string is un-marshalled into a https://pkg.go.dev/github.com/bitly/go-simplejson struct.
  2. A recursive function scrubs values based on the passed path.
  3. Resulting simplejson struct is marshalled back into a pretty-printed JSON.

What's nice: it works and should be good great for most common usage:

  1. Scrubbing object properties.
  2. Scrubbing properties in lists of objects.

The things left to iterate on (in this PR or later):

  1. Would be nice to drop simplejson dependency.
  2. Doesn't look optimal perf-wise to pass JSON string to a scrubber instead of the original map.
  3. Doesn't implement full JSONPath proposal.