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 }