github.com/theQRL/go-zond@v0.2.1/common/types_test.go (about) 1 // Copyright 2015 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 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 "time" 29 ) 30 31 func TestBytesConversion(t *testing.T) { 32 bytes := []byte{5} 33 hash := BytesToHash(bytes) 34 35 var exp Hash 36 exp[31] = 5 37 38 if hash != exp { 39 t.Errorf("expected %x got %x", exp, hash) 40 } 41 } 42 43 func TestIsAddress(t *testing.T) { 44 tests := []struct { 45 str string 46 exp bool 47 }{ 48 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 49 {"5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", false}, 50 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", true}, 51 {"ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 52 {"ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", true}, 53 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed1", false}, 54 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beae", false}, 55 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed11", false}, 56 {"Zxaaeb6053f3e94c9b9a09f33669435e7ef1beaed", false}, 57 } 58 59 for _, test := range tests { 60 if result := IsAddress(test.str); result != test.exp { 61 t.Errorf("IsAddress(%s) == %v; expected %v", 62 test.str, result, test.exp) 63 } 64 } 65 } 66 67 func TestHashJsonValidation(t *testing.T) { 68 var tests = []struct { 69 Prefix string 70 Size int 71 Error string 72 }{ 73 {"", 62, "json: cannot unmarshal hex string without 0x prefix into Go value of type common.Hash"}, 74 {"0x", 66, "hex string has length 66, want 64 for common.Hash"}, 75 {"0x", 63, "json: cannot unmarshal hex string of odd length into Go value of type common.Hash"}, 76 {"0x", 0, "hex string has length 0, want 64 for common.Hash"}, 77 {"0x", 64, ""}, 78 {"0X", 64, ""}, 79 } 80 for _, test := range tests { 81 input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"` 82 var v Hash 83 err := json.Unmarshal([]byte(input), &v) 84 if err == nil { 85 if test.Error != "" { 86 t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error) 87 } 88 } else { 89 if err.Error() != test.Error { 90 t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error) 91 } 92 } 93 } 94 } 95 96 func TestAddressUnmarshalJSON(t *testing.T) { 97 var tests = []struct { 98 Input string 99 ShouldErr bool 100 Output *big.Int 101 }{ 102 {"", true, nil}, 103 {`""`, true, nil}, 104 {`"Z"`, true, nil}, 105 {`"Z00"`, true, nil}, 106 {`"ZG000000000000000000000000000000000000000"`, true, nil}, 107 {`"Z0000000000000000000000000000000000000000"`, false, big.NewInt(0)}, 108 {`"Z0000000000000000000000000000000000000010"`, false, big.NewInt(16)}, 109 } 110 for i, test := range tests { 111 var v Address 112 err := json.Unmarshal([]byte(test.Input), &v) 113 if err != nil && !test.ShouldErr { 114 t.Errorf("test #%d: unexpected error: %v", i, err) 115 } 116 if err == nil { 117 if test.ShouldErr { 118 t.Errorf("test #%d: expected error, got none", i) 119 } 120 if got := new(big.Int).SetBytes(v.Bytes()); got.Cmp(test.Output) != 0 { 121 t.Errorf("test #%d: address mismatch: have %v, want %v", i, got, test.Output) 122 } 123 } 124 } 125 } 126 127 func TestAddressHexChecksum(t *testing.T) { 128 var tests = []struct { 129 Input string 130 Output string 131 }{ 132 // Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification 133 {"Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "Z5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"}, 134 {"Zfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "ZfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"}, 135 {"Zdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "ZdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"}, 136 {"Zd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "ZD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"}, 137 } 138 for i, test := range tests { 139 addr, _ := NewAddressFromString(test.Input) 140 output := addr.Hex() 141 if output != test.Output { 142 t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output) 143 } 144 } 145 } 146 147 func BenchmarkAddressHex(b *testing.B) { 148 testAddr, _ := NewAddressFromString("Z5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") 149 for n := 0; n < b.N; n++ { 150 testAddr.Hex() 151 } 152 } 153 154 // Test checks if the customized json marshaller of MixedcaseAddress object 155 // is invoked correctly. In golang the struct pointer will inherit the 156 // non-pointer receiver methods, the reverse is not true. In the case of 157 // MixedcaseAddress, it must define the MarshalJSON method in the object 158 // but not the pointer level, so that this customized marshalled can be used 159 // for both MixedcaseAddress object and pointer. 160 func TestMixedcaseAddressMarshal(t *testing.T) { 161 var ( 162 output string 163 input = "Zae967917c465db8578ca9024c205720b1a3651A9" 164 ) 165 addr, err := NewMixedcaseAddressFromString(input) 166 if err != nil { 167 t.Fatal(err) 168 } 169 blob, err := json.Marshal(*addr) 170 if err != nil { 171 t.Fatal(err) 172 } 173 json.Unmarshal(blob, &output) 174 if output != input { 175 t.Fatal("Failed to marshal/unmarshal MixedcaseAddress object") 176 } 177 } 178 179 func TestMixedcaseAccount_Address(t *testing.T) { 180 var res []struct { 181 A MixedcaseAddress 182 Valid bool 183 } 184 if err := json.Unmarshal([]byte(`[ 185 {"A" : "Zae967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, 186 {"A" : "ZAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true}, 187 {"A" : "Z1111111111111111111112222222222223333323", "Valid": true} 188 ]`), &res); err != nil { 189 t.Fatal(err) 190 } 191 192 for _, r := range res { 193 if got := r.A.ValidChecksum(); got != r.Valid { 194 t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String()) 195 } 196 } 197 198 // These should throw exceptions: 199 var r2 []MixedcaseAddress 200 for _, r := range []string{ 201 `["Z11111111111111111111122222222222233333"]`, // Too short 202 `["Z111111111111111111111222222222222333332"]`, // Too short 203 `["Z11111111111111111111122222222222233333234"]`, // Too long 204 `["Z111111111111111111111222222222222333332344"]`, // Too long 205 `["1111111111111111111112222222222223333323"]`, // Missing Z 206 `["z1111111111111111111112222222222223333323"]`, // Lower case Z 207 `["ZG111111111111111111112222222222223333323"]`, //Non-hex 208 } { 209 if err := json.Unmarshal([]byte(r), &r2); err == nil { 210 t.Errorf("Expected failure, input %v", r) 211 } 212 } 213 } 214 215 func TestHash_Scan(t *testing.T) { 216 type args struct { 217 src interface{} 218 } 219 tests := []struct { 220 name string 221 args args 222 wantErr bool 223 }{ 224 { 225 name: "working 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 0x10, 0x00, 231 }}, 232 wantErr: false, 233 }, 234 { 235 name: "non working scan", 236 args: args{src: int64(1234567890)}, 237 wantErr: true, 238 }, 239 { 240 name: "invalid length scan", 241 args: args{src: []byte{ 242 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 243 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 244 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 245 }}, 246 wantErr: true, 247 }, 248 } 249 for _, tt := range tests { 250 t.Run(tt.name, func(t *testing.T) { 251 h := &Hash{} 252 if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr { 253 t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr) 254 } 255 256 if !tt.wantErr { 257 for i := range h { 258 if h[i] != tt.args.src.([]byte)[i] { 259 t.Errorf( 260 "Hash.Scan() didn't scan the %d src correctly (have %X, want %X)", 261 i, h[i], tt.args.src.([]byte)[i], 262 ) 263 } 264 } 265 } 266 }) 267 } 268 } 269 270 func TestHash_Value(t *testing.T) { 271 b := []byte{ 272 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 273 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 274 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 275 0x10, 0x00, 276 } 277 var usedH Hash 278 usedH.SetBytes(b) 279 tests := []struct { 280 name string 281 h Hash 282 want driver.Value 283 wantErr bool 284 }{ 285 { 286 name: "Working value", 287 h: usedH, 288 want: b, 289 wantErr: false, 290 }, 291 } 292 for _, tt := range tests { 293 t.Run(tt.name, func(t *testing.T) { 294 got, err := tt.h.Value() 295 if (err != nil) != tt.wantErr { 296 t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr) 297 return 298 } 299 if !reflect.DeepEqual(got, tt.want) { 300 t.Errorf("Hash.Value() = %v, want %v", got, tt.want) 301 } 302 }) 303 } 304 } 305 306 func TestAddress_Scan(t *testing.T) { 307 type args struct { 308 src interface{} 309 } 310 tests := []struct { 311 name string 312 args args 313 wantErr bool 314 }{ 315 { 316 name: "working scan", 317 args: args{src: []byte{ 318 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 319 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 320 }}, 321 wantErr: false, 322 }, 323 { 324 name: "non working scan", 325 args: args{src: int64(1234567890)}, 326 wantErr: true, 327 }, 328 { 329 name: "invalid length scan", 330 args: args{src: []byte{ 331 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 332 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 333 }}, 334 wantErr: true, 335 }, 336 } 337 for _, tt := range tests { 338 t.Run(tt.name, func(t *testing.T) { 339 a := &Address{} 340 if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr { 341 t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr) 342 } 343 344 if !tt.wantErr { 345 for i := range a { 346 if a[i] != tt.args.src.([]byte)[i] { 347 t.Errorf( 348 "Address.Scan() didn't scan the %d src correctly (have %X, want %X)", 349 i, a[i], tt.args.src.([]byte)[i], 350 ) 351 } 352 } 353 } 354 }) 355 } 356 } 357 358 func TestAddress_Value(t *testing.T) { 359 b := []byte{ 360 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 361 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 362 } 363 var usedA Address 364 usedA.SetBytes(b) 365 tests := []struct { 366 name string 367 a Address 368 want driver.Value 369 wantErr bool 370 }{ 371 { 372 name: "Working value", 373 a: usedA, 374 want: b, 375 wantErr: false, 376 }, 377 } 378 for _, tt := range tests { 379 t.Run(tt.name, func(t *testing.T) { 380 got, err := tt.a.Value() 381 if (err != nil) != tt.wantErr { 382 t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr) 383 return 384 } 385 if !reflect.DeepEqual(got, tt.want) { 386 t.Errorf("Address.Value() = %v, want %v", got, tt.want) 387 } 388 }) 389 } 390 } 391 392 func TestAddress_Format(t *testing.T) { 393 b := []byte{ 394 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 395 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 396 } 397 var addr Address 398 addr.SetBytes(b) 399 400 tests := []struct { 401 name string 402 out string 403 want string 404 }{ 405 { 406 name: "println", 407 out: fmt.Sprintln(addr), 408 want: "ZB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15\n", 409 }, 410 { 411 name: "print", 412 out: fmt.Sprint(addr), 413 want: "ZB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 414 }, 415 { 416 name: "printf-s", 417 out: func() string { 418 buf := new(bytes.Buffer) 419 fmt.Fprintf(buf, "%s", addr) 420 return buf.String() 421 }(), 422 want: "ZB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 423 }, 424 { 425 name: "printf-q", 426 out: fmt.Sprintf("%q", addr), 427 want: `"ZB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15"`, 428 }, 429 { 430 name: "printf-x", 431 out: fmt.Sprintf("%x", addr), 432 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15", 433 }, 434 { 435 name: "printf-X", 436 out: fmt.Sprintf("%X", addr), 437 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15", 438 }, 439 { 440 name: "printf-#x", 441 out: fmt.Sprintf("%#x", addr), 442 want: "Zb26f2b342aab24bcf63ea218c6a9274d30ab9a15", 443 }, 444 { 445 name: "printf-v", 446 out: fmt.Sprintf("%v", addr), 447 want: "ZB26f2b342AAb24BCF63ea218c6A9274D30Ab9A15", 448 }, 449 // The original default formatter for byte slice 450 { 451 name: "printf-d", 452 out: fmt.Sprintf("%d", addr), 453 want: "[178 111 43 52 42 171 36 188 246 62 162 24 198 169 39 77 48 171 154 21]", 454 }, 455 // Invalid format char. 456 { 457 name: "printf-t", 458 out: fmt.Sprintf("%t", addr), 459 want: "%!t(address=b26f2b342aab24bcf63ea218c6a9274d30ab9a15)", 460 }, 461 } 462 for _, tt := range tests { 463 t.Run(tt.name, func(t *testing.T) { 464 if tt.out != tt.want { 465 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 466 } 467 }) 468 } 469 } 470 471 func TestHash_Format(t *testing.T) { 472 var hash Hash 473 hash.SetBytes([]byte{ 474 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, 475 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 476 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, 477 0x10, 0x00, 478 }) 479 480 tests := []struct { 481 name string 482 out string 483 want string 484 }{ 485 { 486 name: "println", 487 out: fmt.Sprintln(hash), 488 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000\n", 489 }, 490 { 491 name: "print", 492 out: fmt.Sprint(hash), 493 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 494 }, 495 { 496 name: "printf-s", 497 out: func() string { 498 buf := new(bytes.Buffer) 499 fmt.Fprintf(buf, "%s", hash) 500 return buf.String() 501 }(), 502 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 503 }, 504 { 505 name: "printf-q", 506 out: fmt.Sprintf("%q", hash), 507 want: `"0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000"`, 508 }, 509 { 510 name: "printf-x", 511 out: fmt.Sprintf("%x", hash), 512 want: "b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 513 }, 514 { 515 name: "printf-X", 516 out: fmt.Sprintf("%X", hash), 517 want: "B26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 518 }, 519 { 520 name: "printf-#x", 521 out: fmt.Sprintf("%#x", hash), 522 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 523 }, 524 { 525 name: "printf-#X", 526 out: fmt.Sprintf("%#X", hash), 527 want: "0XB26F2B342AAB24BCF63EA218C6A9274D30AB9A15A218C6A9274D30AB9A151000", 528 }, 529 { 530 name: "printf-v", 531 out: fmt.Sprintf("%v", hash), 532 want: "0xb26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000", 533 }, 534 // The original default formatter for byte slice 535 { 536 name: "printf-d", 537 out: fmt.Sprintf("%d", hash), 538 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]", 539 }, 540 // Invalid format char. 541 { 542 name: "printf-t", 543 out: fmt.Sprintf("%t", hash), 544 want: "%!t(hash=b26f2b342aab24bcf63ea218c6a9274d30ab9a15a218c6a9274d30ab9a151000)", 545 }, 546 } 547 for _, tt := range tests { 548 t.Run(tt.name, func(t *testing.T) { 549 if tt.out != tt.want { 550 t.Errorf("%s does not render as expected:\n got %s\nwant %s", tt.name, tt.out, tt.want) 551 } 552 }) 553 } 554 } 555 556 func BenchmarkPrettyDuration(b *testing.B) { 557 var x = PrettyDuration(time.Duration(int64(1203123912312))) 558 b.Logf("Pre %s", time.Duration(x).String()) 559 var a string 560 b.ResetTimer() 561 for i := 0; i < b.N; i++ { 562 a = x.String() 563 } 564 b.Logf("Post %s", a) 565 }