Skip to content

Commit

Permalink
Merge pull request #8 from bilginyuksel/feat/jsonarr-support
Browse files Browse the repository at this point in the history
Assert json array support
  • Loading branch information
cyucelen authored Oct 25, 2021
2 parents e1b4a4a + cdc457a commit 232faca
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 195 deletions.
192 changes: 20 additions & 172 deletions assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,219 +19,67 @@ package aduket
import (
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
"testing"

"github.com/clbanning/mxj"
"github.com/fatih/color"
"github.com/stretchr/testify/assert"
diff "github.com/yudai/gojsondiff"
"github.com/yudai/gojsondiff/formatter"
)

func (r RequestRecorder) AssertStringBodyEqual(t *testing.T, expectedBody string) bool {
actualBody := string(r.Data)

if expectedBody == actualBody {
return true
}

failTest(t, "String bodies are not equal!", func() {
color.Red("Actual:\t %s", actualBody)
color.Yellow("Expected: %s", expectedBody)
})

return false
return assert.Equal(t, expectedBody, string(r.Data))
}

func (r RequestRecorder) AssertJSONBodyEqual(t *testing.T, expectedBody interface{}) bool {
isEqual, err := isJSONEqual(expectedBody, r.Body)
expectedBodyBytes, err := json.Marshal(expectedBody)
if err != nil {
assert.Fail(t, err.Error())
t.Error("expected body could not marshaled to json")
}

if isEqual {
return true
}

failTest(t, "JSON Bodies are not equal!", func() {
printJSONDiff(expectedBody, r.Body)
})

return false
return assert.Equal(t, string(expectedBodyBytes), string(r.Body))
}

func (r RequestRecorder) AssertXMLBodyEqual(t *testing.T, expectedXMLBody interface{}) bool {
isEqual, err := isXMLEqual(expectedXMLBody, r.Body)
expectedBodyBytes, err := xml.Marshal(expectedXMLBody)
if err != nil {
assert.Fail(t, err.Error())
t.Error("expected body could not marshaled to xml")
}

if isEqual {
return true
}

failTest(t, "XML Bodies are not equal!", func() {
printXMLDiff(expectedXMLBody, r.Body)
})

return false
return assert.Equal(t, string(expectedBodyBytes), string(r.Body))
}

func (r RequestRecorder) AssertParamEqual(t *testing.T, paramName, paramValue string) bool {
if assert.ObjectsAreEqual(r.Params[paramName], paramValue) {
return true
}

failTest(t, fmt.Sprintf("Param name '%s' is not equal to '%s'", paramName, paramValue), func() {
color.Red("Actual:\t %s", r.Params[paramName])
color.Yellow("Expected: %s", paramValue)
})

return false
return assert.Equal(t, paramValue, r.Params[paramName])
}

func (r RequestRecorder) AssertQueryParamEqual(t *testing.T, queryParamName string, queryParamValues []string) bool {
if assert.ObjectsAreEqual(r.QueryParams[queryParamName], queryParamValues) {
return true
}

failTest(t, fmt.Sprintf("QueryParam name '%s' is not equal to %v", queryParamName, queryParamValues), func() {
color.Red("Actual:\t %s", r.QueryParams[queryParamName])
color.Yellow("Expected: %s", queryParamValues)
})

return false
return assert.Equal(t, queryParamValues, r.QueryParams[queryParamName])
}

func (r RequestRecorder) AssertFormParamEqual(t *testing.T, formParamName string, formValues []string) bool {
if assert.ObjectsAreEqual(r.FormParams[formParamName], formValues) {
return true
}

failTest(t, fmt.Sprintf("FormParam name '%s' is not equal to %v", formParamName, formValues), func() {
color.Red("Actual:\t %s", r.FormParams[formParamName])
color.Yellow("Expected: %s", formValues)
})

return false
return assert.Equal(t, formValues, r.FormParams[formParamName])
}

func (r RequestRecorder) AssertHeaderContains(t *testing.T, expectedHeader http.Header) bool {
if isHeaderContains(expectedHeader, r.Header) {
return true
}

failTest(t, "HTTP Headers are not equal", func() {
printJSONDiff(expectedHeader, r.Header)
})

return false
return assert.True(t, isHeaderContains(expectedHeader, r.Header))
}

func (r RequestRecorder) AssertNoRequest(t *testing.T) bool {
if !r.isRequestReceived {
return true
}

failTest(t, "No requests were expected, but a request was received!")

return false
return assert.False(t, r.isRequestReceived)
}

func isHeaderContains(expectedHeader, actualHeader http.Header) bool {
assertionResult := true
for key, value := range expectedHeader {
actualValue, contains := actualHeader[key]
if !contains {
return false
}

if !assert.ObjectsAreEqualValues(value, actualValue) {
return false
}
headerValue := actualHeader.Values(key)
assertionResult = assertionResult && assert.ObjectsAreEqualValues(headerValue, value)
}

return true
return assertionResult
}

func isJSONEqual(expectedBody interface{}, actualBody Body) (bool, error) {
expectedRecorderBody, err := jsonObjectToBody(expectedBody)
if err != nil {
return false, err
}

return assert.ObjectsAreEqualValues(expectedRecorderBody, actualBody), nil
expectedBytes, err := json.Marshal(expectedBody)
return assert.ObjectsAreEqualValues(expectedBytes, actualBody), err
}

func isXMLEqual(expectedBody interface{}, actualBody Body) (bool, error) {
expectedRecorderBody, err := xmlObjectToBody(expectedBody)
if err != nil {
return false, err
}

return assert.ObjectsAreEqualValues(expectedRecorderBody, actualBody), nil
}

func xmlObjectToBody(xmlObject interface{}) (Body, error) {
bodyXML, err := xml.Marshal(xmlObject)
if err != nil {
return nil, err
}

mv, err := mxj.NewMapXml(bodyXML)
if err != nil {
return nil, err
}

return mv.Old(), nil
}

func jsonObjectToBody(jsonObject interface{}) (Body, error) {
jsonBody, err := json.Marshal(jsonObject)
if err != nil {
return nil, err
}

body := Body{}
if err := json.Unmarshal(jsonBody, &body); err != nil {
return nil, err
}

return body, err
}

func failTest(t *testing.T, message string, callback ...func()) {
color.Red(message)

if len(callback) > 0 {
callback[0]()
}

t.Fail()
}

func printJSONDiff(expected, actual interface{}) {
expectedJSON, _ := json.Marshal(expected)
actualJSON, _ := json.Marshal(actual)

differ := diff.New()
diff, _ := differ.Compare(expectedJSON, actualJSON)

var asciiFormatMap map[string]interface{}
json.Unmarshal(expectedJSON, &asciiFormatMap)

formatter := formatter.NewAsciiFormatter(asciiFormatMap, formatter.AsciiFormatterConfig{
Coloring: true,
})

diffString, _ := formatter.Format(diff)

color.Yellow("Difference:")
fmt.Println(diffString)
}

func printXMLDiff(expected interface{}, actualBody Body) {
expectedBody, _ := xmlObjectToBody(expected)
printJSONDiff(expectedBody, actualBody)
expectedBytes, err := xml.Marshal(expectedBody)
return assert.ObjectsAreEqualValues(expectedBytes, actualBody), err
}
22 changes: 22 additions & 0 deletions assert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ import (

var dummyRequest = httptest.NewRequest(http.MethodGet, "http://streetbyters.com", http.NoBody)

func TestAssertJSONBodyEqual_JSONArray(t *testing.T) {
type Post struct {
Title string `json:"title"`
}

expectedPayload := []Post{{Title: "post1"}, {Title: "post2"}}
request := newJSONRequest(http.MethodPost, "", expectedPayload)

ctx := echo.New().NewContext(request, nil)

requestRecorder := NewRequestRecorder()
requestRecorder.saveContext(ctx)

tester := &testing.T{}

assert.True(t, requestRecorder.AssertJSONBodyEqual(tester, expectedPayload))
assert.False(t, tester.Failed())

assert.False(t, requestRecorder.AssertJSONBodyEqual(tester, []Post{{Title: "post2"}, {Title: "post1"}}))
assert.True(t, tester.Failed())
}

func TestAssertJSONBodyEqual(t *testing.T) {
type User struct {
Name string `json:"name"`
Expand Down
34 changes: 11 additions & 23 deletions requestrecorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"net/http"
"net/url"

"github.com/clbanning/mxj"
"github.com/labstack/echo"
)

Expand All @@ -36,13 +35,13 @@ type RequestRecorder struct {
isRequestReceived bool
}

type Body map[string]interface{}
type Body []byte

func NewRequestRecorder() *RequestRecorder {
requestRecorder := &RequestRecorder{}
requestRecorder.Body = make(Body)
requestRecorder.Params = make(map[string]string)
return requestRecorder
return &RequestRecorder{
Body: nil,
Params: make(map[string]string),
}
}

func (r *RequestRecorder) saveContext(ctx echo.Context) error {
Expand All @@ -51,24 +50,19 @@ func (r *RequestRecorder) saveContext(ctx echo.Context) error {
return nil
}

defaultBinder := new(echo.DefaultBinder)

if err := defaultBinder.Bind(&r.Body, ctx); err != nil {
data, err := ioutil.ReadAll(ctx.Request().Body)
if err != nil {
return err
}

r.setData(data)
bodyBytes, err := ioutil.ReadAll(ctx.Request().Body)
if err != nil {
return err
}

r.setData(bodyBytes)
r.Body = bodyBytes
r.setParams(ctx.ParamNames(), ctx.ParamValues())
r.setQueryParams(ctx.QueryParams())
r.setFormParams(ctx.Request().Form)
r.setHeader(ctx.Request().Header)

return nil

}

func (r *RequestRecorder) setQueryParams(queryParams url.Values) {
Expand Down Expand Up @@ -98,13 +92,7 @@ func (r *RequestRecorder) bindXML(from io.ReadCloser) error {
if err != nil {
return err
}

mv, err := mxj.NewMapXml(body)
if err != nil {
return err
}

r.Body = mv.Old()
r.Body = body

return nil
}

0 comments on commit 232faca

Please sign in to comment.