github.com/pure-x-eth/consensus_tm@v0.0.0-20230502163723-e3c2ff987250/libs/json/encoder_test.go (about) 1 package json_test 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 "github.com/pure-x-eth/consensus_tm/libs/json" 11 ) 12 13 func TestMarshal(t *testing.T) { 14 s := "string" 15 sPtr := &s 16 i64 := int64(64) 17 ti := time.Date(2020, 6, 2, 18, 5, 13, 4346374, time.FixedZone("UTC+2", 2*60*60)) 18 car := &Car{Wheels: 4} 19 boat := Boat{Sail: true} 20 21 testcases := map[string]struct { 22 value interface{} 23 output string 24 }{ 25 "nil": {nil, `null`}, 26 "string": {"foo", `"foo"`}, 27 "float32": {float32(3.14), `3.14`}, 28 "float32 neg": {float32(-3.14), `-3.14`}, 29 "float64": {float64(3.14), `3.14`}, 30 "float64 neg": {float64(-3.14), `-3.14`}, 31 "int32": {int32(32), `32`}, 32 "int64": {int64(64), `"64"`}, 33 "int64 neg": {int64(-64), `"-64"`}, 34 "int64 ptr": {&i64, `"64"`}, 35 "uint64": {uint64(64), `"64"`}, 36 "time": {ti, `"2020-06-02T16:05:13.004346374Z"`}, 37 "time empty": {time.Time{}, `"0001-01-01T00:00:00Z"`}, 38 "time ptr": {&ti, `"2020-06-02T16:05:13.004346374Z"`}, 39 "customptr": {CustomPtr{Value: "x"}, `{"Value":"x"}`}, // same as encoding/json 40 "customptr ptr": {&CustomPtr{Value: "x"}, `"custom"`}, 41 "customvalue": {CustomValue{Value: "x"}, `"custom"`}, 42 "customvalue ptr": {&CustomValue{Value: "x"}, `"custom"`}, 43 "slice nil": {[]int(nil), `null`}, 44 "slice empty": {[]int{}, `[]`}, 45 "slice bytes": {[]byte{1, 2, 3}, `"AQID"`}, 46 "slice int64": {[]int64{1, 2, 3}, `["1","2","3"]`}, 47 "slice int64 ptr": {[]*int64{&i64, nil}, `["64",null]`}, 48 "array bytes": {[3]byte{1, 2, 3}, `"AQID"`}, 49 "array int64": {[3]int64{1, 2, 3}, `["1","2","3"]`}, 50 "map nil": {map[string]int64(nil), `{}`}, // retain Amino compatibility 51 "map empty": {map[string]int64{}, `{}`}, 52 "map int64": {map[string]int64{"a": 1, "b": 2, "c": 3}, `{"a":"1","b":"2","c":"3"}`}, 53 "car": {car, `{"type":"vehicle/car","value":{"Wheels":4}}`}, 54 "car value": {*car, `{"type":"vehicle/car","value":{"Wheels":4}}`}, 55 "car iface": {Vehicle(car), `{"type":"vehicle/car","value":{"Wheels":4}}`}, 56 "car nil": {(*Car)(nil), `null`}, 57 "boat": {boat, `{"type":"vehicle/boat","value":{"Sail":true}}`}, 58 "boat ptr": {&boat, `{"type":"vehicle/boat","value":{"Sail":true}}`}, 59 "boat iface": {Vehicle(boat), `{"type":"vehicle/boat","value":{"Sail":true}}`}, 60 "key public": {PublicKey{1, 2, 3, 4, 5, 6, 7, 8}, `{"type":"key/public","value":"AQIDBAUGBwg="}`}, 61 "tags": { 62 Tags{JSONName: "name", OmitEmpty: "foo", Hidden: "bar", Tags: &Tags{JSONName: "child"}}, 63 `{"name":"name","OmitEmpty":"foo","tags":{"name":"child"}}`, 64 }, 65 "tags empty": {Tags{}, `{"name":""}`}, 66 // The encoding of the Car and Boat fields do not have type wrappers, even though they get 67 // type wrappers when encoded directly (see "car" and "boat" tests). This is to retain the 68 // same behavior as Amino. If the field was a Vehicle interface instead, it would get 69 // type wrappers, as seen in the Vehicles field. 70 "struct": { 71 Struct{ 72 Bool: true, Float64: 3.14, Int32: 32, Int64: 64, Int64Ptr: &i64, 73 String: "foo", StringPtrPtr: &sPtr, Bytes: []byte{1, 2, 3}, 74 Time: ti, Car: car, Boat: boat, Vehicles: []Vehicle{car, boat}, 75 Child: &Struct{Bool: false, String: "child"}, private: "private", 76 }, 77 `{ 78 "Bool":true, "Float64":3.14, "Int32":32, "Int64":"64", "Int64Ptr":"64", 79 "String":"foo", "StringPtrPtr": "string", "Bytes":"AQID", 80 "Time":"2020-06-02T16:05:13.004346374Z", 81 "Car":{"Wheels":4}, 82 "Boat":{"Sail":true}, 83 "Vehicles":[ 84 {"type":"vehicle/car","value":{"Wheels":4}}, 85 {"type":"vehicle/boat","value":{"Sail":true}} 86 ], 87 "Child":{ 88 "Bool":false, "Float64":0, "Int32":0, "Int64":"0", "Int64Ptr":null, 89 "String":"child", "StringPtrPtr":null, "Bytes":null, 90 "Time":"0001-01-01T00:00:00Z", 91 "Car":null, "Boat":{"Sail":false}, "Vehicles":null, "Child":null 92 } 93 }`, 94 }, 95 } 96 for name, tc := range testcases { 97 tc := tc 98 t.Run(name, func(t *testing.T) { 99 bz, err := json.Marshal(tc.value) 100 require.NoError(t, err) 101 assert.JSONEq(t, tc.output, string(bz)) 102 }) 103 } 104 }