Skip to content

Commit

Permalink
test: few more examples for testing
Browse files Browse the repository at this point in the history
simplify errors a little bit
  • Loading branch information
howeyc committed Nov 10, 2023
1 parent d3041fc commit 95dad56
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 27 deletions.
36 changes: 19 additions & 17 deletions decimal/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,34 @@ func NewFromInt(i int64) Decimal {
return Decimal(i) * scaleFactor
}

var errEmpty = errors.New("empty string")
var errTooBig = errors.New("number too big")
var errInvalid = errors.New("invalid syntax")

// atoi64 is equivalent to strconv.Atoi
func atoi64(s string) (bool, int64, error) {
sLen := len(s)
if sLen < 1 || sLen > 18 {
return false, 0, errors.New("atoi failed")
if sLen < 1 {
return false, 0, errEmpty
}
if sLen > 18 {
return false, 0, errTooBig
}

neg := false
if s[0] == '-' {
neg = true
s = s[1:]
if len(s) < 1 {
return false, 0, errors.New("atoi failed")
return neg, 0, errEmpty
}
}

var n int64
for _, ch := range []byte(s) {
ch -= '0'
if ch > 9 {
return false, 0, errors.New("atoi failed")
return neg, 0, errInvalid
}
n = n*10 + int64(ch)
}
Expand All @@ -82,21 +90,15 @@ func atoi64(s string) (bool, int64, error) {
// error if integer parsing fails.
func NewFromString(s string) (Decimal, error) {
if whole, frac, split := strings.Cut(s, "."); split {
var neg bool
var w int64
if whole == "-" {
neg = true
} else if whole != "" {
var err error
neg, w, err = atoi64(whole)
if err != nil {
return Zero, err
}
neg, w, err := atoi64(whole)
// if fractional portion exists, whole part can be empty
if err != nil && err != errEmpty {
return Zero, err
}

// overflow
if w > parseMax || w < parseMin {
return Zero, errors.New("number too big")
return Zero, errTooBig
}
w = w * int64(scaleFactor)

Expand All @@ -106,7 +108,7 @@ func NewFromString(s string) (Decimal, error) {
for _, b := range frac {
f *= 10
if b < '0' || b > '9' {
return Zero, errors.New("invalid syntax")
return Zero, errInvalid
}
f += int64(b - '0')
seen++
Expand All @@ -126,7 +128,7 @@ func NewFromString(s string) (Decimal, error) {
} else {
_, i, err := atoi64(s)
if i > parseMax || i < parseMin {
return Zero, errors.New("number too big")
return Zero, errTooBig
}
i = i * int64(scaleFactor)
return Decimal(i), err
Expand Down
38 changes: 28 additions & 10 deletions decimal/decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,47 +298,47 @@ var testParseCases = []testCase{
},
{
"error-1",
"number too big",
errTooBig.Error(),
"100000000000000000",
},
{
"error-2",
"number too big",
errTooBig.Error(),
"10000000000000000",
},
{
"error-3",
"number too big",
errTooBig.Error(),
"10000000000000000.56",
},
{
"error-4",
"invalid syntax",
errInvalid.Error(),
"0.e0",
},
{
"error-5",
"atoi failed",
errTooBig.Error(),
"5555555555555555555555555550000000000000000",
},
{
"error-6",
"atoi failed",
errEmpty.Error(),
"-",
},
{
"error-7",
"atoi failed",
errEmpty.Error(),
"",
},
{
"error-badint-1",
`atoi failed`,
errInvalid.Error(),
"1QZ.56",
},
{
"error-expr-1",
`atoi failed`,
errInvalid.Error(),
"(123 * 6)",
},
{
Expand All @@ -351,6 +351,21 @@ var testParseCases = []testCase{
"-0.50",
"-.50",
},
{
"missingfrac",
"5.00",
"5.",
},
{
"neg-missingfrac",
"-5.00",
"-5.",
},
{
"just-a-decimal",
"0.00",
".",
},
}

func TestStringParse(t *testing.T) {
Expand All @@ -364,6 +379,9 @@ func TestStringParse(t *testing.T) {
t.Fatalf("Error(%s): expected `%s`, got `%s`", tc.name, tc.Result, err)
}
}
if !strings.HasPrefix(tc.name, "error") && err != nil {
t.Fatalf("Error(%s): unexpected error `%s`", tc.name, err)
}
if !strings.HasPrefix(tc.name, "error") && tc.Result != d.StringFixedBank() {
t.Errorf("Error(%s): expected \n`%s`, \ngot \n`%s`", tc.name, tc.Result, d.StringFixedBank())
}
Expand Down Expand Up @@ -395,7 +413,7 @@ func FuzzStringParse(f *testing.F) {
}

func BenchmarkNewFromString(b *testing.B) {
numbers := []string{"10.0", "245.6", "354", "2.456"}
numbers := []string{"10.0", "245.6", "354", "2.456", "-31.2"}
for n := 0; n < b.N; n++ {
for _, numStr := range numbers {
NewFromString(numStr)
Expand Down

0 comments on commit 95dad56

Please sign in to comment.