github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/contract/parse_test.go (about)

     1  // Copyright (c) 2022 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package contract
     7  
     8  import (
     9  	"math/big"
    10  	"strconv"
    11  	"testing"
    12  
    13  	"github.com/ethereum/go-ethereum/accounts/abi"
    14  	"github.com/ethereum/go-ethereum/common"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func Test_parseOutputArgument(t *testing.T) {
    19  	require := require.New(t)
    20  
    21  	bigInt, _ := new(big.Int).SetString("2346783498523230921101011", 10)
    22  	var bytes31 [31]byte
    23  	var bytes24 [24]byte
    24  	copy(bytes31[:], "test byte31313131313131313131")
    25  	copy(bytes24[:], "test function (=24-byte)")
    26  
    27  	tests := []struct {
    28  		v          interface{}
    29  		t          string
    30  		components []abi.ArgumentMarshaling
    31  		expect     string
    32  	}{
    33  		{
    34  			int16(-3),
    35  			"int16",
    36  			nil,
    37  			"-3",
    38  		},
    39  		{
    40  			uint64(98237478346),
    41  			"uint64",
    42  			nil,
    43  			"98237478346",
    44  		},
    45  		{
    46  			bigInt,
    47  			"uint233",
    48  			nil,
    49  			"2346783498523230921101011",
    50  		},
    51  		{
    52  			common.HexToAddress("c7F43FaB2ca353d29cE0DA04851aB74f45B09593"),
    53  			"address",
    54  			nil,
    55  			"io1cl6rl2ev5dfa988qmgzg2x4hfazmp9vn2g66ng",
    56  		},
    57  		{
    58  			[]byte("test bytes"),
    59  			"bytes",
    60  			nil,
    61  			"0x74657374206279746573",
    62  		},
    63  		{
    64  			bytes31,
    65  			"bytes31",
    66  			nil,
    67  			"0x74657374206279746533313331333133313331333133313331333133310000",
    68  		},
    69  		{
    70  			[5]string{"IoTeX blockchain", "Raullen", "MenloPark", "2020/06/13", "Frank-is-testing!"},
    71  			"string[5]",
    72  			nil,
    73  			"[IoTeX blockchain Raullen MenloPark 2020/06/13 Frank-is-testing!]",
    74  		},
    75  		{
    76  			[][31]byte{bytes31, bytes31},
    77  			"bytes31[]",
    78  			nil,
    79  			"[0x74657374206279746533313331333133313331333133313331333133310000 0x74657374206279746533313331333133313331333133313331333133310000]",
    80  		},
    81  		{
    82  			struct {
    83  				A string
    84  				B [24]byte
    85  				C []*big.Int
    86  			}{"tuple test!", bytes24, []*big.Int{big.NewInt(-123), bigInt, big.NewInt(0)}},
    87  			"tuple",
    88  			[]abi.ArgumentMarshaling{{Name: "a", Type: "string"}, {Name: "b", Type: "bytes24"}, {Name: "c", Type: "int256[]"}},
    89  			"{a:tuple test! b:0x746573742066756e6374696f6e20283d32342d6279746529 c:[-123 2346783498523230921101011 0]}",
    90  		},
    91  	}
    92  
    93  	for _, test := range tests {
    94  		t, err := abi.NewType(test.t, "", test.components)
    95  		require.NoError(err)
    96  		result, ok := parseOutputArgument(test.v, &t)
    97  		require.True(ok)
    98  		require.Equal(test.expect, result)
    99  	}
   100  }
   101  
   102  func Test_parseAbi(t *testing.T) {
   103  	require := require.New(t)
   104  
   105  	abiBytes := []byte(`[
   106  {
   107  	"constant": false,
   108      "inputs": [
   109        {
   110          "name": "recipients",
   111          "type": "address[]"
   112        },
   113        {
   114          "name": "amounts",
   115          "type": "uint256[]"
   116        },
   117        {
   118          "name": "payload",
   119          "type": "string"
   120        }
   121      ],
   122      "name": "multiSend",
   123      "outputs": [],
   124      "payable": true,
   125      "stateMutability": "payable",
   126      "type": "function"
   127  }
   128  ]`)
   129  
   130  	abi, err := parseAbi(abiBytes)
   131  	require.NoError(err)
   132  
   133  	require.Len(abi.Methods, 1)
   134  	method, ok := abi.Methods["multiSend"]
   135  	require.True(ok)
   136  	require.False(method.IsConstant())
   137  	require.True(method.IsPayable())
   138  	require.Equal("payable", method.StateMutability)
   139  	require.Len(method.Inputs, 3)
   140  	require.Equal("recipients", method.Inputs[0].Name)
   141  	require.Equal("amounts", method.Inputs[1].Name)
   142  	require.Equal("payload", method.Inputs[2].Name)
   143  	require.Len(method.Outputs, 0)
   144  }
   145  
   146  func Test_parseInput(t *testing.T) {
   147  	require := require.New(t)
   148  
   149  	tests := []struct {
   150  		rowInput string
   151  		want     map[string]interface{}
   152  	}{
   153  		{
   154  			`{"name": "Marry"}`,
   155  			map[string]interface{}{
   156  				"name": "Marry",
   157  			},
   158  		},
   159  		{
   160  			`{"age": 12}`,
   161  			map[string]interface{}{
   162  				"age": float64(12),
   163  			},
   164  		},
   165  		{
   166  			`{"names": ["marry", "alice"]}`,
   167  			map[string]interface{}{
   168  				"names": []interface{}{"marry", "alice"},
   169  			},
   170  		},
   171  	}
   172  	for i, tt := range tests {
   173  		t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) {
   174  			got, err := parseInput(tt.rowInput)
   175  			require.NoError(err)
   176  			require.Equal(tt.want, got)
   177  		})
   178  	}
   179  }
   180  
   181  func Test_parseInputArgument(t *testing.T) {
   182  	require := require.New(t)
   183  
   184  	abiType, err := abi.NewType("string[]", "", nil)
   185  	require.NoError(err)
   186  
   187  	tests := []struct {
   188  		t    *abi.Type
   189  		arg  interface{}
   190  		want interface{}
   191  	}{
   192  		{
   193  			&abiType,
   194  			[]interface{}{"hello world", "happy holidays"},
   195  			[]string{"hello world", "happy holidays"},
   196  		},
   197  	}
   198  	for i, tt := range tests {
   199  		t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) {
   200  			got, err := parseInputArgument(tt.t, tt.arg)
   201  			require.NoError(err)
   202  			require.Equal(tt.want, got)
   203  		})
   204  	}
   205  }