mirror of https://github.com/stretchr/testify.git
Added assertion/requirement that checks if two JSON strings represent equivalent objects
parent
b8dc1cecf1
commit
930ea90dbd
|
@ -3,6 +3,7 @@ package assert
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
|
@ -909,3 +910,37 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||
expectSlice := false
|
||||
expectedJSONAsMap := make(map[string]interface{})
|
||||
expectedJSONAsSlice := make([]interface{}, 0, 0)
|
||||
|
||||
actualJSONAsMap := make(map[string]interface{})
|
||||
actualJSONAsSlice := make([]interface{}, 0, 0)
|
||||
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsMap); err != nil {
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsSlice); err == nil {
|
||||
expectSlice = true
|
||||
} else {
|
||||
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
if expectSlice {
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsSlice); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
|
||||
}
|
||||
return Equal(t, expectedJSONAsSlice, actualJSONAsSlice, msgAndArgs...)
|
||||
} else {
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsMap); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
|
||||
}
|
||||
return Equal(t, expectedJSONAsMap, actualJSONAsMap, msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
i interface{}
|
||||
i interface{}
|
||||
zeros = []interface{}{
|
||||
false,
|
||||
byte(0),
|
||||
|
@ -903,3 +903,18 @@ func TestNotZero(t *testing.T) {
|
|||
True(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
|
||||
True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
|
||||
True(t, JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}"))
|
||||
True(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`))
|
||||
False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`))
|
||||
False(t, JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
|
||||
False(t, JSONEq(mockT, `{"foo": "bar"}`, "Not JSON"))
|
||||
False(t, JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`))
|
||||
False(t, JSONEq(mockT, "Not JSON", "Not JSON"))
|
||||
}
|
||||
|
|
|
@ -273,3 +273,12 @@ func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
|
|||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||
return JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
|
|
@ -535,3 +535,44 @@ func TestNotZeroWrapper(t *testing.T) {
|
|||
assert.True(mockAssert.NotZero(test), "Zero should return false for %v", test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
if !assert.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
if !assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
|
||||
if assert.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
|
||||
if assert.JSONEq(`{"foo": "bar"}`, "Not JSON") {
|
||||
t.Error("JSONEq should return false for invalid JSON")
|
||||
}
|
||||
|
||||
if assert.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
|
||||
if assert.JSONEq("Not JSON", "Not JSON") {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,3 +219,12 @@ func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
|
|||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
|
||||
NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {
|
||||
JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
|
|
@ -282,3 +282,56 @@ func TestNotZeroWrapper(t *testing.T) {
|
|||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper(t *testing.T) {
|
||||
// mockRequire := New(new(testing.T))
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("JSONEq should pass")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("JSONEq should pass")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
|
||||
if mockT.Failed {
|
||||
t.Error("JSONEq should pass")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
t.Error("JSONEq should pass")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("JSONEq should fail")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("JSONEq should fail")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq(`{"foo": "bar"}`, "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("JSONEq should fail")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("JSONEq should fail")
|
||||
}
|
||||
|
||||
mockRequire.JSONEq("Not JSON", "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("JSONEq should fail")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package require
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -228,6 +229,40 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
|||
}
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
|
||||
expectSlice := false
|
||||
expectedJSONAsMap := make(map[string]interface{})
|
||||
expectedJSONAsSlice := make([]interface{}, 0, 0)
|
||||
|
||||
actualJSONAsMap := make(map[string]interface{})
|
||||
actualJSONAsSlice := make([]interface{}, 0, 0)
|
||||
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsMap); err != nil {
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsSlice); err == nil {
|
||||
expectSlice = true
|
||||
} else {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
if expectSlice {
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsSlice); err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
Equal(t, expectedJSONAsSlice, actualJSONAsSlice, msgAndArgs...)
|
||||
} else {
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsMap); err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
Equal(t, expectedJSONAsMap, actualJSONAsMap, msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Errors
|
||||
*/
|
||||
|
|
|
@ -286,3 +286,53 @@ func TestNotZero(t *testing.T) {
|
|||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
|
||||
JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
|
||||
JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
|
||||
JSONEq(mockT, `{"foo": "bar"}`, "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
|
||||
JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
|
||||
JSONEq(mockT, "Not JSON", "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue