|
| 1 | +package mockutils |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + |
| 6 | + "github.com/amp-labs/connectors/test/utils/testutils" |
| 7 | +) |
| 8 | + |
| 9 | +// JSONComparator offers helpers for structural equality checks between |
| 10 | +// arbitrary Go values and JSON documents. |
| 11 | +// |
| 12 | +// It provides a robust comparison mechanism for verifying JSON |
| 13 | +// equivalence in tests, ignoring superficial differences such as |
| 14 | +// whitespace, field order, or formatting. |
| 15 | +// |
| 16 | +// Example: |
| 17 | +// |
| 18 | +// type response struct { |
| 19 | +// ID string `json:"id"` |
| 20 | +// Name string `json:"name"` |
| 21 | +// } |
| 22 | +// |
| 23 | +// actual := response{ID: "123", Name: "Alice"} |
| 24 | +// expected := mockutils.JSONErrorWrapper(`{"name":"Alice","id":"123"}`) |
| 25 | +// |
| 26 | +// ok := mockutils.JSONComparator.Equals(actual, expected) |
| 27 | +// // ok == true (field order does not matter) |
| 28 | +// |
| 29 | +// This utility is primarily used by ErrorNormalizedComparator |
| 30 | +// to compare JSON-encoded error objects but can be reused |
| 31 | +// directly in tests where normalized JSON equality is needed. |
| 32 | +var JSONComparator = jsonComparator{} |
| 33 | + |
| 34 | +type jsonComparator struct{} |
| 35 | + |
| 36 | +// Equals reports whether the given Go value and a JSON-encoded |
| 37 | +// expected representation are structurally equivalent. |
| 38 | +// |
| 39 | +// It returns true if both JSON documents represent identical key-value |
| 40 | +// structures, ignoring field order and insignificant formatting. |
| 41 | +// |
| 42 | +// Any marshal or unmarshal failure results in false. |
| 43 | +func (jsonComparator) Equals(expected string, actual any) *testutils.CompareResult { |
| 44 | + result := testutils.NewCompareResult() |
| 45 | + |
| 46 | + actualBytes, err := json.Marshal(actual) |
| 47 | + if err != nil { |
| 48 | + result.AddDiff("jsonComparator.Equals: couldn't marshall: %v", actual) |
| 49 | + return result |
| 50 | + } |
| 51 | + |
| 52 | + actualJSON := make(map[string]any) |
| 53 | + if err = json.Unmarshal(actualBytes, &actualJSON); err != nil { |
| 54 | + result.AddDiff("jsonComparator.Equals: couldn't unmarshall 'actual' into map[string]any") |
| 55 | + return result |
| 56 | + } |
| 57 | + |
| 58 | + expectedJSON := make(map[string]any) |
| 59 | + if err = json.Unmarshal([]byte(expected), &expectedJSON); err != nil { |
| 60 | + result.AddDiff("jsonComparator.Equals: couldn't unmarshall 'expected' into map[string]any") |
| 61 | + return result |
| 62 | + } |
| 63 | + |
| 64 | + result.Assert("jsonComparator.Equals", actualJSON, expectedJSON) |
| 65 | + |
| 66 | + return result |
| 67 | +} |
| 68 | + |
| 69 | +func (jsonComparator) ListsEqual(expected []string, actual []any) (result *testutils.CompareResult) { |
| 70 | + result = testutils.NewCompareResult() |
| 71 | + |
| 72 | + if !result.Assert("jsonComparator.ListsEqual lists are of different sizes", len(expected), len(actual)) { |
| 73 | + return result |
| 74 | + } |
| 75 | + |
| 76 | + for index, e := range expected { |
| 77 | + a := actual[index] |
| 78 | + result.Merge(JSONComparator.Equals(e, a)) |
| 79 | + } |
| 80 | + |
| 81 | + return result |
| 82 | +} |
0 commit comments