github.com/cosmos/cosmos-sdk@v0.50.10/codec/amino_codec_test.go (about) 1 package codec_test 2 3 import ( 4 "bytes" 5 "errors" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/cosmos/cosmos-sdk/codec" 11 "github.com/cosmos/cosmos-sdk/codec/types" 12 "github.com/cosmos/cosmos-sdk/testutil/testdata" 13 ) 14 15 func createTestCodec() *codec.LegacyAmino { 16 cdc := codec.NewLegacyAmino() 17 cdc.RegisterInterface((*testdata.Animal)(nil), nil) 18 // NOTE: since we unmarshal interface using pointers, we need to register a pointer 19 // types here. 20 cdc.RegisterConcrete(&testdata.Dog{}, "testdata/Dog", nil) 21 cdc.RegisterConcrete(&testdata.Cat{}, "testdata/Cat", nil) 22 23 return cdc 24 } 25 26 func TestAminoMarsharlInterface(t *testing.T) { 27 cdc := codec.NewAminoCodec(createTestCodec()) 28 m := interfaceMarshaler{cdc.MarshalInterface, cdc.UnmarshalInterface} 29 testInterfaceMarshaling(require.New(t), m, true) 30 31 m = interfaceMarshaler{cdc.MarshalInterfaceJSON, cdc.UnmarshalInterfaceJSON} 32 testInterfaceMarshaling(require.New(t), m, false) 33 } 34 35 func TestAminoCodec(t *testing.T) { 36 testMarshaling(t, codec.NewAminoCodec(createTestCodec())) 37 } 38 39 func TestAminoCodecMarshalJSONIndent(t *testing.T) { 40 any, err := types.NewAnyWithValue(&testdata.Dog{Name: "rufus"}) 41 require.NoError(t, err) 42 43 testCases := []struct { 44 name string 45 input interface{} 46 marshalErr bool 47 wantJSON string 48 }{ 49 { 50 name: "valid encoding and decoding", 51 input: &testdata.Dog{Name: "rufus"}, 52 wantJSON: `{ 53 "type": "testdata/Dog", 54 "value": { 55 "name": "rufus" 56 } 57 }`, 58 }, 59 { 60 name: "any marshaling", 61 input: &testdata.HasAnimal{Animal: any}, 62 wantJSON: `{ 63 "animal": { 64 "type": "testdata/Dog", 65 "value": { 66 "name": "rufus" 67 } 68 } 69 }`, 70 }, 71 } 72 73 for _, tc := range testCases { 74 tc := tc 75 76 t.Run(tc.name, func(t *testing.T) { 77 cdc := codec.NewAminoCodec(createTestCodec()) 78 bz, err := cdc.MarshalJSONIndent(tc.input, "", " ") 79 80 if tc.marshalErr { 81 require.Error(t, err) 82 require.Panics(t, func() { codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) }) 83 return 84 } 85 86 // Otherwise these are expected to pass. 87 require.NoError(t, err) 88 require.Equal(t, bz, []byte(tc.wantJSON)) 89 90 var bz2 []byte 91 require.NotPanics(t, func() { bz2 = codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) }) 92 require.Equal(t, bz2, []byte(tc.wantJSON)) 93 }) 94 } 95 } 96 97 func TestAminoCodecPrintTypes(t *testing.T) { 98 cdc := codec.NewAminoCodec(createTestCodec()) 99 buf := new(bytes.Buffer) 100 require.NoError(t, cdc.PrintTypes(buf)) 101 lines := bytes.Split(buf.Bytes(), []byte("\n")) 102 require.True(t, len(lines) > 1) 103 wantHeader := "| Type | Name | Prefix | Length | Notes |" 104 require.Equal(t, lines[0], []byte(wantHeader)) 105 106 // Expecting the types to be listed in the order that they were registered. 107 require.True(t, bytes.HasPrefix(lines[2], []byte("| Dog | testdata/Dog |"))) 108 require.True(t, bytes.HasPrefix(lines[3], []byte("| Cat | testdata/Cat |"))) 109 } 110 111 func TestAminoCodecUnpackAnyFails(t *testing.T) { 112 cdc := codec.NewAminoCodec(createTestCodec()) 113 err := cdc.UnpackAny(new(types.Any), &testdata.Cat{}) 114 require.Error(t, err) 115 require.Equal(t, err, errors.New("AminoCodec can't handle unpack protobuf Any's")) 116 }