-
Notifications
You must be signed in to change notification settings - Fork 60
/
json_test.go
132 lines (116 loc) · 3.37 KB
/
json_test.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
package cbor_test
import (
"encoding/json"
"reflect"
"testing"
"github.com/fxamacker/cbor/v2"
)
// TestStdlibJSONCompatibility tests compatibility as a drop-in replacement for the standard library
// encoding/json package on a round trip encoding from Go object to interface{}.
func TestStdlibJSONCompatibility(t *testing.T) {
// TODO: With better coverage and compatibility, it could be useful to expose these option
// configurations to users.
enc, err := cbor.EncOptions{
ByteSliceLaterFormat: cbor.ByteSliceLaterFormatBase64,
String: cbor.StringToByteString,
ByteArray: cbor.ByteArrayToArray,
}.EncMode()
if err != nil {
t.Fatal(err)
}
dec, err := cbor.DecOptions{
DefaultByteStringType: reflect.TypeOf(""),
ByteStringToString: cbor.ByteStringToStringAllowedWithExpectedLaterEncoding,
ByteStringExpectedFormat: cbor.ByteStringExpectedBase64,
}.DecMode()
if err != nil {
t.Fatal(err)
}
for _, tc := range []struct {
name string
original interface{}
ifaceEqual bool // require equal intermediate interface{} values from both protocols
}{
{
name: "byte slice to base64-encoded string",
original: []byte("hello world"),
ifaceEqual: true,
},
{
name: "byte array to array of integers",
original: [11]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'},
ifaceEqual: false, // encoding/json decodes the array elements to float64
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Logf("original: %#v", tc.original)
j1, err := json.Marshal(tc.original)
if err != nil {
t.Fatal(err)
}
t.Logf("original to json: %s", string(j1))
c1, err := enc.Marshal(tc.original)
if err != nil {
t.Fatal(err)
}
diag1, err := cbor.Diagnose(c1)
if err != nil {
t.Fatal(err)
}
t.Logf("original to cbor: %s", diag1)
var jintf interface{}
err = json.Unmarshal(j1, &jintf)
if err != nil {
t.Fatal(err)
}
t.Logf("json to interface{} (%T): %#v", jintf, jintf)
var cintf interface{}
err = dec.Unmarshal(c1, &cintf)
if err != nil {
t.Fatal(err)
}
t.Logf("cbor to interface{} (%T): %#v", cintf, cintf)
j2, err := json.Marshal(jintf)
if err != nil {
t.Fatal(err)
}
t.Logf("interface{} to json: %s", string(j2))
c2, err := enc.Marshal(cintf)
if err != nil {
t.Fatal(err)
}
diag2, err := cbor.Diagnose(c2)
if err != nil {
t.Fatal(err)
}
t.Logf("interface{} to cbor: %s", diag2)
if !reflect.DeepEqual(jintf, cintf) {
if tc.ifaceEqual {
t.Errorf("native-to-interface{} via cbor differed from native-to-interface{} via json")
} else {
t.Logf("native-to-interface{} via cbor differed from native-to-interface{} via json")
}
}
jfinalValue := reflect.New(reflect.TypeOf(tc.original))
err = json.Unmarshal(j2, jfinalValue.Interface())
if err != nil {
t.Fatal(err)
}
jfinal := jfinalValue.Elem().Interface()
t.Logf("json to native: %#v", jfinal)
if !reflect.DeepEqual(tc.original, jfinal) {
t.Error("diff in json roundtrip")
}
cfinalValue := reflect.New(reflect.TypeOf(tc.original))
err = dec.Unmarshal(c2, cfinalValue.Interface())
if err != nil {
t.Fatal(err)
}
cfinal := cfinalValue.Elem().Interface()
t.Logf("cbor to native: %#v", cfinal)
if !reflect.DeepEqual(tc.original, cfinal) {
t.Error("diff in cbor roundtrip")
}
})
}
}