@@ -4,21 +4,20 @@ import (
4
4
"bytes"
5
5
"encoding/json"
6
6
"fmt"
7
- "io"
8
7
"io/ioutil"
9
8
"net/http"
10
9
"reflect"
11
10
)
12
11
13
- func unmarshal (buf []byte ) (map [ string ] interface {}, error ) {
14
- data := make ( map [ string ] interface {})
12
+ func unmarshal (buf []byte ) (interface {}, error ) {
13
+ var data interface {}
15
14
if err := json .Unmarshal (buf , & data ); err != nil {
16
15
return data , fmt .Errorf ("failed to Unmarshal: %s" , err )
17
16
}
18
17
return data , nil
19
18
}
20
19
21
- func unmarshalBody (res * http.Response ) (map [ string ] interface {}, error ) {
20
+ func unmarshalBody (res * http.Response ) (interface {}, error ) {
22
21
body , err := ioutil .ReadAll (res .Body )
23
22
if err != nil {
24
23
return nil , err
@@ -29,7 +28,7 @@ func unmarshalBody(res *http.Response) (map[string]interface{}, error) {
29
28
return unmarshal (body )
30
29
}
31
30
32
- func marshal (data map [ string ] interface {}) ([]byte , error ) {
31
+ func marshal (data interface {}) ([]byte , error ) {
33
32
return json .Marshal (data )
34
33
}
35
34
@@ -44,53 +43,48 @@ func readBodyJSON(res *http.Response) ([]byte, error) {
44
43
return body , err
45
44
}
46
45
47
- func compare (body map [ string ] interface {}, data interface {}) error {
46
+ func compare (body interface {}, data interface {}) error {
48
47
var err error
49
- var match map [string ]interface {}
50
-
51
- // Infer and cast string input
52
- if jsonStr , ok := data .(string ); ok {
53
- data = []byte (jsonStr )
48
+ var matchBytes []byte
49
+
50
+ // taking pointer to json.RawMessage due to regression in go 1.7 (https://github.com/golang/go/issues/14493)
51
+ var matchData interface {}
52
+ switch data := data .(type ) {
53
+ case json.Marshaler :
54
+ matchData = data
55
+ case string :
56
+ v := json .RawMessage ([]byte (data ))
57
+ matchData = & v
58
+ case []byte :
59
+ v := json .RawMessage (data )
60
+ matchData = & v
61
+ default :
62
+ matchData = data
54
63
}
64
+ matchBytes , err = marshal (matchData )
55
65
56
- // Infer and cast string input
57
- if reader , ok := data .(io.Reader ); ok {
58
- data , err = ioutil .ReadAll (reader )
59
- if err != nil {
60
- return err
61
- }
62
- }
63
-
64
- // Infer and cast input as map
65
- if fields , ok := data .(map [string ]interface {}); ok {
66
- data , err = marshal (fields )
67
- if err != nil {
68
- return err
69
- }
66
+ if err != nil {
67
+ return err
70
68
}
71
69
72
- // Infer and cast bytes input
73
- buf , ok := data .([]byte )
74
- if ok {
75
- match , err = unmarshal (buf )
76
- if err != nil {
77
- return err
78
- }
70
+ // Assert via string
71
+ bodyBytes , err := marshal (body )
72
+ if err != nil {
73
+ return err
79
74
}
80
75
81
- // Assert via string
82
- bodyBuf , err := marshal (body )
76
+ bodyValue , err := unmarshal (bodyBytes )
83
77
if err != nil {
84
78
return err
85
79
}
86
- matchBuf , err := marshal ( match )
80
+ matchValue , err := unmarshal ( matchBytes )
87
81
if err != nil {
88
82
return err
89
83
}
90
84
91
- // Compare by byte sequences
92
- if ! reflect .DeepEqual (bodyBuf , matchBuf ) {
93
- return fmt .Errorf ("failed due to JSON mismatch:\n \t have: %#v\n \t want: %#v" , string (bodyBuf ), string (matchBuf ))
85
+ // Compare values so order of keys in maps does not influence the result
86
+ if ! reflect .DeepEqual (bodyValue , matchValue ) {
87
+ return fmt .Errorf ("failed due to JSON mismatch:\n \t have: %#v\n \t want: %#v" , string (bodyBytes ), string (matchBytes ))
94
88
}
95
89
96
90
return nil
0 commit comments