Skip to content

Commit 6b51fb8

Browse files
committed
Adding MarshalsEquivalentJSON to value assertions
1 parent 0486df2 commit 6b51fb8

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

assert/value.go

+42-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package assert
22

33
import (
4+
"bytes"
5+
"encoding/json"
46
"fmt"
57
"reflect"
68
)
79

10+
const (
11+
jsonIndent = " "
12+
)
13+
814
// AssertableValue represents an under-test value that's expected to meet
915
// certain criteria.
1016
type AssertableValue interface {
@@ -34,6 +40,12 @@ type AssertableValue interface {
3440
// IsTrue asserts that the specified actual value is true.
3541
// Returns a ValueAssertionResult that provides post-assert actions.
3642
IsTrue() ValueAssertionResult
43+
44+
// MarshalsEquivalentJSON asserts that the specified actual value yields
45+
// a JSON encoding equivalent to that of the specified expected value.
46+
// See https://golang.org/pkg/encoding/json/#Marshal for encoding details.
47+
// Returns a ValueAssertionResult that provides post-assert actions.
48+
MarshalsEquivalentJSON(expected interface{}) ValueAssertionResult
3749
}
3850

3951
type assertableValue struct {
@@ -50,16 +62,20 @@ type anyOtherValue struct{}
5062
func (actual *assertableValue) Equals(expected interface{}) ValueAssertionResult {
5163
areEqual := reflect.DeepEqual(actual.value, expected)
5264
if !areEqual {
53-
if fmt.Sprint(actual.value) == fmt.Sprint(expected) {
54-
actual.testContext.decoratedErrorf(
55-
"Type mismatch.\nActual: %T=%v\nExpected: %T=%v\n", actual.value, actual.value, expected, expected)
56-
} else {
57-
actual.testContext.decoratedErrorf("Value mismatch.\nActual: %#v\nExpected: %#v\n", actual.value, expected)
58-
}
65+
actual.printValueMismatchError(expected)
5966
}
6067
return &valueAssertionResult{bool: areEqual, actual: actual.value, expected: expected}
6168
}
6269

70+
func (actual *assertableValue) printValueMismatchError(expected interface{}) {
71+
if fmt.Sprint(actual.value) == fmt.Sprint(expected) {
72+
actual.testContext.decoratedErrorf(
73+
"Type mismatch.\nActual: %T=%v\nExpected: %T=%v\n", actual.value, actual.value, expected, expected)
74+
} else {
75+
actual.testContext.decoratedErrorf("Value mismatch.\nActual: %#v\nExpected: %#v\n", actual.value, expected)
76+
}
77+
}
78+
6379
func (actual *assertableValue) DoesNotEqual(value interface{}) ValueAssertionResult {
6480
areEqual := reflect.DeepEqual(actual.value, value)
6581
if areEqual {
@@ -83,3 +99,23 @@ func (actual *assertableValue) IsFalse() ValueAssertionResult {
8399
func (actual *assertableValue) IsTrue() ValueAssertionResult {
84100
return actual.Equals(true)
85101
}
102+
103+
func (actual *assertableValue) MarshalsEquivalentJSON(expected interface{}) ValueAssertionResult {
104+
var expectedBytes []byte
105+
actualBytes, err := json.MarshalIndent(actual.value, "", jsonIndent)
106+
if err != nil {
107+
goto mismatch
108+
}
109+
expectedBytes, err = json.MarshalIndent(expected, "", jsonIndent)
110+
if err != nil {
111+
goto mismatch
112+
}
113+
if !bytes.Equal(actualBytes, expectedBytes) {
114+
goto mismatch
115+
}
116+
return &valueAssertionResult{bool: true, actual: actual.value, expected: expected}
117+
118+
mismatch:
119+
actual.testContext.decoratedErrorf("JSON mismatch.\nActual: %s\nExpected: %s\n", actualBytes, expectedBytes)
120+
return &valueAssertionResult{bool: false, actual: actual.value, expected: expected}
121+
}

assert/value_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,32 @@ func ExampleAssertableValue_IsTrue_fail() {
145145
// Expected: true
146146
// Assertion failed successfully!
147147
}
148+
149+
func ExampleAssertableValue_MarshalsEquivalentJSON_pass() {
150+
foo := &struct {
151+
Key string `json:"key"`
152+
}{
153+
Key: "value",
154+
}
155+
equivalentToFoo := &struct {
156+
Key string `json:"key"`
157+
}{
158+
Key: "value",
159+
}
160+
161+
if For(t).ThatActual(foo).MarshalsEquivalentJSON(equivalentToFoo).Passed() {
162+
fmt.Println("Passed!")
163+
}
164+
// Output: Passed!
165+
}
166+
167+
func ExampleAssertableValue_MarshalsEquivalentJSON_fail() {
168+
if !mockTestContextToAssert().ThatActual(nil).MarshalsEquivalentJSON("").Passed() {
169+
fmt.Println("Assertion failed successfully!")
170+
}
171+
// Output:
172+
// file:3: JSON mismatch.
173+
// Actual: null
174+
// Expected: ""
175+
// Assertion failed successfully!
176+
}

0 commit comments

Comments
 (0)