accounts/abi: add Method Unpack tests
+ Reworked Method Unpack tests into more readable components + Added Method Unpack into slice test
This commit is contained in:
		
				
					committed by
					
						
						Martin Holst Swende
					
				
			
			
				
	
			
			
			
						parent
						
							95461e8b22
						
					
				
				
					commit
					1afca33eac
				
			@@ -27,6 +27,7 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type unpackTest struct {
 | 
					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 = `[
 | 
						const definition = `[
 | 
				
			||||||
	{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
 | 
						{ "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))
 | 
						abi, err := JSON(strings.NewReader(definition))
 | 
				
			||||||
	if err != nil {
 | 
						require.NoError(err)
 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// using buff to make the code readable
 | 
						// using buff to make the code readable
 | 
				
			||||||
	buff := new(bytes.Buffer)
 | 
						buff := new(bytes.Buffer)
 | 
				
			||||||
	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
 | 
						buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
 | 
				
			||||||
	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040"))
 | 
						buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040"))
 | 
				
			||||||
	buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005"))
 | 
						buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005"))
 | 
				
			||||||
	stringOut := "hello"
 | 
						buff.Write(common.RightPadBytes([]byte(expected.String), 32))
 | 
				
			||||||
	buff.Write(common.RightPadBytes([]byte(stringOut), 32))
 | 
						return abi, buff.Bytes(), expected
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var inter struct {
 | 
					func TestMethodMultiReturn(t *testing.T) {
 | 
				
			||||||
		Int    *big.Int
 | 
						type reversed struct {
 | 
				
			||||||
		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)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var reversed struct {
 | 
					 | 
				
			||||||
		String string
 | 
							String string
 | 
				
			||||||
		Int    *big.Int
 | 
							Int    *big.Int
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = abi.Unpack(&reversed, "multi", buff.Bytes())
 | 
						abi, data, expected := methodMultiReturn(require.New(t))
 | 
				
			||||||
	if err != nil {
 | 
						bigint := new(big.Int)
 | 
				
			||||||
		t.Error(err)
 | 
						var testCases = []struct {
 | 
				
			||||||
	}
 | 
							dest     interface{}
 | 
				
			||||||
 | 
							expected interface{}
 | 
				
			||||||
	if reversed.Int == nil || reversed.Int.Cmp(big.NewInt(1)) != 0 {
 | 
							error    string
 | 
				
			||||||
		t.Error("expected Int to be 1 got", reversed.Int)
 | 
							name     string
 | 
				
			||||||
	}
 | 
						}{{
 | 
				
			||||||
 | 
							&methodMultiOutput{},
 | 
				
			||||||
	if reversed.String != stringOut {
 | 
							&expected,
 | 
				
			||||||
		t.Error("expected String to be", stringOut, "got", reversed.String)
 | 
							"",
 | 
				
			||||||
 | 
							"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)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user