github.com/Finschia/finschia-sdk@v0.48.1/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/Finschia/finschia-sdk/codec" 11 "github.com/Finschia/finschia-sdk/codec/types" 12 "github.com/Finschia/finschia-sdk/simapp" 13 "github.com/Finschia/finschia-sdk/testutil/testdata" 14 "github.com/Finschia/finschia-sdk/x/auth/client/cli" 15 "github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx" 16 ) 17 18 func createTestCodec() *codec.LegacyAmino { 19 cdc := codec.NewLegacyAmino() 20 cdc.RegisterInterface((*testdata.Animal)(nil), nil) 21 // NOTE: since we unmarshal interface using pointers, we need to register a pointer 22 // types here. 23 cdc.RegisterConcrete(&testdata.Dog{}, "testdata/Dog", nil) 24 cdc.RegisterConcrete(&testdata.Cat{}, "testdata/Cat", nil) 25 26 return cdc 27 } 28 29 func TestAminoMarsharlInterface(t *testing.T) { 30 cdc := codec.NewAminoCodec(createTestCodec()) 31 m := interfaceMarshaler{cdc.MarshalInterface, cdc.UnmarshalInterface} 32 testInterfaceMarshaling(require.New(t), m, true) 33 34 m = interfaceMarshaler{cdc.MarshalInterfaceJSON, cdc.UnmarshalInterfaceJSON} 35 testInterfaceMarshaling(require.New(t), m, false) 36 } 37 38 func TestAminoCodec(t *testing.T) { 39 testMarshaling(t, codec.NewAminoCodec(createTestCodec())) 40 } 41 42 func TestAminoCodecMarshalJSONIndent(t *testing.T) { 43 any, err := types.NewAnyWithValue(&testdata.Dog{Name: "rufus"}) 44 require.NoError(t, err) 45 46 testCases := []struct { 47 name string 48 input interface{} 49 marshalErr bool 50 wantJSON string 51 }{ 52 { 53 name: "valid encoding and decoding", 54 input: &testdata.Dog{Name: "rufus"}, 55 wantJSON: `{ 56 "type": "testdata/Dog", 57 "value": { 58 "name": "rufus" 59 } 60 }`, 61 }, 62 { 63 name: "any marshaling", 64 input: &testdata.HasAnimal{Animal: any}, 65 wantJSON: `{ 66 "animal": { 67 "type": "testdata/Dog", 68 "value": { 69 "name": "rufus" 70 } 71 } 72 }`, 73 }, 74 } 75 76 for _, tc := range testCases { 77 tc := tc 78 79 t.Run(tc.name, func(t *testing.T) { 80 cdc := codec.NewAminoCodec(createTestCodec()) 81 bz, err := cdc.MarshalJSONIndent(tc.input, "", " ") 82 83 if tc.marshalErr { 84 require.Error(t, err) 85 require.Panics(t, func() { codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) }) 86 return 87 } 88 89 // Otherwise these are expected to pass. 90 require.NoError(t, err) 91 require.Equal(t, bz, []byte(tc.wantJSON)) 92 93 var bz2 []byte 94 require.NotPanics(t, func() { bz2 = codec.MustMarshalJSONIndent(cdc.LegacyAmino, tc.input) }) 95 require.Equal(t, bz2, []byte(tc.wantJSON)) 96 }) 97 } 98 } 99 100 func TestAminoCodecPrintTypes(t *testing.T) { 101 cdc := codec.NewAminoCodec(createTestCodec()) 102 buf := new(bytes.Buffer) 103 require.NoError(t, cdc.PrintTypes(buf)) 104 lines := bytes.Split(buf.Bytes(), []byte("\n")) 105 require.True(t, len(lines) > 1) 106 wantHeader := "| Type | Name | Prefix | Length | Notes |" 107 require.Equal(t, lines[0], []byte(wantHeader)) 108 109 // Expecting the types to be listed in the order that they were registered. 110 require.True(t, bytes.HasPrefix(lines[2], []byte("| Dog | testdata/Dog |"))) 111 require.True(t, bytes.HasPrefix(lines[3], []byte("| Cat | testdata/Cat |"))) 112 } 113 114 func TestAminoCodecUnpackAnyFails(t *testing.T) { 115 cdc := codec.NewAminoCodec(createTestCodec()) 116 err := cdc.UnpackAny(new(types.Any), &testdata.Cat{}) 117 require.Error(t, err) 118 require.Equal(t, err, errors.New("AminoCodec can't handle unpack protobuf Any's")) 119 } 120 121 func TestAminoCodecFullDecodeAndEncode(t *testing.T) { 122 // This tx comes from https://github.com/cosmos/cosmos-sdk/issues/8117. 123 txSigned := `{"type":"cosmos-sdk/StdTx","value":{"msg":[{"type":"cosmos-sdk/MsgCreateValidator","value":{"description":{"moniker":"fulltest","identity":"satoshi","website":"example.com","details":"example inc"},"commission":{"rate":"0.500000000000000000","max_rate":"1.000000000000000000","max_change_rate":"0.200000000000000000"},"min_self_delegation":"1000000","delegator_address":"link14pt0q5cwf38zt08uu0n6yrstf3rndzr5057jys","validator_address":"linkvaloper14pt0q5cwf38zt08uu0n6yrstf3rndzr52q28gr","pubkey":{"type":"tendermint/PubKeyEd25519","value":"CYrOiM3HtS7uv1B1OAkknZnFYSRpQYSYII8AtMMtev0="},"value":{"denom":"umuon","amount":"700000000"}}}],"fee":{"amount":[{"denom":"umuon","amount":"6000"}],"gas":"160000"},"signatures":[{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"AwAOXeWgNf1FjMaayrSnrOOKz+Fivr6DiI/i0x0sZCHw"},"signature":"RcnfS/u2yl7uIShTrSUlDWvsXo2p2dYu6WJC8VDVHMBLEQZWc8bsINSCjOnlsIVkUNNe1q/WCA9n3Gy1+0zhYA=="}],"memo":"","timeout_height":"0"}}` 124 legacyCdc := simapp.MakeTestEncodingConfig().Amino 125 var tx legacytx.StdTx 126 err := legacyCdc.UnmarshalJSON([]byte(txSigned), &tx) 127 require.NoError(t, err) 128 129 // Marshalling/unmarshalling the tx should work. 130 marshaledTx, err := legacyCdc.MarshalJSON(tx) 131 require.NoError(t, err) 132 require.Equal(t, string(marshaledTx), txSigned) 133 134 // The test logic written below is not included in cosmos-sdk 135 // Marshalling/unmarshalling the tx wrapped in a struct should work. 136 txRequest := &cli.BroadcastReq{ 137 Mode: "block", 138 Tx: tx, 139 } 140 _, err = legacyCdc.MarshalJSON(txRequest) 141 require.NoError(t, err) 142 }