github.com/aidoskuneen/adk-node@v0.0.0-20220315131952-2e32567cb7f4/common/types_test.go (about)

     1  // Copyright 2021 The adkgo Authors
     2  // This file is part of the adkgo library (adapted for adkgo from go--ethereum v1.10.8).
     3  //
     4  // the adkgo 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 adkgo 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 adkgo library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package common
    18  
    19  import (
    20  	"bytes"
    21  	"database/sql/driver"
    22  	"encoding/json"
    23  	"fmt"
    24  	"math/big"
    25  	"reflect"
    26  	"strings"
    27  	"testing"
    28  )
    29  
    30  func TestBytesConversion(t *testing.T) {
    31  	bytes := []byte{5}
    32  	hash := BytesToHash(bytes)
    33  
    34  	var exp Hash
    35  	exp[31] = 5
    36  
    37  	if hash != exp {
    38  		t.Errorf("expected %x got %x", exp, hash)
    39  	}
    40  }
    41  
    42  func TestIsHexAddress(t *testing.T) {
    43  	tests := []struct {
    44  		str string
    45  		exp bool
    46  	}{
    47  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    48  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    49  		{"0X5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    50  		{"0XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
    51  		{"0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
    52  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false},
    53  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false},
    54  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false},
    55  		{"0xxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false},
    56  	}
    57  
    58  	for _, test := range tests {
    59  		if result := IsHexAddress(test.str); result != test.exp {
    60  			t.Errorf("IsHexAddress(%s) == %v; expected %v",
    61  				test.str, result, test.exp)
    62  		}
    63  	}
    64  }
    65  
    66  func TestHashJsonValidation(t *testing.T) {
    67  	var tests = []struct {
    68  		Prefix string
    69  		Size   int
    70  		Error  string
    71  	}{
    72  		{"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"},
    73  		{"0x", 66, "hex string has length 66, want 64 for common.Hash"},
    74  		{"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"},
    75  		{"0x", 0, "hex string has length 0, want 64 for common.Hash"},
    76  		{"0x", 64, ""},
    77  		{"0X", 64, ""},
    78  	}
    79  	for _, test := range tests {
    80  		input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"`
    81  		var v Hash
    82  		err := json.Unmarshal([]byte(input), &v)
    83  		if err == nil {
    84  			if test.Error != "" {
    85  				t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error)
    86  			}
    87  		} else {
    88  			if err.Error() != test.Error {
    89  				t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error)
    90  			}
    91  		}
    92  	}
    93  }
    94  
    95  func TestAddressUnmarshalJSON(t *testing.T) {
    96  	var tests = []struct {
    97  		Input     string
    98  		ShouldErr bool
    99  		Output    *big.Int
   100  	}{
   101  		{"", true, nil},
   102  		{`""`, true, nil},
   103  		{`"0x"`, true, nil},
   104  		{`"0x00"`, true, nil},
   105  		{`"0xG000000000000000000000000000000000000000"`, true, nil},
   106  		{`"0x0000000000000000000000000000000000000000"`, false, big.NewInt(0)},
   107  		{`"0x0000000000000000000000000000000000000010"`, false, big.NewInt(16)},
   108  	}
   109  	for i, test := range tests {
   110  		var v Address
   111  		err := json.Unmarshal([]byte(test.Input), &v)
   112  		if err != nil && !test.ShouldErr {
   113  			t.Errorf("test #%d: unexpected error: %v", i, err)
   114  		}
   115  		if err == nil {
   116  			if test.ShouldErr {
   117  				t.Errorf("test #%d: expected error, got none", i)
   118  			}
   119  			if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 {
   120  				t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output)
   121  			}
   122  		}
   123  	}
   124  }
   125  
   126  func TestAddressHexChecksum(t *testing.T) {
   127  	var tests = []struct {
   128  		Input  string
   129  		Output string
   130  	}{
   131  		// Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification
   132  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"},
   133  		{"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"},
   134  		{"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"},
   135  		{"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"},
   136  		// Ensure that non-standard length input values are handled correctly
   137  		{"0xa", "0x000000000000000000000000000000000000000A"},
   138  		{"0x0a", "0x000000000000000000000000000000000000000A"},
   139  		{"0x00a", "0x000000000000000000000000000000000000000A"},
   140  		{"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"},
   141  	}
   142  	for i, test := range tests {
   143  		output := HexToAddress(test.Input).Hex()
   144  		if output != test.Output {
   145  			t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output)
   146  		}
   147  	}
   148  }
   149  
   150  func BenchmarkAddressHex(b *testing.B) {
   151  	testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
   152  	for n := 0; n < b.N; n++ {
   153  		testAddr.Hex()
   154  	}
   155  }
   156  
   157  func TestMixedcaseAccount_Address(t *testing.T) {
   158  
   159  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
   160  	// Note: 0X{checksum_addr} is not valid according to spec above
   161  
   162  	var res []struct {
   163  		A     MixedcaseAddress
   164  		Valid bool
   165  	}
   166  	if err := json.Unmarshal([]byte(`[
   167  		{"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   168  		{"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true},
   169  		{"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   170  		{"A" : "0x1111111111111111111112222222222223333323", "Valid": true}
   171  		]`), &res); err != nil {
   172  		t.Fatal(err)
   173  	}
   174  
   175  	for _, r := range res {
   176  		if got := r.A.ValidChecksum(); got != r.Valid {
   177  			t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String())
   178  		}
   179  	}
   180  
   181  	//These should throw exceptions:
   182  	var r2 []MixedcaseAddress
   183  	for _, r := range []string{
   184  		`["0x11111111111111111111122222222222233333"]`,     // Too short
   185  		`["0x111111111111111111111222222222222333332"]`,    // Too short
   186  		`["0x11111111111111111111122222222222233333234"]`,  // Too long
   187  		`["0x111111111111111111111222222222222333332344"]`, // Too long
   188  		`["1111111111111111111112222222222223333323"]`,     // Missing 0x
   189  		`["x1111111111111111111112222222222223333323"]`,    // Missing 0
   190  		`["0xG111111111111111111112222222222223333323"]`,   //Non-hex
   191  	} {
   192  		if err := json.Unmarshal([]byte(r), &r2); err == nil {
   193  			t.Errorf("Expected failure, input %v", r)
   194  		}
   195  
   196  	}
   197  
   198  }
   199  
   200  func TestHash_Scan(t *testing.T) {
   201  	type args struct {
   202  		src interface{}
   203  	}
   204  	tests := []struct {
   205  		name    string
   206  		args    args
   207  		wantErr bool
   208  	}{
   209  		{
   210  			name: "working scan",
   211  			args: args{src: []byte{
   212  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   213  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   214  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   215  				0x10, 0x00,
   216  			}},
   217  			wantErr: false,
   218  		},
   219  		{
   220  			name:    "non working scan",
   221  			args:    args{src: int64(1234567890)},
   222  			wantErr: true,
   223  		},
   224  		{
   225  			name: "invalid length scan",
   226  			args: args{src: []byte{
   227  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   228  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   229  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   230  			}},
   231  			wantErr: true,
   232  		},
   233  	}
   234  	for _, tt := range tests {
   235  		t.Run(tt.name, func(t *testing.T) {
   236  			h := &Hash{}
   237  			if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr {
   238  				t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr)
   239  			}
   240  
   241  			if !tt.wantErr {
   242  				for i := range h {
   243  					if h[i] != tt.args.src.([]byte)[i] {
   244  						t.Errorf(
   245  							"Hash.Scan() didn't scan the %d src correctly (have %X, want %X)",
   246  							i, h[i], tt.args.src.([]byte)[i],
   247  						)
   248  					}
   249  				}
   250  			}
   251  		})
   252  	}
   253  }
   254  
   255  func TestHash_Value(t *testing.T) {
   256  	b := []byte{
   257  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   258  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   259  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   260  		0x10, 0x00,
   261  	}
   262  	var usedH Hash
   263  	usedH.SetBytes(b)
   264  	tests := []struct {
   265  		name    string
   266  		h       Hash
   267  		want    driver.Value
   268  		wantErr bool
   269  	}{
   270  		{
   271  			name:    "Working value",
   272  			h:       usedH,
   273  			want:    b,
   274  			wantErr: false,
   275  		},
   276  	}
   277  	for _, tt := range tests {
   278  		t.Run(tt.name, func(t *testing.T) {
   279  			got, err := tt.h.Value()
   280  			if (err != nil) != tt.wantErr {
   281  				t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr)
   282  				return
   283  			}
   284  			if !reflect.DeepEqual(got, tt.want) {
   285  				t.Errorf("Hash.Value() = %v, want %v", got, tt.want)
   286  			}
   287  		})
   288  	}
   289  }
   290  
   291  func TestAddress_Scan(t *testing.T) {
   292  	type args struct {
   293  		src interface{}
   294  	}
   295  	tests := []struct {
   296  		name    string
   297  		args    args
   298  		wantErr bool
   299  	}{
   300  		{
   301  			name: "working scan",
   302  			args: args{src: []byte{
   303  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   304  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   305  			}},
   306  			wantErr: false,
   307  		},
   308  		{
   309  			name:    "non working scan",
   310  			args:    args{src: int64(1234567890)},
   311  			wantErr: true,
   312  		},
   313  		{
   314  			name: "invalid length scan",
   315  			args: args{src: []byte{
   316  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   317  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a,
   318  			}},
   319  			wantErr: true,
   320  		},
   321  	}
   322  	for _, tt := range tests {
   323  		t.Run(tt.name, func(t *testing.T) {
   324  			a := &Address{}
   325  			if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr {
   326  				t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr)
   327  			}
   328  
   329  			if !tt.wantErr {
   330  				for i := range a {
   331  					if a[i] != tt.args.src.([]byte)[i] {
   332  						t.Errorf(
   333  							"Address.Scan() didn't scan the %d src correctly (have %X, want %X)",
   334  							i, a[i], tt.args.src.([]byte)[i],
   335  						)
   336  					}
   337  				}
   338  			}
   339  		})
   340  	}
   341  }
   342  
   343  func TestAddress_Value(t *testing.T) {
   344  	b := []byte{
   345  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   346  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   347  	}
   348  	var usedA Address
   349  	usedA.SetBytes(b)
   350  	tests := []struct {
   351  		name    string
   352  		a       Address
   353  		want    driver.Value
   354  		wantErr bool
   355  	}{
   356  		{
   357  			name:    "Working value",
   358  			a:       usedA,
   359  			want:    b,
   360  			wantErr: false,
   361  		},
   362  	}
   363  	for _, tt := range tests {
   364  		t.Run(tt.name, func(t *testing.T) {
   365  			got, err := tt.a.Value()
   366  			if (err != nil) != tt.wantErr {
   367  				t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr)
   368  				return
   369  			}
   370  			if !reflect.DeepEqual(got, tt.want) {
   371  				t.Errorf("Address.Value() = %v, want %v", got, tt.want)
   372  			}
   373  		})
   374  	}
   375  }
   376  
   377  func TestAddress_Format(t *testing.T) {
   378  	b := []byte{
   379  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   380  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   381  	}
   382  	var addr Address
   383  	addr.SetBytes(b)
   384  
   385  	tests := []struct {
   386  		name string
   387  		out  string
   388  		want string
   389  	}{
   390  		{
   391  			name: "println",
   392  			out:  fmt.Sprintln(addr),
   393  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n",
   394  		},
   395  		{
   396  			name: "print",
   397  			out:  fmt.Sprint(addr),
   398  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   399  		},
   400  		{
   401  			name: "printf-s",
   402  			out: func() string {
   403  				buf := new(bytes.Buffer)
   404  				fmt.Fprintf(buf, "%s", addr)
   405  				return buf.String()
   406  			}(),
   407  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   408  		},
   409  		{
   410  			name: "printf-q",
   411  			out:  fmt.Sprintf("%q", addr),
   412  			want: `"0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`,
   413  		},
   414  		{
   415  			name: "printf-x",
   416  			out:  fmt.Sprintf("%x", addr),
   417  			want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15",
   418  		},
   419  		{
   420  			name: "printf-X",
   421  			out:  fmt.Sprintf("%X", addr),
   422  			want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15",
   423  		},
   424  		{
   425  			name: "printf-#x",
   426  			out:  fmt.Sprintf("%#x", addr),
   427  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15",
   428  		},
   429  		{
   430  			name: "printf-v",
   431  			out:  fmt.Sprintf("%v", addr),
   432  			want: "0xB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15",
   433  		},
   434  		// The original default formatter for byte slice
   435  		{
   436  			name: "printf-d",
   437  			out:  fmt.Sprintf("%d", addr),
   438  			want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]",
   439  		},
   440  		// Invalid format char.
   441  		{
   442  			name: "printf-t",
   443  			out:  fmt.Sprintf("%t", addr),
   444  			want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)",
   445  		},
   446  	}
   447  	for _, tt := range tests {
   448  		t.Run(tt.name, func(t *testing.T) {
   449  			if tt.out != tt.want {
   450  				t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want)
   451  			}
   452  		})
   453  	}
   454  }
   455  
   456  func TestHash_Format(t *testing.T) {
   457  	var hash Hash
   458  	hash.SetBytes([]byte{
   459  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   460  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   461  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   462  		0x10, 0x00,
   463  	})
   464  
   465  	tests := []struct {
   466  		name string
   467  		out  string
   468  		want string
   469  	}{
   470  		{
   471  			name: "println",
   472  			out:  fmt.Sprintln(hash),
   473  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n",
   474  		},
   475  		{
   476  			name: "print",
   477  			out:  fmt.Sprint(hash),
   478  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   479  		},
   480  		{
   481  			name: "printf-s",
   482  			out: func() string {
   483  				buf := new(bytes.Buffer)
   484  				fmt.Fprintf(buf, "%s", hash)
   485  				return buf.String()
   486  			}(),
   487  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   488  		},
   489  		{
   490  			name: "printf-q",
   491  			out:  fmt.Sprintf("%q", hash),
   492  			want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`,
   493  		},
   494  		{
   495  			name: "printf-x",
   496  			out:  fmt.Sprintf("%x", hash),
   497  			want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   498  		},
   499  		{
   500  			name: "printf-X",
   501  			out:  fmt.Sprintf("%X", hash),
   502  			want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000",
   503  		},
   504  		{
   505  			name: "printf-#x",
   506  			out:  fmt.Sprintf("%#x", hash),
   507  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   508  		},
   509  		{
   510  			name: "printf-#X",
   511  			out:  fmt.Sprintf("%#X", hash),
   512  			want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000",
   513  		},
   514  		{
   515  			name: "printf-v",
   516  			out:  fmt.Sprintf("%v", hash),
   517  			want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000",
   518  		},
   519  		// The original default formatter for byte slice
   520  		{
   521  			name: "printf-d",
   522  			out:  fmt.Sprintf("%d", hash),
   523  			want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21 162 24 198 169 39 77 48 171 154 21 16 0]",
   524  		},
   525  		// Invalid format char.
   526  		{
   527  			name: "printf-t",
   528  			out:  fmt.Sprintf("%t", hash),
   529  			want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)",
   530  		},
   531  	}
   532  	for _, tt := range tests {
   533  		t.Run(tt.name, func(t *testing.T) {
   534  			if tt.out != tt.want {
   535  				t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want)
   536  			}
   537  		})
   538  	}
   539  }