Skip to content

Commit

Permalink
Add matching checker (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop committed Apr 12, 2023
1 parent 04c2462 commit b42051d
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 4 deletions.
17 changes: 13 additions & 4 deletions equal.go
Expand Up @@ -122,7 +122,7 @@ func (c Comparer) varCollected(s string, v interface{}) bool {
return false
}

func (c Comparer) filterDeltas(deltas []gojsondiff.Delta) []gojsondiff.Delta {
func (c Comparer) filterDeltas(deltas []gojsondiff.Delta, ignoreAdded bool) []gojsondiff.Delta {
result := make([]gojsondiff.Delta, 0, len(deltas))

for _, delta := range deltas {
Expand All @@ -142,19 +142,24 @@ func (c Comparer) filterDeltas(deltas []gojsondiff.Delta) []gojsondiff.Delta {
}
}
case *gojsondiff.Object:
v.Deltas = c.filterDeltas(v.Deltas)
v.Deltas = c.filterDeltas(v.Deltas, ignoreAdded)
if len(v.Deltas) == 0 {
continue
}

delta = v
case *gojsondiff.Array:
v.Deltas = c.filterDeltas(v.Deltas)
v.Deltas = c.filterDeltas(v.Deltas, ignoreAdded)
if len(v.Deltas) == 0 {
continue
}

delta = v

case *gojsondiff.Added:
if ignoreAdded {
continue
}
}

result = append(result, delta)
Expand Down Expand Up @@ -237,6 +242,10 @@ func (c Comparer) FailNotEqualMarshal(expected []byte, actualValue interface{})

// FailNotEqual returns error if JSON payloads are different, nil otherwise.
func (c Comparer) FailNotEqual(expected, actual []byte) error {
return c.fail(expected, actual, false)
}

func (c Comparer) fail(expected, actual []byte, ignoreAdded bool) error {
var expDecoded, actDecoded interface{}

expected, err := c.filterExpected(expected)
Expand Down Expand Up @@ -277,7 +286,7 @@ func (c Comparer) FailNotEqual(expected, actual []byte) error {
return nil
}

diffValue = &diff{deltas: c.filterDeltas(diffValue.Deltas())}
diffValue = &diff{deltas: c.filterDeltas(diffValue.Deltas(), ignoreAdded)}
if !diffValue.Modified() {
return nil
}
Expand Down
92 changes: 92 additions & 0 deletions matches.go
@@ -0,0 +1,92 @@
package assertjson

import (
"strings"

"github.com/stretchr/testify/assert"
)

// Matches compares two JSON payloads.
// It ignores added fields in actual JSON payload.
func (c Comparer) Matches(t TestingT, expected, actual []byte, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}

err := c.FailMismatch(expected, actual)
if err == nil {
return true
}

msg := err.Error()
msg = strings.ToUpper(msg[0:1]) + msg[1:]
assert.Fail(t, msg, msgAndArgs...)

return false
}

// MatchesMarshal marshals actual JSON payload and compares it with expected payload.
// It ignores added fields in actual JSON payload.
func (c Comparer) MatchesMarshal(t TestingT, expected []byte, actualValue interface{}, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}

actual, err := MarshalIndentCompact(actualValue, "", " ", 80)
assert.NoError(t, err, "failed to marshal actual value")

if len(msgAndArgs) == 0 {
msgAndArgs = append(msgAndArgs, string(actual))
}

return c.Matches(t, expected, actual, msgAndArgs...)
}

// FailMismatch returns error if expected JSON payload does not match actual JSON payload, nil otherwise.
// It ignores added fields in actual JSON payload.
func FailMismatch(expected, actual []byte) error {
return defaultComparer.FailMismatch(expected, actual)
}

// FailMismatchMarshal returns error if expected JSON payload does not match marshaled actual value, nil otherwise.
// It ignores added fields in actual JSON payload.
func FailMismatchMarshal(expected []byte, actualValue interface{}) error {
return defaultComparer.FailMismatchMarshal(expected, actualValue)
}

// FailMismatchMarshal returns error if expected JSON payload does not match marshaled actual value, nil otherwise.
// It ignores added fields in actual JSON payload.
func (c Comparer) FailMismatchMarshal(expected []byte, actualValue interface{}) error {
actual, err := MarshalIndentCompact(actualValue, "", " ", 80)
if err != nil {
return err
}

return c.FailMismatch(expected, actual)
}

// FailMismatch returns error if expected JSON payload does not match actual JSON payload, nil otherwise.
// It ignores added fields in actual JSON payload.
func (c Comparer) FailMismatch(expected, actual []byte) error {
return c.fail(expected, actual, true)
}

// Matches compares two JSON documents ignoring string values "<ignore-diff>".
// It ignores added fields in actual JSON payload.
func Matches(t TestingT, expected, actual []byte, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}

return defaultComparer.Matches(t, expected, actual, msgAndArgs...)
}

// MatchesMarshal marshals actual value and compares two JSON documents ignoring string values "<ignore-diff>".
// It ignores added fields in actual JSON payload.
func MatchesMarshal(t TestingT, expected []byte, actualValue interface{}, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}

return defaultComparer.MatchesMarshal(t, expected, actualValue, msgAndArgs...)
}
42 changes: 42 additions & 0 deletions matches_test.go
@@ -0,0 +1,42 @@
package assertjson_test

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
"github.com/swaggest/assertjson"
)

func TestFailMismatch(t *testing.T) {
act := json.RawMessage(`{"a": 1, "b": 2, "c": {"d": 1, "e": 2}}`)
exp := []byte(`{"a": 1, "c": {"d": 1}}`)
expFail := []byte(`{"a": 1, "c": {"d": 2}}`)

assert.EqualError(t, assertjson.FailNotEqualMarshal(exp, act), `not equal:
{
"a": 1,
"c": {
"d": 1
+ "e": 2
}
+ "b": 2
}
`)

assert.NoError(t, assertjson.FailMismatchMarshal(exp, act))
assert.NoError(t, assertjson.FailMismatch(exp, act))
assert.EqualError(t, assertjson.FailMismatchMarshal(expFail, act), `not equal:
{
"a": 1,
"c": {
- "d": 2
+ "d": 1
}
}
`)

assert.False(t, assertjson.MatchesMarshal(testingT(func(format string, args ...interface{}) {}), expFail, act))
assertjson.MatchesMarshal(t, exp, act)
assertjson.Matches(t, exp, act)
}

0 comments on commit b42051d

Please sign in to comment.