diff options
Diffstat (limited to 'jsonmatch/machinery.go')
| -rw-r--r-- | jsonmatch/machinery.go | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/jsonmatch/machinery.go b/jsonmatch/machinery.go index f3f5348..a10251a 100644 --- a/jsonmatch/machinery.go +++ b/jsonmatch/machinery.go @@ -26,7 +26,7 @@ func marshalExpectedForDiff(value any) string { func marshalActualForDiff(value any) string { // `actual` values are always safe to marshal because they were - // unmarshaled from JSON into any and thus can only contain safe + // unmarshaled from JSON into any and thus can only contain safe types buf, err := json.Marshal(value) if err != nil { // this line is therefore unreachable in tests and only exists as defense in depth @@ -121,8 +121,9 @@ func keyIntoPointerFragment(key string) string { } const ( - kindValueMismatch = "value mismatch" - kindTypeMismatch = "type mismatch" + kindValueMismatch = "value mismatch" + kindTypeMismatch = "type mismatch" + kindDispatchFailed = "dispatch failed" ) // NOTE: getDiffsForValue is the main part of the recursion to generate the diff. @@ -168,6 +169,29 @@ func getDiffsForValue(path []pathElement, expected, actual any) []Diff { } } + // generic handling for custom Diffables + // (if any unexpected error occurs here, we fall back to the default handling) + if diffable, ok := expected.(Diffable); ok { + // `actual` values are always safe to marshal because they were + // unmarshaled from JSON into any and thus can only contain safe types + buf, err := json.Marshal(actual) + if err != nil { + // this branch is therefore unreachable in tests and only exists as defense in depth + return []Diff{{ + Kind: kindDispatchFailed, + Pointer: pathIntoPointer(path), + ExpectedJSON: fmt.Sprintf("<custom diffable: %#v>", diffable), + ActualJSON: fmt.Sprintf("<marshal error: %s>", err.Error()), + }} + } + diffs := diffable.DiffAgainst(buf) + for idx, diff := range diffs { + diff.Pointer = pathIntoPointer(path) + diff.Pointer + diffs[idx] = diff + } + return diffs + } + // generic handling for values or structures that we do not recurse into further: // check that `expected` encodes to JSON in an equivalent way to `actual` actualJSON := marshalActualForDiff(actual) |
