1 package matchers
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7
8 "github.com/onsi/gomega/format"
9 )
10
11 type MatchJSONMatcher struct {
12 JSONToMatch interface{}
13 firstFailurePath []interface{}
14 }
15
16 func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err error) {
17 actualString, expectedString, err := matcher.prettyPrint(actual)
18 if err != nil {
19 return false, err
20 }
21
22 var aval interface{}
23 var eval interface{}
24
25
26 json.Unmarshal([]byte(actualString), &aval)
27 json.Unmarshal([]byte(expectedString), &eval)
28 var equal bool
29 equal, matcher.firstFailurePath = deepEqual(aval, eval)
30 return equal, nil
31 }
32
33 func (matcher *MatchJSONMatcher) FailureMessage(actual interface{}) (message string) {
34 actualString, expectedString, _ := matcher.prettyPrint(actual)
35 return formattedMessage(format.Message(actualString, "to match JSON of", expectedString), matcher.firstFailurePath)
36 }
37
38 func (matcher *MatchJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) {
39 actualString, expectedString, _ := matcher.prettyPrint(actual)
40 return formattedMessage(format.Message(actualString, "not to match JSON of", expectedString), matcher.firstFailurePath)
41 }
42
43 func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
44 actualString, ok := toString(actual)
45 if !ok {
46 return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte. Got actual:\n%s", format.Object(actual, 1))
47 }
48 expectedString, ok := toString(matcher.JSONToMatch)
49 if !ok {
50 return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte. Got expected:\n%s", format.Object(matcher.JSONToMatch, 1))
51 }
52
53 abuf := new(bytes.Buffer)
54 ebuf := new(bytes.Buffer)
55
56 if err := json.Indent(abuf, []byte(actualString), "", " "); err != nil {
57 return "", "", fmt.Errorf("Actual '%s' should be valid JSON, but it is not.\nUnderlying error:%s", actualString, err)
58 }
59
60 if err := json.Indent(ebuf, []byte(expectedString), "", " "); err != nil {
61 return "", "", fmt.Errorf("Expected '%s' should be valid JSON, but it is not.\nUnderlying error:%s", expectedString, err)
62 }
63
64 return abuf.String(), ebuf.String(), nil
65 }
66
View as plain text