-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.go
142 lines (116 loc) · 3.54 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Package test contains testing utils functions.
package test
import (
"bytes"
"encoding/json"
"reflect"
"testing"
"github.com/sergi/go-diff/diffmatchpatch"
)
// PrettyDiff print pretty diff of expected and actual using t.Errorf().
func PrettyDiff(t *testing.T, expected, actual string) {
t.Helper()
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(expected, actual, true)
t.Errorf("\n%s", dmp.DiffPrettyText(diffs))
}
// PrettyMarshal return prettified json representation of the argument.
// Return empty string, if argument can not be represented as json.
func PrettyMarshal(toMarshall interface{}) string {
marshalled, err := json.Marshal(toMarshall)
if err != nil {
return ""
}
var out bytes.Buffer
err = json.Indent(&out, marshalled, "", " ")
if err != nil {
return ""
}
return out.String()
}
func jsonPrettyPrint(in string) string {
var out bytes.Buffer
err := json.Indent(&out, []byte(in), "", "\t")
if err != nil {
return in
}
return out.String()
}
// MarshallingCases contains test cases for Marshalling Test functions.
type MarshallingCases []struct {
Model interface{}
// JSON which is compared to json.Marshal result.
// JSON can be in any valid format. Indents and white spaces are ignored.
JSON string
}
// Marshal run testCases on json.Marshal function.
func Marshal(t *testing.T, testCases MarshallingCases) {
for _, tc := range testCases {
prettyJSON := jsonPrettyPrint(tc.JSON)
result, err := json.MarshalIndent(tc.Model, "", "\t")
if err != nil {
t.Error(err.Error())
}
sres := string(result[:])
if sres != prettyJSON {
t.Errorf("json.Marshal(%T):", tc.Model)
PrettyDiff(t, prettyJSON, sres)
}
}
}
// Unmarshal run test cases on json.Unmarshal function.
func Unmarshal(t *testing.T, testCases MarshallingCases) {
for _, tc := range testCases {
objType := reflect.TypeOf(tc.Model).Elem()
res := reflect.New(objType).Interface()
bInput := []byte(tc.JSON)
err := json.Unmarshal(bInput, &res)
if err != nil {
t.Error(err.Error())
}
if !reflect.DeepEqual(res, tc.Model) {
t.Errorf("json.Unmarshal(%T, %T): \nexpected:\n%+v\nactual:\n%+v",
bInput, res, tc.Model, res)
}
}
}
// UnmarshalMarshalled first Marshal tc.Model, then Unmarshal result from previous operation.
func UnmarshalMarshalled(t *testing.T, testCases MarshallingCases) {
for _, tc := range testCases {
marshallingResult, err := json.Marshal(tc.Model)
if err != nil {
t.Error(err.Error())
}
objType := reflect.TypeOf(tc.Model).Elem()
res := reflect.New(objType).Interface()
err = json.Unmarshal(marshallingResult, &res)
if err != nil {
t.Error(err.Error())
}
if !reflect.DeepEqual(res, tc.Model) {
t.Errorf("json.Unmarshal(%T, %T) on json.Marshal(%T) result: \nexpected:\n%s\nactual:\n%s",
marshallingResult, res, tc.Model, tc.Model, res)
}
}
}
// MarshalUnmarshalled first Unmarshal tc.JSON, then Marshal result from previous operation.
func MarshalUnmarshalled(t *testing.T, testCases MarshallingCases) {
for _, tc := range testCases {
objType := reflect.TypeOf(tc.Model).Elem()
unmarshallingResult := reflect.New(objType).Interface()
bInput := []byte(tc.JSON)
err := json.Unmarshal(bInput, &unmarshallingResult)
if err != nil {
t.Error(err.Error())
}
res, err := json.MarshalIndent(unmarshallingResult, "", "\t")
if err != nil {
t.Error(err.Error())
}
sres := string(res[:])
if sres != jsonPrettyPrint(tc.JSON) {
t.Errorf("json.Marshal(%T) on json.Unmarshal(%T, %T):", unmarshallingResult, bInput, unmarshallingResult)
PrettyDiff(t, tc.JSON, sres)
}
}
}