github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/common/types_test.go (about)

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