github.com/nonsense/go-ethereum@v1.9.7/accounts/abi/reflect_test.go (about) 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 }