github.com/codingfuture/orig-energi3@v0.8.4/accounts/abi/reflect_test.go (about)

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