|
|
|
@ -27,6 +27,7 @@ import ( |
|
|
|
|
"testing" |
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
|
"github.com/stretchr/testify/require" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type unpackTest struct { |
|
|
|
@ -286,56 +287,78 @@ func TestUnpack(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestMultiReturnWithStruct(t *testing.T) { |
|
|
|
|
type methodMultiOutput struct { |
|
|
|
|
Int *big.Int |
|
|
|
|
String string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func methodMultiReturn(require *require.Assertions) (ABI, []byte, methodMultiOutput) { |
|
|
|
|
const definition = `[ |
|
|
|
|
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]` |
|
|
|
|
var expected = methodMultiOutput{big.NewInt(1), "hello"} |
|
|
|
|
|
|
|
|
|
abi, err := JSON(strings.NewReader(definition)) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
require.NoError(err) |
|
|
|
|
// using buff to make the code readable
|
|
|
|
|
buff := new(bytes.Buffer) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) |
|
|
|
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005")) |
|
|
|
|
stringOut := "hello" |
|
|
|
|
buff.Write(common.RightPadBytes([]byte(stringOut), 32)) |
|
|
|
|
|
|
|
|
|
var inter struct { |
|
|
|
|
Int *big.Int |
|
|
|
|
String string |
|
|
|
|
} |
|
|
|
|
err = abi.Unpack(&inter, "multi", buff.Bytes()) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if inter.Int == nil || inter.Int.Cmp(big.NewInt(1)) != 0 { |
|
|
|
|
t.Error("expected Int to be 1 got", inter.Int) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if inter.String != stringOut { |
|
|
|
|
t.Error("expected String to be", stringOut, "got", inter.String) |
|
|
|
|
} |
|
|
|
|
buff.Write(common.RightPadBytes([]byte(expected.String), 32)) |
|
|
|
|
return abi, buff.Bytes(), expected |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var reversed struct { |
|
|
|
|
func TestMethodMultiReturn(t *testing.T) { |
|
|
|
|
type reversed struct { |
|
|
|
|
String string |
|
|
|
|
Int *big.Int |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = abi.Unpack(&reversed, "multi", buff.Bytes()) |
|
|
|
|
if err != nil { |
|
|
|
|
t.Error(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if reversed.Int == nil || reversed.Int.Cmp(big.NewInt(1)) != 0 { |
|
|
|
|
t.Error("expected Int to be 1 got", reversed.Int) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if reversed.String != stringOut { |
|
|
|
|
t.Error("expected String to be", stringOut, "got", reversed.String) |
|
|
|
|
abi, data, expected := methodMultiReturn(require.New(t)) |
|
|
|
|
bigint := new(big.Int) |
|
|
|
|
var testCases = []struct { |
|
|
|
|
dest interface{} |
|
|
|
|
expected interface{} |
|
|
|
|
error string |
|
|
|
|
name string |
|
|
|
|
}{{ |
|
|
|
|
&methodMultiOutput{}, |
|
|
|
|
&expected, |
|
|
|
|
"", |
|
|
|
|
"Can unpack into structure", |
|
|
|
|
}, { |
|
|
|
|
&reversed{}, |
|
|
|
|
&reversed{expected.String, expected.Int}, |
|
|
|
|
"", |
|
|
|
|
"Can unpack into reversed structure", |
|
|
|
|
}, { |
|
|
|
|
&[]interface{}{&bigint, new(string)}, |
|
|
|
|
&[]interface{}{&expected.Int, &expected.String}, |
|
|
|
|
"", |
|
|
|
|
"Can unpack into a slice", |
|
|
|
|
}, { |
|
|
|
|
&[]interface{}{new(int), new(int)}, |
|
|
|
|
&[]interface{}{&expected.Int, &expected.String}, |
|
|
|
|
"abi: cannot unmarshal *big.Int in to int", |
|
|
|
|
"Can not unpack into a slice with wrong types", |
|
|
|
|
}, { |
|
|
|
|
&[]interface{}{new(int)}, |
|
|
|
|
&[]interface{}{}, |
|
|
|
|
"abi: insufficient number of elements in the list/array for unpack, want 2, got 1", |
|
|
|
|
"Can not unpack into a slice with wrong types", |
|
|
|
|
}} |
|
|
|
|
for _, tc := range testCases { |
|
|
|
|
tc := tc |
|
|
|
|
t.Run(tc.name, func(t *testing.T) { |
|
|
|
|
require := require.New(t) |
|
|
|
|
err := abi.Unpack(tc.dest, "multi", data) |
|
|
|
|
if tc.error == "" { |
|
|
|
|
require.Nil(err, "Should be able to unpack method outputs.") |
|
|
|
|
require.Equal(tc.expected, tc.dest) |
|
|
|
|
} else { |
|
|
|
|
require.EqualError(err, tc.error) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|