github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/amino/codec_test.go (about) 1 package amino_test 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 12 amino "github.com/gnolang/gno/tm2/pkg/amino" 13 "github.com/gnolang/gno/tm2/pkg/amino/tests" 14 ) 15 16 type SimpleStruct struct { 17 String string 18 Bytes []byte 19 Time time.Time 20 } 21 22 func newSimpleStruct() SimpleStruct { 23 s := SimpleStruct{ 24 String: "hello", 25 Bytes: []byte("goodbye"), 26 Time: time.Now().UTC().Truncate(time.Millisecond), // strip monotonic and timezone. 27 } 28 return s 29 } 30 31 func TestMarshalUnmarshalPointer0(t *testing.T) { 32 t.Parallel() 33 34 s := newSimpleStruct() 35 cdc := amino.NewCodec() 36 b, err := cdc.MarshalSized(s) // no indirection 37 assert.NoError(t, err) 38 39 var s2 SimpleStruct 40 err = cdc.UnmarshalSized(b, &s2) // no indirection 41 assert.NoError(t, err) 42 assert.Equal(t, s, s2) 43 } 44 45 func TestMarshalUnmarshalPointer1(t *testing.T) { 46 t.Parallel() 47 48 s := newSimpleStruct() 49 cdc := amino.NewCodec() 50 b, err := cdc.MarshalSized(&s) // extra indirection 51 assert.NoError(t, err) 52 53 var s2 SimpleStruct 54 err = cdc.UnmarshalSized(b, &s2) // no indirection 55 assert.NoError(t, err) 56 assert.Equal(t, s, s2) 57 } 58 59 func TestMarshalUnmarshalPointer2(t *testing.T) { 60 t.Parallel() 61 62 s := newSimpleStruct() 63 ptr := &s 64 cdc := amino.NewCodec() 65 assert.Panics(t, func() { 66 cdc.MarshalSized(&ptr) // double extra indirection panics. 67 cdc.RegisterPackage(tests.Package) 68 }) 69 } 70 71 func TestMarshalUnmarshalPointer3(t *testing.T) { 72 t.Parallel() 73 74 s := newSimpleStruct() 75 cdc := amino.NewCodec() 76 b, err := cdc.MarshalSized(s) // no indirection 77 assert.NoError(t, err) 78 79 var s2 *SimpleStruct 80 err = cdc.UnmarshalSized(b, &s2) // extra indirection 81 assert.NoError(t, err) 82 assert.Equal(t, s, *s2) 83 } 84 85 func TestDecodeVarint8(t *testing.T) { 86 t.Parallel() 87 88 // DecodeVarint8 uses binary.Varint so we need to make 89 // sure that all the values out of the range of [-128, 127] 90 // return an error. 91 tests := []struct { 92 in int64 93 wantErr string 94 want int8 95 }{ 96 {in: 0x7F, want: 0x7F}, 97 {in: -0x7F, want: -0x7F}, 98 {in: -0x80, want: -0x80}, 99 {in: 0x10, want: 0x10}, 100 101 {in: -0xFF, wantErr: "decoding int8"}, 102 {in: 0xFF, wantErr: "decoding int8"}, 103 {in: 0x100, wantErr: "decoding int8"}, 104 {in: -0x100, wantErr: "decoding int8"}, 105 } 106 107 buf := make([]byte, 10) 108 for i, tt := range tests { 109 n := binary.PutVarint(buf, tt.in) 110 gotI8, gotN, err := amino.DecodeVarint8(buf[:n]) 111 if tt.wantErr != "" { 112 if err == nil { 113 t.Errorf("#%d expected error=%q", i, tt.wantErr) 114 } else if !strings.Contains(err.Error(), tt.wantErr) { 115 t.Errorf("#%d\ngotErr=%q\nwantSegment=%q", i, err, tt.wantErr) 116 } 117 continue 118 } 119 120 if err != nil { 121 t.Errorf("#%d unexpected error: %v", i, err) 122 continue 123 } 124 125 if wantI8 := tt.want; gotI8 != wantI8 { 126 t.Errorf("#%d gotI8=%d wantI8=%d", i, gotI8, wantI8) 127 } 128 if wantN := n; gotN != wantN { 129 t.Errorf("#%d gotN=%d wantN=%d", i, gotN, wantN) 130 } 131 } 132 } 133 134 func TestDecodeVarint16(t *testing.T) { 135 t.Parallel() 136 137 // DecodeVarint16 uses binary.Varint so we need to make 138 // sure that all the values out of the range of [-32768, 32767] 139 // return an error. 140 tests := []struct { 141 in int64 142 wantErr string 143 want int16 144 }{ 145 {in: -0x8000, want: -0x8000}, 146 {in: -0x7FFF, want: -0x7FFF}, 147 {in: -0x7F, want: -0x7F}, 148 {in: -0x80, want: -0x80}, 149 {in: 0x10, want: 0x10}, 150 151 {in: -0xFFFF, wantErr: "decoding int16"}, 152 {in: 0xFFFF, wantErr: "decoding int16"}, 153 {in: 0x10000, wantErr: "decoding int16"}, 154 {in: -0x10000, wantErr: "decoding int16"}, 155 } 156 157 buf := make([]byte, 10) 158 for i, tt := range tests { 159 n := binary.PutVarint(buf, tt.in) 160 gotI16, gotN, err := amino.DecodeVarint16(buf[:n]) 161 if tt.wantErr != "" { 162 if err == nil { 163 t.Errorf("#%d in=(%X) expected error=%q", i, tt.in, tt.wantErr) 164 } else if !strings.Contains(err.Error(), tt.wantErr) { 165 t.Errorf("#%d\ngotErr=%q\nwantSegment=%q", i, err, tt.wantErr) 166 } 167 continue 168 } 169 170 if err != nil { 171 t.Errorf("#%d unexpected error: %v", i, err) 172 continue 173 } 174 175 if wantI16 := tt.want; gotI16 != wantI16 { 176 t.Errorf("#%d gotI16=%d wantI16=%d", i, gotI16, wantI16) 177 } 178 if wantN := n; gotN != wantN { 179 t.Errorf("#%d gotN=%d wantN=%d", i, gotN, wantN) 180 } 181 } 182 } 183 184 func TestEncodeDecodeString(t *testing.T) { 185 t.Parallel() 186 187 s := "🔌🎉⛵︎♠️⎍" 188 bs := []byte(s) 189 di := len(bs) * 3 / 4 190 b1 := bs[:di] 191 b2 := bs[di:] 192 193 // Encoding phase 194 buf1 := new(bytes.Buffer) 195 if err := amino.EncodeByteSlice(buf1, b1); err != nil { 196 t.Fatalf("EncodeByteSlice(b1) = %v", err) 197 } 198 buf2 := new(bytes.Buffer) 199 if err := amino.EncodeByteSlice(buf2, b2); err != nil { 200 t.Fatalf("EncodeByteSlice(b2) = %v", err) 201 } 202 203 // Decoding phase 204 e1 := buf1.Bytes() 205 dec1, n, err := amino.DecodeByteSlice(e1) 206 if err != nil { 207 t.Errorf("DecodeByteSlice(e1) = %v", err) 208 } 209 if g, w := n, len(e1); g != w { 210 t.Errorf("e1: length:: got = %d want = %d", g, w) 211 } 212 e2 := buf2.Bytes() 213 dec2, n, err := amino.DecodeByteSlice(e2) 214 if err != nil { 215 t.Errorf("DecodeByteSlice(e2) = %v", err) 216 } 217 if g, w := n, len(e2); g != w { 218 t.Errorf("e2: length:: got = %d want = %d", g, w) 219 } 220 joined := bytes.Join([][]byte{dec1, dec2}, []byte("")) 221 if !bytes.Equal(joined, bs) { 222 t.Errorf("got joined=(% X) want=(% X)", joined, bs) 223 } 224 js := string(joined) 225 if js != s { 226 t.Errorf("got string=%q want=%q", js, s) 227 } 228 } 229 230 func TestCodecSeal(t *testing.T) { 231 t.Parallel() 232 233 cdc := amino.NewCodec() 234 cdc.Seal() 235 236 assert.Panics(t, func() { cdc.RegisterPackage(tests.Package) }) 237 } 238 239 // XXX Test registering duplicate names or concrete types not in a package.