Skip to content

Commit 115b1c3

Browse files
authored
accounts/abi: Add tests for reflection ahead of refactor (#18434)
1 parent 4aeeecf commit 115b1c3

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed

accounts/abi/reflect_test.go

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Copyright 2019 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package abi
18+
19+
import (
20+
"reflect"
21+
"testing"
22+
)
23+
24+
type reflectTest struct {
25+
name string
26+
args []string
27+
struc interface{}
28+
want map[string]string
29+
err string
30+
}
31+
32+
var reflectTests = []reflectTest{
33+
{
34+
name: "OneToOneCorrespondance",
35+
args: []string{"fieldA"},
36+
struc: struct {
37+
FieldA int `abi:"fieldA"`
38+
}{},
39+
want: map[string]string{
40+
"fieldA": "FieldA",
41+
},
42+
},
43+
{
44+
name: "MissingFieldsInStruct",
45+
args: []string{"fieldA", "fieldB"},
46+
struc: struct {
47+
FieldA int `abi:"fieldA"`
48+
}{},
49+
want: map[string]string{
50+
"fieldA": "FieldA",
51+
},
52+
},
53+
{
54+
name: "MoreFieldsInStructThanArgs",
55+
args: []string{"fieldA"},
56+
struc: struct {
57+
FieldA int `abi:"fieldA"`
58+
FieldB int
59+
}{},
60+
want: map[string]string{
61+
"fieldA": "FieldA",
62+
},
63+
},
64+
{
65+
name: "MissingFieldInArgs",
66+
args: []string{"fieldA"},
67+
struc: struct {
68+
FieldA int `abi:"fieldA"`
69+
FieldB int `abi:"fieldB"`
70+
}{},
71+
err: "struct: abi tag 'fieldB' defined but not found in abi",
72+
},
73+
{
74+
name: "NoAbiDescriptor",
75+
args: []string{"fieldA"},
76+
struc: struct {
77+
FieldA int
78+
}{},
79+
want: map[string]string{
80+
"fieldA": "FieldA",
81+
},
82+
},
83+
{
84+
name: "NoArgs",
85+
args: []string{},
86+
struc: struct {
87+
FieldA int `abi:"fieldA"`
88+
}{},
89+
err: "struct: abi tag 'fieldA' defined but not found in abi",
90+
},
91+
{
92+
name: "DifferentName",
93+
args: []string{"fieldB"},
94+
struc: struct {
95+
FieldA int `abi:"fieldB"`
96+
}{},
97+
want: map[string]string{
98+
"fieldB": "FieldA",
99+
},
100+
},
101+
{
102+
name: "DifferentName",
103+
args: []string{"fieldB"},
104+
struc: struct {
105+
FieldA int `abi:"fieldB"`
106+
}{},
107+
want: map[string]string{
108+
"fieldB": "FieldA",
109+
},
110+
},
111+
{
112+
name: "MultipleFields",
113+
args: []string{"fieldA", "fieldB"},
114+
struc: struct {
115+
FieldA int `abi:"fieldA"`
116+
FieldB int `abi:"fieldB"`
117+
}{},
118+
want: map[string]string{
119+
"fieldA": "FieldA",
120+
"fieldB": "FieldB",
121+
},
122+
},
123+
{
124+
name: "MultipleFieldsABIMissing",
125+
args: []string{"fieldA", "fieldB"},
126+
struc: struct {
127+
FieldA int `abi:"fieldA"`
128+
FieldB int
129+
}{},
130+
want: map[string]string{
131+
"fieldA": "FieldA",
132+
"fieldB": "FieldB",
133+
},
134+
},
135+
{
136+
name: "NameConflict",
137+
args: []string{"fieldB"},
138+
struc: struct {
139+
FieldA int `abi:"fieldB"`
140+
FieldB int
141+
}{},
142+
err: "abi: multiple variables maps to the same abi field 'fieldB'",
143+
},
144+
{
145+
name: "Underscored",
146+
args: []string{"_"},
147+
struc: struct {
148+
FieldA int
149+
}{},
150+
err: "abi: purely underscored output cannot unpack to struct",
151+
},
152+
{
153+
name: "DoubleMapping",
154+
args: []string{"fieldB", "fieldC", "fieldA"},
155+
struc: struct {
156+
FieldA int `abi:"fieldC"`
157+
FieldB int
158+
}{},
159+
err: "abi: multiple outputs mapping to the same struct field 'FieldA'",
160+
},
161+
{
162+
name: "AlreadyMapped",
163+
args: []string{"fieldB", "fieldB"},
164+
struc: struct {
165+
FieldB int `abi:"fieldB"`
166+
}{},
167+
err: "struct: abi tag in 'FieldB' already mapped",
168+
},
169+
}
170+
171+
func TestReflectNameToStruct(t *testing.T) {
172+
for _, test := range reflectTests {
173+
t.Run(test.name, func(t *testing.T) {
174+
m, err := mapArgNamesToStructFields(test.args, reflect.ValueOf(test.struc))
175+
if len(test.err) > 0 {
176+
if err == nil || err.Error() != test.err {
177+
t.Fatalf("Invalid error: expected %v, got %v", test.err, err)
178+
}
179+
} else {
180+
if err != nil {
181+
t.Fatalf("Unexpected error: %v", err)
182+
}
183+
for fname := range test.want {
184+
if m[fname] != test.want[fname] {
185+
t.Fatalf("Incorrect value for field %s: expected %v, got %v", fname, test.want[fname], m[fname])
186+
}
187+
}
188+
}
189+
})
190+
}
191+
}

0 commit comments

Comments
 (0)