This repository has been archived by the owner on Aug 1, 2024. It is now read-only.
forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
codec_common_test.go
137 lines (120 loc) · 3.73 KB
/
codec_common_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
133
134
135
136
137
package codec_test
import (
"testing"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
)
type interfaceMarshaler struct {
marshal func(i proto.Message) ([]byte, error)
unmarshal func(bz []byte, ptr interface{}) error
}
func testInterfaceMarshaling(require *require.Assertions, cdc interfaceMarshaler, isAminoBin bool) {
_, err := cdc.marshal(nil)
require.Error(err, "can't marshal a nil value")
dog := &testdata.Dog{Name: "rufus"}
var dogI testdata.Animal = dog
bz, err := cdc.marshal(dogI)
require.NoError(err)
var animal testdata.Animal
if isAminoBin {
require.PanicsWithValue("Unmarshal expects a pointer", func() {
_ = cdc.unmarshal(bz, animal)
})
} else {
err = cdc.unmarshal(bz, animal)
require.Error(err)
require.Contains(err.Error(), "expects a pointer")
}
require.NoError(cdc.unmarshal(bz, &animal))
require.Equal(dog, animal)
// Amino doesn't wrap into Any, so it doesn't need to register self type
if isAminoBin {
var dog2 testdata.Dog
require.NoError(cdc.unmarshal(bz, &dog2))
require.Equal(*dog, dog2)
}
var cat testdata.Cat
require.Error(cdc.unmarshal(bz, &cat))
}
type mustMarshaler struct {
marshal func(i proto.Message) ([]byte, error)
mustMarshal func(i proto.Message) []byte
unmarshal func(bz []byte, ptr proto.Message) error
mustUnmarshal func(bz []byte, ptr proto.Message)
}
type testCase struct {
name string
input proto.Message
recv proto.Message
marshalErr bool
unmarshalErr bool
}
func testMarshalingTestCase(require *require.Assertions, tc testCase, m mustMarshaler) {
bz, err := m.marshal(tc.input)
if tc.marshalErr {
require.Error(err)
require.Panics(func() { m.mustMarshal(tc.input) })
} else {
var bz2 []byte
require.NoError(err)
require.NotPanics(func() { bz2 = m.mustMarshal(tc.input) })
require.Equal(bz, bz2)
err := m.unmarshal(bz, tc.recv)
if tc.unmarshalErr {
require.Error(err)
require.Panics(func() { m.mustUnmarshal(bz, tc.recv) })
} else {
require.NoError(err)
require.NotPanics(func() { m.mustUnmarshal(bz, tc.recv) })
require.Equal(tc.input, tc.recv)
}
}
}
func testMarshaling(t *testing.T, cdc codec.Codec) {
any, err := types.NewAnyWithValue(&testdata.Dog{Name: "rufus"})
require.NoError(t, err)
testCases := []testCase{
{
"valid encoding and decoding",
&testdata.Dog{Name: "rufus"},
&testdata.Dog{},
false,
false,
}, {
"invalid decode type",
&testdata.Dog{Name: "rufus"},
&testdata.Cat{},
false,
true,
},
}
if _, ok := cdc.(*codec.AminoCodec); ok {
testCases = append(testCases, testCase{
"any marshaling",
&testdata.HasAnimal{Animal: any},
&testdata.HasAnimal{Animal: any},
false,
false,
})
}
for _, tc := range testCases {
tc := tc
m1 := mustMarshaler{cdc.Marshal, cdc.MustMarshal, cdc.Unmarshal, cdc.MustUnmarshal}
m2 := mustMarshaler{cdc.MarshalLengthPrefixed, cdc.MustMarshalLengthPrefixed, cdc.UnmarshalLengthPrefixed, cdc.MustUnmarshalLengthPrefixed}
m3 := mustMarshaler{
func(i proto.Message) ([]byte, error) { return cdc.MarshalJSON(i) },
func(i proto.Message) []byte { return cdc.MustMarshalJSON(i) },
func(bz []byte, ptr proto.Message) error { return cdc.UnmarshalJSON(bz, ptr) },
func(bz []byte, ptr proto.Message) { cdc.MustUnmarshalJSON(bz, ptr) },
}
t.Run(tc.name+"_BinaryBare",
func(t *testing.T) { testMarshalingTestCase(require.New(t), tc, m1) })
t.Run(tc.name+"_BinaryLengthPrefixed",
func(t *testing.T) { testMarshalingTestCase(require.New(t), tc, m2) })
t.Run(tc.name+"_JSON",
func(t *testing.T) { testMarshalingTestCase(require.New(t), tc, m3) })
}
}