github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/common/types_test.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar 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 go-aigar 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 go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package common
    19  
    20  import (
    21  	"database/sql/driver"
    22  	"encoding/json"
    23  	"math/big"
    24  	"reflect"
    25  	"strings"
    26  	"testing"
    27  )
    28  
    29  func TestBytesConversion(t *testing.T) {
    30  	bytes := []byte{5}
    31  	hash := BytesToHash(bytes)
    32  
    33  	var exp Hash
    34  	exp[31] = 5
    35  
    36  	if hash != exp {
    37  		t.Errorf("expected %x got %x", exp, hash)
    38  	}
    39  }
    40  
    41  func TestIsHexAddress(t *testing.T) {
    42  	tests := []struct {
    43  		str string
    44  		exp bool
    45  	}{
    46  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    47  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    48  		{"0X5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true},
    49  		{"0XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
    50  		{"0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true},
    51  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false},
    52  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false},
    53  		{"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false},
    54  		{"0xxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false},
    55  	}
    56  
    57  	for _, test := range tests {
    58  		if result := IsHexAddress(test.str); result != test.exp {
    59  			t.Errorf("IsHexAddress(%s) == %v; expected %v",
    60  				test.str, result, test.exp)
    61  		}
    62  	}
    63  }
    64  
    65  func TestHashJsonValidation(t *testing.T) {
    66  	var tests = []struct {
    67  		Prefix string
    68  		Size   int
    69  		Error  string
    70  	}{
    71  		{"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"},
    72  		{"0x", 66, "hex string has length 66, want 64 for common.Hash"},
    73  		{"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"},
    74  		{"0x", 0, "hex string has length 0, want 64 for common.Hash"},
    75  		{"0x", 64, ""},
    76  		{"0X", 64, ""},
    77  	}
    78  	for _, test := range tests {
    79  		input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"`
    80  		var v Hash
    81  		err := json.Unmarshal([]byte(input), &v)
    82  		if err == nil {
    83  			if test.Error != "" {
    84  				t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error)
    85  			}
    86  		} else {
    87  			if err.Error() != test.Error {
    88  				t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error)
    89  			}
    90  		}
    91  	}
    92  }
    93  
    94  func TestAddressUnmarshalJSON(t *testing.T) {
    95  	var tests = []struct {
    96  		Input     string
    97  		ShouldErr bool
    98  		Output    *big.Int
    99  	}{
   100  		{"", true, nil},
   101  		{`""`, true, nil},
   102  		{`"0x"`, true, nil},
   103  		{`"0x00"`, true, nil},
   104  		{`"0xG000000000000000000000000000000000000000"`, true, nil},
   105  		{`"0x0000000000000000000000000000000000000000"`, false, big.NewInt(0)},
   106  		{`"0x0000000000000000000000000000000000000010"`, false, big.NewInt(16)},
   107  	}
   108  	for i, test := range tests {
   109  		var v Address
   110  		err := json.Unmarshal([]byte(test.Input), &v)
   111  		if err != nil && !test.ShouldErr {
   112  			t.Errorf("test #%d: unexpected error: %v", i, err)
   113  		}
   114  		if err == nil {
   115  			if test.ShouldErr {
   116  				t.Errorf("test #%d: expected error, got none", i)
   117  			}
   118  			if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 {
   119  				t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output)
   120  			}
   121  		}
   122  	}
   123  }
   124  
   125  func TestAddressHexChecksum(t *testing.T) {
   126  	var tests = []struct {
   127  		Input  string
   128  		Output string
   129  	}{
   130  		// Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification
   131  		{"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"},
   132  		{"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"},
   133  		{"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"},
   134  		{"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"},
   135  		// Ensure that non-standard length input values are handled correctly
   136  		{"0xa", "0x000000000000000000000000000000000000000A"},
   137  		{"0x0a", "0x000000000000000000000000000000000000000A"},
   138  		{"0x00a", "0x000000000000000000000000000000000000000A"},
   139  		{"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"},
   140  	}
   141  	for i, test := range tests {
   142  		output := HexToAddress(test.Input).Hex()
   143  		if output != test.Output {
   144  			t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output)
   145  		}
   146  	}
   147  }
   148  
   149  func BenchmarkAddressHex(b *testing.B) {
   150  	testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
   151  	for n := 0; n < b.N; n++ {
   152  		testAddr.Hex()
   153  	}
   154  }
   155  
   156  func TestMixedcaseAccount_Address(t *testing.T) {
   157  
   158  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
   159  	// Note: 0X{checksum_addr} is not valid according to spec above
   160  
   161  	var res []struct {
   162  		A     MixedcaseAddress
   163  		Valid bool
   164  	}
   165  	if err := json.Unmarshal([]byte(`[
   166  		{"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   167  		{"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true},
   168  		{"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
   169  		{"A" : "0x1111111111111111111112222222222223333323", "Valid": true}
   170  		]`), &res); err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	for _, r := range res {
   175  		if got := r.A.ValidChecksum(); got != r.Valid {
   176  			t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String())
   177  		}
   178  	}
   179  
   180  	//These should throw exceptions:
   181  	var r2 []MixedcaseAddress
   182  	for _, r := range []string{
   183  		`["0x11111111111111111111122222222222233333"]`,     // Too short
   184  		`["0x111111111111111111111222222222222333332"]`,    // Too short
   185  		`["0x11111111111111111111122222222222233333234"]`,  // Too long
   186  		`["0x111111111111111111111222222222222333332344"]`, // Too long
   187  		`["1111111111111111111112222222222223333323"]`,     // Missing 0x
   188  		`["x1111111111111111111112222222222223333323"]`,    // Missing 0
   189  		`["0xG111111111111111111112222222222223333323"]`,   //Non-hex
   190  	} {
   191  		if err := json.Unmarshal([]byte(r), &r2); err == nil {
   192  			t.Errorf("Expected failure, input %v", r)
   193  		}
   194  
   195  	}
   196  
   197  }
   198  
   199  func TestHash_Scan(t *testing.T) {
   200  	type args struct {
   201  		src interface{}
   202  	}
   203  	tests := []struct {
   204  		name    string
   205  		args    args
   206  		wantErr bool
   207  	}{
   208  		{
   209  			name: "working scan",
   210  			args: args{src: []byte{
   211  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   212  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   213  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   214  				0x10, 0x00,
   215  			}},
   216  			wantErr: false,
   217  		},
   218  		{
   219  			name:    "non working scan",
   220  			args:    args{src: int64(1234567890)},
   221  			wantErr: true,
   222  		},
   223  		{
   224  			name: "invalid length scan",
   225  			args: args{src: []byte{
   226  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   227  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   228  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   229  			}},
   230  			wantErr: true,
   231  		},
   232  	}
   233  	for _, tt := range tests {
   234  		t.Run(tt.name, func(t *testing.T) {
   235  			h := &Hash{}
   236  			if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr {
   237  				t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr)
   238  			}
   239  
   240  			if !tt.wantErr {
   241  				for i := range h {
   242  					if h[i] != tt.args.src.([]byte)[i] {
   243  						t.Errorf(
   244  							"Hash.Scan() didn't scan the %d src correctly (have %X, want %X)",
   245  							i, h[i], tt.args.src.([]byte)[i],
   246  						)
   247  					}
   248  				}
   249  			}
   250  		})
   251  	}
   252  }
   253  
   254  func TestHash_Value(t *testing.T) {
   255  	b := []byte{
   256  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   257  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   258  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   259  		0x10, 0x00,
   260  	}
   261  	var usedH Hash
   262  	usedH.SetBytes(b)
   263  	tests := []struct {
   264  		name    string
   265  		h       Hash
   266  		want    driver.Value
   267  		wantErr bool
   268  	}{
   269  		{
   270  			name:    "Working value",
   271  			h:       usedH,
   272  			want:    b,
   273  			wantErr: false,
   274  		},
   275  	}
   276  	for _, tt := range tests {
   277  		t.Run(tt.name, func(t *testing.T) {
   278  			got, err := tt.h.Value()
   279  			if (err != nil) != tt.wantErr {
   280  				t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr)
   281  				return
   282  			}
   283  			if !reflect.DeepEqual(got, tt.want) {
   284  				t.Errorf("Hash.Value() = %v, want %v", got, tt.want)
   285  			}
   286  		})
   287  	}
   288  }
   289  
   290  func TestAddress_Scan(t *testing.T) {
   291  	type args struct {
   292  		src interface{}
   293  	}
   294  	tests := []struct {
   295  		name    string
   296  		args    args
   297  		wantErr bool
   298  	}{
   299  		{
   300  			name: "working scan",
   301  			args: args{src: []byte{
   302  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   303  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   304  			}},
   305  			wantErr: false,
   306  		},
   307  		{
   308  			name:    "non working scan",
   309  			args:    args{src: int64(1234567890)},
   310  			wantErr: true,
   311  		},
   312  		{
   313  			name: "invalid length scan",
   314  			args: args{src: []byte{
   315  				0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   316  				0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a,
   317  			}},
   318  			wantErr: true,
   319  		},
   320  	}
   321  	for _, tt := range tests {
   322  		t.Run(tt.name, func(t *testing.T) {
   323  			a := &Address{}
   324  			if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr {
   325  				t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr)
   326  			}
   327  
   328  			if !tt.wantErr {
   329  				for i := range a {
   330  					if a[i] != tt.args.src.([]byte)[i] {
   331  						t.Errorf(
   332  							"Address.Scan() didn't scan the %d src correctly (have %X, want %X)",
   333  							i, a[i], tt.args.src.([]byte)[i],
   334  						)
   335  					}
   336  				}
   337  			}
   338  		})
   339  	}
   340  }
   341  
   342  func TestAddress_Value(t *testing.T) {
   343  	b := []byte{
   344  		0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e,
   345  		0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15,
   346  	}
   347  	var usedA Address
   348  	usedA.SetBytes(b)
   349  	tests := []struct {
   350  		name    string
   351  		a       Address
   352  		want    driver.Value
   353  		wantErr bool
   354  	}{
   355  		{
   356  			name:    "Working value",
   357  			a:       usedA,
   358  			want:    b,
   359  			wantErr: false,
   360  		},
   361  	}
   362  	for _, tt := range tests {
   363  		t.Run(tt.name, func(t *testing.T) {
   364  			got, err := tt.a.Value()
   365  			if (err != nil) != tt.wantErr {
   366  				t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr)
   367  				return
   368  			}
   369  			if !reflect.DeepEqual(got, tt.want) {
   370  				t.Errorf("Address.Value() = %v, want %v", got, tt.want)
   371  			}
   372  		})
   373  	}
   374  }