...

Source file src/strconv/atoi_test.go

Documentation: strconv

		 1  // Copyright 2009 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package strconv_test
		 6  
		 7  import (
		 8  	"errors"
		 9  	"fmt"
		10  	"reflect"
		11  	. "strconv"
		12  	"testing"
		13  )
		14  
		15  type parseUint64Test struct {
		16  	in	string
		17  	out uint64
		18  	err error
		19  }
		20  
		21  var parseUint64Tests = []parseUint64Test{
		22  	{"", 0, ErrSyntax},
		23  	{"0", 0, nil},
		24  	{"1", 1, nil},
		25  	{"12345", 12345, nil},
		26  	{"012345", 12345, nil},
		27  	{"12345x", 0, ErrSyntax},
		28  	{"98765432100", 98765432100, nil},
		29  	{"18446744073709551615", 1<<64 - 1, nil},
		30  	{"18446744073709551616", 1<<64 - 1, ErrRange},
		31  	{"18446744073709551620", 1<<64 - 1, ErrRange},
		32  	{"1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
		33  	{"_12345", 0, ErrSyntax},
		34  	{"1__2345", 0, ErrSyntax},
		35  	{"12345_", 0, ErrSyntax},
		36  	{"-0", 0, ErrSyntax},
		37  	{"-1", 0, ErrSyntax},
		38  	{"+1", 0, ErrSyntax},
		39  }
		40  
		41  type parseUint64BaseTest struct {
		42  	in	 string
		43  	base int
		44  	out	uint64
		45  	err	error
		46  }
		47  
		48  var parseUint64BaseTests = []parseUint64BaseTest{
		49  	{"", 0, 0, ErrSyntax},
		50  	{"0", 0, 0, nil},
		51  	{"0x", 0, 0, ErrSyntax},
		52  	{"0X", 0, 0, ErrSyntax},
		53  	{"1", 0, 1, nil},
		54  	{"12345", 0, 12345, nil},
		55  	{"012345", 0, 012345, nil},
		56  	{"0x12345", 0, 0x12345, nil},
		57  	{"0X12345", 0, 0x12345, nil},
		58  	{"12345x", 0, 0, ErrSyntax},
		59  	{"0xabcdefg123", 0, 0, ErrSyntax},
		60  	{"123456789abc", 0, 0, ErrSyntax},
		61  	{"98765432100", 0, 98765432100, nil},
		62  	{"18446744073709551615", 0, 1<<64 - 1, nil},
		63  	{"18446744073709551616", 0, 1<<64 - 1, ErrRange},
		64  	{"18446744073709551620", 0, 1<<64 - 1, ErrRange},
		65  	{"0xFFFFFFFFFFFFFFFF", 0, 1<<64 - 1, nil},
		66  	{"0x10000000000000000", 0, 1<<64 - 1, ErrRange},
		67  	{"01777777777777777777777", 0, 1<<64 - 1, nil},
		68  	{"01777777777777777777778", 0, 0, ErrSyntax},
		69  	{"02000000000000000000000", 0, 1<<64 - 1, ErrRange},
		70  	{"0200000000000000000000", 0, 1 << 61, nil},
		71  	{"0b", 0, 0, ErrSyntax},
		72  	{"0B", 0, 0, ErrSyntax},
		73  	{"0b101", 0, 5, nil},
		74  	{"0B101", 0, 5, nil},
		75  	{"0o", 0, 0, ErrSyntax},
		76  	{"0O", 0, 0, ErrSyntax},
		77  	{"0o377", 0, 255, nil},
		78  	{"0O377", 0, 255, nil},
		79  
		80  	// underscores allowed with base == 0 only
		81  	{"1_2_3_4_5", 0, 12345, nil}, // base 0 => 10
		82  	{"_12345", 0, 0, ErrSyntax},
		83  	{"1__2345", 0, 0, ErrSyntax},
		84  	{"12345_", 0, 0, ErrSyntax},
		85  
		86  	{"1_2_3_4_5", 10, 0, ErrSyntax}, // base 10
		87  	{"_12345", 10, 0, ErrSyntax},
		88  	{"1__2345", 10, 0, ErrSyntax},
		89  	{"12345_", 10, 0, ErrSyntax},
		90  
		91  	{"0x_1_2_3_4_5", 0, 0x12345, nil}, // base 0 => 16
		92  	{"_0x12345", 0, 0, ErrSyntax},
		93  	{"0x__12345", 0, 0, ErrSyntax},
		94  	{"0x1__2345", 0, 0, ErrSyntax},
		95  	{"0x1234__5", 0, 0, ErrSyntax},
		96  	{"0x12345_", 0, 0, ErrSyntax},
		97  
		98  	{"1_2_3_4_5", 16, 0, ErrSyntax}, // base 16
		99  	{"_12345", 16, 0, ErrSyntax},
	 100  	{"1__2345", 16, 0, ErrSyntax},
	 101  	{"1234__5", 16, 0, ErrSyntax},
	 102  	{"12345_", 16, 0, ErrSyntax},
	 103  
	 104  	{"0_1_2_3_4_5", 0, 012345, nil}, // base 0 => 8 (0377)
	 105  	{"_012345", 0, 0, ErrSyntax},
	 106  	{"0__12345", 0, 0, ErrSyntax},
	 107  	{"01234__5", 0, 0, ErrSyntax},
	 108  	{"012345_", 0, 0, ErrSyntax},
	 109  
	 110  	{"0o_1_2_3_4_5", 0, 012345, nil}, // base 0 => 8 (0o377)
	 111  	{"_0o12345", 0, 0, ErrSyntax},
	 112  	{"0o__12345", 0, 0, ErrSyntax},
	 113  	{"0o1234__5", 0, 0, ErrSyntax},
	 114  	{"0o12345_", 0, 0, ErrSyntax},
	 115  
	 116  	{"0_1_2_3_4_5", 8, 0, ErrSyntax}, // base 8
	 117  	{"_012345", 8, 0, ErrSyntax},
	 118  	{"0__12345", 8, 0, ErrSyntax},
	 119  	{"01234__5", 8, 0, ErrSyntax},
	 120  	{"012345_", 8, 0, ErrSyntax},
	 121  
	 122  	{"0b_1_0_1", 0, 5, nil}, // base 0 => 2 (0b101)
	 123  	{"_0b101", 0, 0, ErrSyntax},
	 124  	{"0b__101", 0, 0, ErrSyntax},
	 125  	{"0b1__01", 0, 0, ErrSyntax},
	 126  	{"0b10__1", 0, 0, ErrSyntax},
	 127  	{"0b101_", 0, 0, ErrSyntax},
	 128  
	 129  	{"1_0_1", 2, 0, ErrSyntax}, // base 2
	 130  	{"_101", 2, 0, ErrSyntax},
	 131  	{"1_01", 2, 0, ErrSyntax},
	 132  	{"10_1", 2, 0, ErrSyntax},
	 133  	{"101_", 2, 0, ErrSyntax},
	 134  }
	 135  
	 136  type parseInt64Test struct {
	 137  	in	string
	 138  	out int64
	 139  	err error
	 140  }
	 141  
	 142  var parseInt64Tests = []parseInt64Test{
	 143  	{"", 0, ErrSyntax},
	 144  	{"0", 0, nil},
	 145  	{"-0", 0, nil},
	 146  	{"+0", 0, nil},
	 147  	{"1", 1, nil},
	 148  	{"-1", -1, nil},
	 149  	{"+1", 1, nil},
	 150  	{"12345", 12345, nil},
	 151  	{"-12345", -12345, nil},
	 152  	{"012345", 12345, nil},
	 153  	{"-012345", -12345, nil},
	 154  	{"98765432100", 98765432100, nil},
	 155  	{"-98765432100", -98765432100, nil},
	 156  	{"9223372036854775807", 1<<63 - 1, nil},
	 157  	{"-9223372036854775807", -(1<<63 - 1), nil},
	 158  	{"9223372036854775808", 1<<63 - 1, ErrRange},
	 159  	{"-9223372036854775808", -1 << 63, nil},
	 160  	{"9223372036854775809", 1<<63 - 1, ErrRange},
	 161  	{"-9223372036854775809", -1 << 63, ErrRange},
	 162  	{"-1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
	 163  	{"-_12345", 0, ErrSyntax},
	 164  	{"_12345", 0, ErrSyntax},
	 165  	{"1__2345", 0, ErrSyntax},
	 166  	{"12345_", 0, ErrSyntax},
	 167  }
	 168  
	 169  type parseInt64BaseTest struct {
	 170  	in	 string
	 171  	base int
	 172  	out	int64
	 173  	err	error
	 174  }
	 175  
	 176  var parseInt64BaseTests = []parseInt64BaseTest{
	 177  	{"", 0, 0, ErrSyntax},
	 178  	{"0", 0, 0, nil},
	 179  	{"-0", 0, 0, nil},
	 180  	{"1", 0, 1, nil},
	 181  	{"-1", 0, -1, nil},
	 182  	{"12345", 0, 12345, nil},
	 183  	{"-12345", 0, -12345, nil},
	 184  	{"012345", 0, 012345, nil},
	 185  	{"-012345", 0, -012345, nil},
	 186  	{"0x12345", 0, 0x12345, nil},
	 187  	{"-0X12345", 0, -0x12345, nil},
	 188  	{"12345x", 0, 0, ErrSyntax},
	 189  	{"-12345x", 0, 0, ErrSyntax},
	 190  	{"98765432100", 0, 98765432100, nil},
	 191  	{"-98765432100", 0, -98765432100, nil},
	 192  	{"9223372036854775807", 0, 1<<63 - 1, nil},
	 193  	{"-9223372036854775807", 0, -(1<<63 - 1), nil},
	 194  	{"9223372036854775808", 0, 1<<63 - 1, ErrRange},
	 195  	{"-9223372036854775808", 0, -1 << 63, nil},
	 196  	{"9223372036854775809", 0, 1<<63 - 1, ErrRange},
	 197  	{"-9223372036854775809", 0, -1 << 63, ErrRange},
	 198  
	 199  	// other bases
	 200  	{"g", 17, 16, nil},
	 201  	{"10", 25, 25, nil},
	 202  	{"holycow", 35, (((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, nil},
	 203  	{"holycow", 36, (((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, nil},
	 204  
	 205  	// base 2
	 206  	{"0", 2, 0, nil},
	 207  	{"-1", 2, -1, nil},
	 208  	{"1010", 2, 10, nil},
	 209  	{"1000000000000000", 2, 1 << 15, nil},
	 210  	{"111111111111111111111111111111111111111111111111111111111111111", 2, 1<<63 - 1, nil},
	 211  	{"1000000000000000000000000000000000000000000000000000000000000000", 2, 1<<63 - 1, ErrRange},
	 212  	{"-1000000000000000000000000000000000000000000000000000000000000000", 2, -1 << 63, nil},
	 213  	{"-1000000000000000000000000000000000000000000000000000000000000001", 2, -1 << 63, ErrRange},
	 214  
	 215  	// base 8
	 216  	{"-10", 8, -8, nil},
	 217  	{"57635436545", 8, 057635436545, nil},
	 218  	{"100000000", 8, 1 << 24, nil},
	 219  
	 220  	// base 16
	 221  	{"10", 16, 16, nil},
	 222  	{"-123456789abcdef", 16, -0x123456789abcdef, nil},
	 223  	{"7fffffffffffffff", 16, 1<<63 - 1, nil},
	 224  
	 225  	// underscores
	 226  	{"-0x_1_2_3_4_5", 0, -0x12345, nil},
	 227  	{"0x_1_2_3_4_5", 0, 0x12345, nil},
	 228  	{"-_0x12345", 0, 0, ErrSyntax},
	 229  	{"_-0x12345", 0, 0, ErrSyntax},
	 230  	{"_0x12345", 0, 0, ErrSyntax},
	 231  	{"0x__12345", 0, 0, ErrSyntax},
	 232  	{"0x1__2345", 0, 0, ErrSyntax},
	 233  	{"0x1234__5", 0, 0, ErrSyntax},
	 234  	{"0x12345_", 0, 0, ErrSyntax},
	 235  
	 236  	{"-0_1_2_3_4_5", 0, -012345, nil}, // octal
	 237  	{"0_1_2_3_4_5", 0, 012345, nil},	 // octal
	 238  	{"-_012345", 0, 0, ErrSyntax},
	 239  	{"_-012345", 0, 0, ErrSyntax},
	 240  	{"_012345", 0, 0, ErrSyntax},
	 241  	{"0__12345", 0, 0, ErrSyntax},
	 242  	{"01234__5", 0, 0, ErrSyntax},
	 243  	{"012345_", 0, 0, ErrSyntax},
	 244  
	 245  	{"+0xf", 0, 0xf, nil},
	 246  	{"-0xf", 0, -0xf, nil},
	 247  	{"0x+f", 0, 0, ErrSyntax},
	 248  	{"0x-f", 0, 0, ErrSyntax},
	 249  }
	 250  
	 251  type parseUint32Test struct {
	 252  	in	string
	 253  	out uint32
	 254  	err error
	 255  }
	 256  
	 257  var parseUint32Tests = []parseUint32Test{
	 258  	{"", 0, ErrSyntax},
	 259  	{"0", 0, nil},
	 260  	{"1", 1, nil},
	 261  	{"12345", 12345, nil},
	 262  	{"012345", 12345, nil},
	 263  	{"12345x", 0, ErrSyntax},
	 264  	{"987654321", 987654321, nil},
	 265  	{"4294967295", 1<<32 - 1, nil},
	 266  	{"4294967296", 1<<32 - 1, ErrRange},
	 267  	{"1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
	 268  	{"_12345", 0, ErrSyntax},
	 269  	{"_12345", 0, ErrSyntax},
	 270  	{"1__2345", 0, ErrSyntax},
	 271  	{"12345_", 0, ErrSyntax},
	 272  }
	 273  
	 274  type parseInt32Test struct {
	 275  	in	string
	 276  	out int32
	 277  	err error
	 278  }
	 279  
	 280  var parseInt32Tests = []parseInt32Test{
	 281  	{"", 0, ErrSyntax},
	 282  	{"0", 0, nil},
	 283  	{"-0", 0, nil},
	 284  	{"1", 1, nil},
	 285  	{"-1", -1, nil},
	 286  	{"12345", 12345, nil},
	 287  	{"-12345", -12345, nil},
	 288  	{"012345", 12345, nil},
	 289  	{"-012345", -12345, nil},
	 290  	{"12345x", 0, ErrSyntax},
	 291  	{"-12345x", 0, ErrSyntax},
	 292  	{"987654321", 987654321, nil},
	 293  	{"-987654321", -987654321, nil},
	 294  	{"2147483647", 1<<31 - 1, nil},
	 295  	{"-2147483647", -(1<<31 - 1), nil},
	 296  	{"2147483648", 1<<31 - 1, ErrRange},
	 297  	{"-2147483648", -1 << 31, nil},
	 298  	{"2147483649", 1<<31 - 1, ErrRange},
	 299  	{"-2147483649", -1 << 31, ErrRange},
	 300  	{"-1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
	 301  	{"-_12345", 0, ErrSyntax},
	 302  	{"_12345", 0, ErrSyntax},
	 303  	{"1__2345", 0, ErrSyntax},
	 304  	{"12345_", 0, ErrSyntax},
	 305  }
	 306  
	 307  type numErrorTest struct {
	 308  	num, want string
	 309  }
	 310  
	 311  var numErrorTests = []numErrorTest{
	 312  	{"0", `strconv.ParseFloat: parsing "0": failed`},
	 313  	{"`", "strconv.ParseFloat: parsing \"`\": failed"},
	 314  	{"1\x00.2", `strconv.ParseFloat: parsing "1\x00.2": failed`},
	 315  }
	 316  
	 317  func init() {
	 318  	// The parse routines return NumErrors wrapping
	 319  	// the error and the string. Convert the tables above.
	 320  	for i := range parseUint64Tests {
	 321  		test := &parseUint64Tests[i]
	 322  		if test.err != nil {
	 323  			test.err = &NumError{"ParseUint", test.in, test.err}
	 324  		}
	 325  	}
	 326  	for i := range parseUint64BaseTests {
	 327  		test := &parseUint64BaseTests[i]
	 328  		if test.err != nil {
	 329  			test.err = &NumError{"ParseUint", test.in, test.err}
	 330  		}
	 331  	}
	 332  	for i := range parseInt64Tests {
	 333  		test := &parseInt64Tests[i]
	 334  		if test.err != nil {
	 335  			test.err = &NumError{"ParseInt", test.in, test.err}
	 336  		}
	 337  	}
	 338  	for i := range parseInt64BaseTests {
	 339  		test := &parseInt64BaseTests[i]
	 340  		if test.err != nil {
	 341  			test.err = &NumError{"ParseInt", test.in, test.err}
	 342  		}
	 343  	}
	 344  	for i := range parseUint32Tests {
	 345  		test := &parseUint32Tests[i]
	 346  		if test.err != nil {
	 347  			test.err = &NumError{"ParseUint", test.in, test.err}
	 348  		}
	 349  	}
	 350  	for i := range parseInt32Tests {
	 351  		test := &parseInt32Tests[i]
	 352  		if test.err != nil {
	 353  			test.err = &NumError{"ParseInt", test.in, test.err}
	 354  		}
	 355  	}
	 356  }
	 357  
	 358  func TestParseUint32(t *testing.T) {
	 359  	for i := range parseUint32Tests {
	 360  		test := &parseUint32Tests[i]
	 361  		out, err := ParseUint(test.in, 10, 32)
	 362  		if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
	 363  			t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
	 364  				test.in, out, err, test.out, test.err)
	 365  		}
	 366  	}
	 367  }
	 368  
	 369  func TestParseUint64(t *testing.T) {
	 370  	for i := range parseUint64Tests {
	 371  		test := &parseUint64Tests[i]
	 372  		out, err := ParseUint(test.in, 10, 64)
	 373  		if test.out != out || !reflect.DeepEqual(test.err, err) {
	 374  			t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
	 375  				test.in, out, err, test.out, test.err)
	 376  		}
	 377  	}
	 378  }
	 379  
	 380  func TestParseUint64Base(t *testing.T) {
	 381  	for i := range parseUint64BaseTests {
	 382  		test := &parseUint64BaseTests[i]
	 383  		out, err := ParseUint(test.in, test.base, 64)
	 384  		if test.out != out || !reflect.DeepEqual(test.err, err) {
	 385  			t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
	 386  				test.in, test.base, out, err, test.out, test.err)
	 387  		}
	 388  	}
	 389  }
	 390  
	 391  func TestParseInt32(t *testing.T) {
	 392  	for i := range parseInt32Tests {
	 393  		test := &parseInt32Tests[i]
	 394  		out, err := ParseInt(test.in, 10, 32)
	 395  		if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
	 396  			t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
	 397  				test.in, out, err, test.out, test.err)
	 398  		}
	 399  	}
	 400  }
	 401  
	 402  func TestParseInt64(t *testing.T) {
	 403  	for i := range parseInt64Tests {
	 404  		test := &parseInt64Tests[i]
	 405  		out, err := ParseInt(test.in, 10, 64)
	 406  		if test.out != out || !reflect.DeepEqual(test.err, err) {
	 407  			t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
	 408  				test.in, out, err, test.out, test.err)
	 409  		}
	 410  	}
	 411  }
	 412  
	 413  func TestParseInt64Base(t *testing.T) {
	 414  	for i := range parseInt64BaseTests {
	 415  		test := &parseInt64BaseTests[i]
	 416  		out, err := ParseInt(test.in, test.base, 64)
	 417  		if test.out != out || !reflect.DeepEqual(test.err, err) {
	 418  			t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
	 419  				test.in, test.base, out, err, test.out, test.err)
	 420  		}
	 421  	}
	 422  }
	 423  
	 424  func TestParseUint(t *testing.T) {
	 425  	switch IntSize {
	 426  	case 32:
	 427  		for i := range parseUint32Tests {
	 428  			test := &parseUint32Tests[i]
	 429  			out, err := ParseUint(test.in, 10, 0)
	 430  			if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
	 431  				t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
	 432  					test.in, out, err, test.out, test.err)
	 433  			}
	 434  		}
	 435  	case 64:
	 436  		for i := range parseUint64Tests {
	 437  			test := &parseUint64Tests[i]
	 438  			out, err := ParseUint(test.in, 10, 0)
	 439  			if test.out != out || !reflect.DeepEqual(test.err, err) {
	 440  				t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
	 441  					test.in, out, err, test.out, test.err)
	 442  			}
	 443  		}
	 444  	}
	 445  }
	 446  
	 447  func TestParseInt(t *testing.T) {
	 448  	switch IntSize {
	 449  	case 32:
	 450  		for i := range parseInt32Tests {
	 451  			test := &parseInt32Tests[i]
	 452  			out, err := ParseInt(test.in, 10, 0)
	 453  			if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
	 454  				t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
	 455  					test.in, out, err, test.out, test.err)
	 456  			}
	 457  		}
	 458  	case 64:
	 459  		for i := range parseInt64Tests {
	 460  			test := &parseInt64Tests[i]
	 461  			out, err := ParseInt(test.in, 10, 0)
	 462  			if test.out != out || !reflect.DeepEqual(test.err, err) {
	 463  				t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
	 464  					test.in, out, err, test.out, test.err)
	 465  			}
	 466  		}
	 467  	}
	 468  }
	 469  
	 470  func TestAtoi(t *testing.T) {
	 471  	switch IntSize {
	 472  	case 32:
	 473  		for i := range parseInt32Tests {
	 474  			test := &parseInt32Tests[i]
	 475  			out, err := Atoi(test.in)
	 476  			var testErr error
	 477  			if test.err != nil {
	 478  				testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
	 479  			}
	 480  			if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
	 481  				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
	 482  					test.in, out, err, test.out, testErr)
	 483  			}
	 484  		}
	 485  	case 64:
	 486  		for i := range parseInt64Tests {
	 487  			test := &parseInt64Tests[i]
	 488  			out, err := Atoi(test.in)
	 489  			var testErr error
	 490  			if test.err != nil {
	 491  				testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
	 492  			}
	 493  			if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
	 494  				t.Errorf("Atoi(%q) = %v, %v want %v, %v",
	 495  					test.in, out, err, test.out, testErr)
	 496  			}
	 497  		}
	 498  	}
	 499  }
	 500  
	 501  func bitSizeErrStub(name string, bitSize int) error {
	 502  	return BitSizeError(name, "0", bitSize)
	 503  }
	 504  
	 505  func baseErrStub(name string, base int) error {
	 506  	return BaseError(name, "0", base)
	 507  }
	 508  
	 509  func noErrStub(name string, arg int) error {
	 510  	return nil
	 511  }
	 512  
	 513  type parseErrorTest struct {
	 514  	arg		 int
	 515  	errStub func(name string, arg int) error
	 516  }
	 517  
	 518  var parseBitSizeTests = []parseErrorTest{
	 519  	{-1, bitSizeErrStub},
	 520  	{0, noErrStub},
	 521  	{64, noErrStub},
	 522  	{65, bitSizeErrStub},
	 523  }
	 524  
	 525  var parseBaseTests = []parseErrorTest{
	 526  	{-1, baseErrStub},
	 527  	{0, noErrStub},
	 528  	{1, baseErrStub},
	 529  	{2, noErrStub},
	 530  	{36, noErrStub},
	 531  	{37, baseErrStub},
	 532  }
	 533  
	 534  func equalError(a, b error) bool {
	 535  	if a == nil {
	 536  		return b == nil
	 537  	}
	 538  	if b == nil {
	 539  		return a == nil
	 540  	}
	 541  	return a.Error() == b.Error()
	 542  }
	 543  
	 544  func TestParseIntBitSize(t *testing.T) {
	 545  	for i := range parseBitSizeTests {
	 546  		test := &parseBitSizeTests[i]
	 547  		testErr := test.errStub("ParseInt", test.arg)
	 548  		_, err := ParseInt("0", 0, test.arg)
	 549  		if !equalError(testErr, err) {
	 550  			t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
	 551  				test.arg, err, testErr)
	 552  		}
	 553  	}
	 554  }
	 555  
	 556  func TestParseUintBitSize(t *testing.T) {
	 557  	for i := range parseBitSizeTests {
	 558  		test := &parseBitSizeTests[i]
	 559  		testErr := test.errStub("ParseUint", test.arg)
	 560  		_, err := ParseUint("0", 0, test.arg)
	 561  		if !equalError(testErr, err) {
	 562  			t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
	 563  				test.arg, err, testErr)
	 564  		}
	 565  	}
	 566  }
	 567  
	 568  func TestParseIntBase(t *testing.T) {
	 569  	for i := range parseBaseTests {
	 570  		test := &parseBaseTests[i]
	 571  		testErr := test.errStub("ParseInt", test.arg)
	 572  		_, err := ParseInt("0", test.arg, 0)
	 573  		if !equalError(testErr, err) {
	 574  			t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
	 575  				test.arg, err, testErr)
	 576  		}
	 577  	}
	 578  }
	 579  
	 580  func TestParseUintBase(t *testing.T) {
	 581  	for i := range parseBaseTests {
	 582  		test := &parseBaseTests[i]
	 583  		testErr := test.errStub("ParseUint", test.arg)
	 584  		_, err := ParseUint("0", test.arg, 0)
	 585  		if !equalError(testErr, err) {
	 586  			t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
	 587  				test.arg, err, testErr)
	 588  		}
	 589  	}
	 590  }
	 591  
	 592  func TestNumError(t *testing.T) {
	 593  	for _, test := range numErrorTests {
	 594  		err := &NumError{
	 595  			Func: "ParseFloat",
	 596  			Num:	test.num,
	 597  			Err:	errors.New("failed"),
	 598  		}
	 599  		if got := err.Error(); got != test.want {
	 600  			t.Errorf(`(&NumError{"ParseFloat", %q, "failed"}).Error() = %v, want %v`, test.num, got, test.want)
	 601  		}
	 602  	}
	 603  }
	 604  
	 605  func TestNumErrorUnwrap(t *testing.T) {
	 606  	err := &NumError{Err: ErrSyntax}
	 607  	if !errors.Is(err, ErrSyntax) {
	 608  		t.Error("errors.Is failed, wanted success")
	 609  	}
	 610  }
	 611  
	 612  func BenchmarkParseInt(b *testing.B) {
	 613  	b.Run("Pos", func(b *testing.B) {
	 614  		benchmarkParseInt(b, 1)
	 615  	})
	 616  	b.Run("Neg", func(b *testing.B) {
	 617  		benchmarkParseInt(b, -1)
	 618  	})
	 619  }
	 620  
	 621  type benchCase struct {
	 622  	name string
	 623  	num	int64
	 624  }
	 625  
	 626  func benchmarkParseInt(b *testing.B, neg int) {
	 627  	cases := []benchCase{
	 628  		{"7bit", 1<<7 - 1},
	 629  		{"26bit", 1<<26 - 1},
	 630  		{"31bit", 1<<31 - 1},
	 631  		{"56bit", 1<<56 - 1},
	 632  		{"63bit", 1<<63 - 1},
	 633  	}
	 634  	for _, cs := range cases {
	 635  		b.Run(cs.name, func(b *testing.B) {
	 636  			s := fmt.Sprintf("%d", cs.num*int64(neg))
	 637  			for i := 0; i < b.N; i++ {
	 638  				out, _ := ParseInt(s, 10, 64)
	 639  				BenchSink += int(out)
	 640  			}
	 641  		})
	 642  	}
	 643  }
	 644  
	 645  func BenchmarkAtoi(b *testing.B) {
	 646  	b.Run("Pos", func(b *testing.B) {
	 647  		benchmarkAtoi(b, 1)
	 648  	})
	 649  	b.Run("Neg", func(b *testing.B) {
	 650  		benchmarkAtoi(b, -1)
	 651  	})
	 652  }
	 653  
	 654  func benchmarkAtoi(b *testing.B, neg int) {
	 655  	cases := []benchCase{
	 656  		{"7bit", 1<<7 - 1},
	 657  		{"26bit", 1<<26 - 1},
	 658  		{"31bit", 1<<31 - 1},
	 659  	}
	 660  	if IntSize == 64 {
	 661  		cases = append(cases, []benchCase{
	 662  			{"56bit", 1<<56 - 1},
	 663  			{"63bit", 1<<63 - 1},
	 664  		}...)
	 665  	}
	 666  	for _, cs := range cases {
	 667  		b.Run(cs.name, func(b *testing.B) {
	 668  			s := fmt.Sprintf("%d", cs.num*int64(neg))
	 669  			for i := 0; i < b.N; i++ {
	 670  				out, _ := Atoi(s)
	 671  				BenchSink += out
	 672  			}
	 673  		})
	 674  	}
	 675  }
	 676  

View as plain text