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  }