github.com/lmittmann/w3@v0.20.0/util_test.go (about) 1 package w3_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "math/big" 7 "strconv" 8 "testing" 9 10 "github.com/ethereum/go-ethereum/common" 11 "github.com/lmittmann/w3" 12 ) 13 14 func ExampleI() { 15 fmt.Printf("%v wei\n", w3.I("0x1111d67bb1bb0000")) 16 fmt.Printf("%v wei\n", w3.I("1230000000000000000")) 17 fmt.Printf("%v wei\n", w3.I("1.23 ether")) 18 fmt.Printf("%v wei\n", w3.I("1.23 gwei")) 19 // Output: 20 // 1230000000000000000 wei 21 // 1230000000000000000 wei 22 // 1230000000000000000 wei 23 // 1230000000 wei 24 } 25 26 func ExampleFromWei() { 27 wei := big.NewInt(1_230000000_000000000) 28 fmt.Printf("%s Ether\n", w3.FromWei(wei, 18)) 29 // Output: 30 // 1.23 Ether 31 } 32 33 func TestA(t *testing.T) { 34 tests := []struct { 35 HexAddress string 36 WantPanic string 37 WantAddress common.Address 38 }{ 39 { 40 HexAddress: "0x000000000000000000000000000000000000c0Fe", 41 WantAddress: common.HexToAddress("0x000000000000000000000000000000000000c0Fe"), 42 }, 43 { 44 HexAddress: "000000000000000000000000000000000000c0Fe", 45 WantAddress: common.HexToAddress("0x000000000000000000000000000000000000c0Fe"), 46 }, 47 {HexAddress: "0xcofe", WantPanic: `invalid address "cofe": encoding/hex: invalid byte: U+006F 'o'`}, 48 {HexAddress: "0xc0Fe", WantPanic: `invalid address "c0Fe": must have 20 bytes`}, 49 } 50 51 for i, test := range tests { 52 t.Run(strconv.Itoa(i), func(t *testing.T) { 53 defer func() { 54 var gotPanic string 55 if r := recover(); r != nil { 56 gotPanic = r.(string) 57 } 58 if test.WantPanic != gotPanic { 59 t.Fatalf("want %q, got %q", test.WantPanic, gotPanic) 60 } 61 }() 62 63 gotAddr := w3.A(test.HexAddress) 64 if test.WantPanic == "" && test.WantAddress != gotAddr { 65 t.Fatalf("want: %s, got: %s", test.WantAddress, gotAddr) 66 } 67 }) 68 } 69 } 70 71 func TestB(t *testing.T) { 72 tests := []struct { 73 HexBytes string 74 WantPanic string 75 WantBytes []byte 76 }{ 77 {HexBytes: "0xc0fe", WantBytes: []byte{0xc0, 0xfe}}, 78 {HexBytes: "c0fe", WantBytes: []byte{0xc0, 0xfe}}, 79 {HexBytes: "0xcofe", WantPanic: `invalid bytes "cofe": encoding/hex: invalid byte: U+006F 'o'`}, 80 {HexBytes: "0xc0f", WantPanic: `invalid bytes "c0f": encoding/hex: odd length hex string`}, 81 } 82 83 for i, test := range tests { 84 t.Run(strconv.Itoa(i), func(t *testing.T) { 85 defer func() { 86 var gotPanic string 87 if r := recover(); r != nil { 88 gotPanic = r.(string) 89 } 90 if test.WantPanic != gotPanic { 91 t.Fatalf("want %q, got %q", test.WantPanic, gotPanic) 92 } 93 }() 94 95 gotBytes := w3.B(test.HexBytes) 96 if test.WantPanic == "" && !bytes.Equal(test.WantBytes, gotBytes) { 97 t.Fatalf("want: %x, got: %x", test.WantBytes, gotBytes) 98 } 99 }) 100 } 101 } 102 103 func TestH(t *testing.T) { 104 tests := []struct { 105 HexHash string 106 WantPanic string 107 WantHash common.Hash 108 }{ 109 { 110 HexHash: "0x000000000000000000000000000000000000000000000000000000000000c0fe", 111 WantHash: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000c0fe"), 112 }, 113 { 114 HexHash: "000000000000000000000000000000000000000000000000000000000000c0fe", 115 WantHash: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000c0fe"), 116 }, 117 {HexHash: "0xcofe", WantPanic: `invalid hash "cofe": encoding/hex: invalid byte: U+006F 'o'`}, 118 {HexHash: "0xc0fe", WantPanic: `invalid hash "c0fe": must have 32 bytes`}, 119 } 120 121 for i, test := range tests { 122 t.Run(strconv.Itoa(i), func(t *testing.T) { 123 defer func() { 124 var gotPanic string 125 if r := recover(); r != nil { 126 gotPanic = r.(string) 127 } 128 if test.WantPanic != gotPanic { 129 t.Fatalf("want %q, got %q", test.WantPanic, gotPanic) 130 } 131 }() 132 133 gotHash := w3.H(test.HexHash) 134 if test.WantPanic == "" && test.WantHash != gotHash { 135 t.Fatalf("want: %s, got: %s", test.WantHash, gotHash) 136 } 137 }) 138 } 139 } 140 141 func TestI(t *testing.T) { 142 tests := []struct { 143 StrInt string 144 WantPanic string 145 WantBig *big.Int 146 }{ 147 // hex big's 148 {StrInt: "0x0", WantBig: big.NewInt(0)}, 149 {StrInt: "0x1", WantBig: big.NewInt(1)}, 150 {StrInt: "0xff", WantBig: big.NewInt(255)}, 151 {StrInt: "0xO", WantPanic: `invalid hex big "0xO"`}, 152 153 // int big's 154 {StrInt: "0", WantBig: big.NewInt(0)}, 155 {StrInt: "1", WantBig: big.NewInt(1)}, 156 {StrInt: "255", WantBig: big.NewInt(255)}, 157 {StrInt: "X", WantPanic: `str big "X" must be number`}, 158 {StrInt: "888916043834286157872", WantBig: strBig("888916043834286157872")}, 159 160 // unit big's 161 {StrInt: "0 ether", WantBig: big.NewInt(0)}, 162 {StrInt: "0 eth", WantBig: big.NewInt(0)}, 163 {StrInt: "0 gwei", WantBig: big.NewInt(0)}, 164 {StrInt: "1 ether", WantBig: big.NewInt(1_000000000_000000000)}, 165 {StrInt: "1 eth", WantBig: big.NewInt(1_000000000_000000000)}, 166 {StrInt: "1ether", WantPanic: `str big "1ether" must be number`}, 167 {StrInt: "1.2 ether", WantBig: big.NewInt(1_200000000_000000000)}, 168 {StrInt: "01.2 ether", WantBig: big.NewInt(1_200000000_000000000)}, 169 {StrInt: "1.20 ether", WantBig: big.NewInt(1_200000000_000000000)}, 170 {StrInt: "1.200000000000000003 ether", WantBig: big.NewInt(1_200000000_000000003)}, 171 {StrInt: "1.2000000000000000034 ether", WantPanic: `str big "1.2000000000000000034 ether" exceeds precision`}, 172 {StrInt: "1 gwei", WantBig: big.NewInt(1_000000000)}, 173 {StrInt: "1.2 gwei", WantBig: big.NewInt(1_200000000)}, 174 {StrInt: "1.200000003 gwei", WantBig: big.NewInt(1_200000003)}, 175 {StrInt: "1.2000000034 gwei", WantPanic: `str big "1.2000000034 gwei" exceeds precision`}, 176 {StrInt: ".", WantPanic: `str big "." must be number`}, 177 {StrInt: ". ether", WantPanic: `str big ". ether" must be number`}, 178 {StrInt: "1.", WantPanic: `str big "1." without unit must be integer`}, 179 {StrInt: "1. ether", WantPanic: `str big "1. ether" must be number`}, 180 {StrInt: ".1", WantPanic: `str big ".1" must be number`}, 181 {StrInt: ".1 ether", WantPanic: `str big ".1 ether" must be number`}, 182 {StrInt: "0.1 ether", WantBig: big.NewInt(100000000_000000000)}, 183 {StrInt: "0.10 ether", WantBig: big.NewInt(100000000_000000000)}, 184 {StrInt: "00.10 ether", WantBig: big.NewInt(100000000_000000000)}, 185 {StrInt: " 1 ether", WantPanic: `str big " 1 ether" must be number`}, 186 {StrInt: "1 ether ", WantPanic: `str big "1 ether " has invalid unit "ether "`}, 187 {StrInt: "1 ether", WantPanic: `str big "1 ether" has invalid unit " ether"`}, 188 {StrInt: "-1", WantBig: big.NewInt(-1)}, 189 } 190 191 for i, test := range tests { 192 t.Run(strconv.Itoa(i), func(t *testing.T) { 193 defer func() { 194 var gotPanic string 195 if r := recover(); r != nil { 196 gotPanic = r.(string) 197 } 198 if test.WantPanic != gotPanic { 199 t.Fatalf("want %q, got %q", test.WantPanic, gotPanic) 200 } 201 }() 202 203 gotBig := w3.I(test.StrInt) 204 if test.WantPanic == "" && test.WantBig.Cmp(gotBig) != 0 { 205 t.Fatalf("want %v, got %v", test.WantBig, gotBig) 206 } 207 }) 208 } 209 } 210 211 func strBig(s string) *big.Int { 212 big, _ := new(big.Int).SetString(s, 10) 213 return big 214 } 215 216 func FuzzI(f *testing.F) { 217 f.Add([]byte{0x2a}) 218 f.Fuzz(func(t *testing.T, b []byte) { 219 wantBig := new(big.Int).SetBytes(b) 220 bigStr := wantBig.String() 221 if gotBig := w3.I(bigStr); wantBig.Cmp(gotBig) != 0 { 222 t.Fatalf("want %v, got %v", wantBig, gotBig) 223 } 224 225 bigHexstr := wantBig.Text(16) 226 if gotBig := w3.I("0x" + bigHexstr); wantBig.Cmp(gotBig) != 0 { 227 t.Fatalf("want %v, got %v", wantBig, gotBig) 228 } 229 }) 230 } 231 232 func BenchmarkI(b *testing.B) { 233 benchmarks := []string{ 234 "0x123456", 235 "1.23456 ether", 236 "1.000000000000000000 ether", 237 "1.000000000000000000123456 ether", 238 } 239 240 for _, bench := range benchmarks { 241 b.Run(bench, func(b *testing.B) { 242 b.ReportAllocs() 243 244 for range b.N { 245 w3.I(bench) 246 } 247 }) 248 } 249 } 250 251 func TestFromWei(t *testing.T) { 252 tests := []struct { 253 Wei *big.Int 254 Decimals uint8 255 Want string 256 }{ 257 {nil, 0, "<nil>"}, 258 {nil, 0, fmt.Sprint(nil)}, 259 {big.NewInt(0), 0, "0"}, 260 {big.NewInt(1), 0, "1"}, 261 {big.NewInt(0), 18, "0"}, 262 {big.NewInt(1), 18, "0.000000000000000001"}, 263 {big.NewInt(1000), 18, "0.000000000000001"}, 264 {big.NewInt(1000000), 18, "0.000000000001"}, 265 {big.NewInt(1000000000), 18, "0.000000001"}, 266 {big.NewInt(1000000000000), 18, "0.000001"}, 267 {big.NewInt(1000000000000000), 18, "0.001"}, 268 {big.NewInt(1000000000000000000), 18, "1"}, 269 {big.NewInt(-1), 18, "-0.000000000000000001"}, 270 {big.NewInt(-1000), 18, "-0.000000000000001"}, 271 {big.NewInt(-1000000), 18, "-0.000000000001"}, 272 {big.NewInt(-1000000000), 18, "-0.000000001"}, 273 {big.NewInt(-1000000000000), 18, "-0.000001"}, 274 {big.NewInt(-1000000000000000), 18, "-0.001"}, 275 {big.NewInt(-1000000000000000000), 18, "-1"}, 276 {big.NewInt(1000000000000000000), 15, "1000"}, 277 {big.NewInt(1000000000000000000), 12, "1000000"}, 278 {big.NewInt(1000000000000000000), 9, "1000000000"}, 279 {big.NewInt(1000000000000000000), 6, "1000000000000"}, 280 {big.NewInt(1000000000000000000), 3, "1000000000000000"}, 281 {big.NewInt(1000000000000000000), 0, "1000000000000000000"}, 282 } 283 284 for i, test := range tests { 285 t.Run(strconv.Itoa(i), func(t *testing.T) { 286 got := w3.FromWei(test.Wei, test.Decimals) 287 if got != test.Want { 288 t.Fatalf("%q != %q", got, test.Want) 289 } 290 }) 291 } 292 } 293 294 func TestBigMin(t *testing.T) { 295 tests := []struct { 296 A, B, Want *big.Int 297 }{ 298 {big.NewInt(0), big.NewInt(0), big.NewInt(0)}, 299 {big.NewInt(0), big.NewInt(1), big.NewInt(0)}, 300 {big.NewInt(1), big.NewInt(0), big.NewInt(0)}, 301 } 302 303 for i, test := range tests { 304 t.Run(strconv.Itoa(i), func(t *testing.T) { 305 got := w3.BigMin(test.A, test.B) 306 if test.Want.Cmp(got) != 0 { 307 t.Fatalf("want: %v, got: %v", test.Want, got) 308 } 309 }) 310 } 311 } 312 313 func TestBigMax(t *testing.T) { 314 tests := []struct { 315 A, B, Want *big.Int 316 }{ 317 {big.NewInt(0), big.NewInt(0), big.NewInt(0)}, 318 {big.NewInt(0), big.NewInt(1), big.NewInt(1)}, 319 {big.NewInt(1), big.NewInt(0), big.NewInt(1)}, 320 } 321 322 for i, test := range tests { 323 t.Run(strconv.Itoa(i), func(t *testing.T) { 324 got := w3.BigMax(test.A, test.B) 325 if test.Want.Cmp(got) != 0 { 326 t.Fatalf("want: %v, got: %v", test.Want, got) 327 } 328 }) 329 } 330 }