featurebase/pql/decimal_test.go
2020-04-01 11:10:33 -05:00

164 lines
5.3 KiB
Go

// Copyright 2017 Pilosa Corp.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package pql_test
import (
"strings"
"testing"
"github.com/pilosa/pilosa/v2/pql"
)
// Ensure call can be converted into a string.
func TestDecimal(t *testing.T) {
t.Run("Parse", func(t *testing.T) {
tests := []struct {
s string
exp pql.Decimal
expErr string
}{
{"0", pql.Decimal{0, 0}, ""},
{"-0", pql.Decimal{0, 0}, ""},
{"0.0", pql.Decimal{0, 0}, ""},
{"-0.00", pql.Decimal{0, 0}, ""},
{"123.4567", pql.Decimal{1234567, 4}, ""},
{" 123.4567", pql.Decimal{1234567, 4}, ""},
{" 123.4567 ", pql.Decimal{1234567, 4}, ""},
{"123.456700", pql.Decimal{1234567, 4}, ""},
{"00123.4567", pql.Decimal{1234567, 4}, ""},
{"+123.4567", pql.Decimal{1234567, 4}, ""},
{"-123.4567", pql.Decimal{-1234567, 4}, ""},
{"-00123.4567", pql.Decimal{-1234567, 4}, ""},
{"-12.25", pql.Decimal{-1225, 2}, ""},
{"123", pql.Decimal{123, 0}, ""},
{"-12300", pql.Decimal{-123, -2}, ""},
{"+012300", pql.Decimal{123, -2}, ""},
{"12300", pql.Decimal{123, -2}, ""},
{"12300.", pql.Decimal{123, -2}, ""},
{"12300.0", pql.Decimal{123, -2}, ""},
{"123.0", pql.Decimal{123, 0}, ""},
{".123", pql.Decimal{123, 3}, ""},
{"0.123", pql.Decimal{123, 3}, ""},
{"0.001230", pql.Decimal{123, 5}, ""},
{" 0.001230 ", pql.Decimal{123, 5}, ""},
{"-0.001230 ", pql.Decimal{-123, 5}, ""},
// int64 edges.
{".000009223372036854775807", pql.Decimal{9223372036854775807, 24}, ""},
{"-.000009223372036854775807", pql.Decimal{-9223372036854775807, 24}, ""},
{"92233720368547.75807", pql.Decimal{9223372036854775807, 5}, ""},
{"-92233720368547.75807", pql.Decimal{-9223372036854775807, 5}, ""},
{"9223372036854775807000", pql.Decimal{9223372036854775807, -3}, ""},
{"-9223372036854775807000", pql.Decimal{-9223372036854775807, -3}, ""},
// Error cases.
{"", pql.Decimal{}, "decimal string is empty"},
{"-", pql.Decimal{}, "decimal string is empty"},
{"*0.123", pql.Decimal{}, "invalid syntax"},
{"abc", pql.Decimal{}, "invalid syntax"},
{"0.12.3", pql.Decimal{}, "invalid decimal string"},
{"--12300", pql.Decimal{}, "invalid negative value"},
{"922337203685477580.8", pql.Decimal{}, "value out of range"},
{"-922337203685477580.8", pql.Decimal{}, "value out of range"},
{"9223372036854775808000", pql.Decimal{}, "value out of range"},
{"-9223372036854775808000", pql.Decimal{}, "value out of range"},
}
for i, test := range tests {
dec, err := pql.ParseDecimal(test.s)
if test.expErr != "" {
if err == nil || !strings.Contains(err.Error(), test.expErr) {
t.Fatalf("test %d expected error to contain: %s, but got: %v", i, test.expErr, err)
}
} else if err != nil {
t.Fatalf("test %d parsing string `%s`: %s", i, test.s, err)
} else if dec != test.exp {
t.Fatalf("test %d expected: %v, but got: %v", i, test.exp, dec)
}
}
})
t.Run("ToInt64", func(t *testing.T) {
tests := []struct {
dec pql.Decimal
scale int64
exp int64
}{
{pql.Decimal{0, 0}, 0, 0}, // 0 : 0
{pql.Decimal{0, 0}, 1, 0}, // 0 : 0.0
{pql.Decimal{0, 0}, -1, 0}, // 0 : 0
{pql.Decimal{1234567, 4}, 5, 12345670}, // 123.4567 : 123.45670
{pql.Decimal{1234567, 4}, 4, 1234567}, // 123.4567 : 123.4567
{pql.Decimal{1234567, 4}, 3, 123456}, // 123.4567 : 123.456
{pql.Decimal{-1234567, 4}, 5, -12345670}, // -123.4567 : -123.45670
{pql.Decimal{-1234567, 4}, 4, -1234567}, // -123.4567 : -123.4567
{pql.Decimal{-1234567, 4}, 3, -123456}, // -123.4567 : -123.456
{pql.Decimal{123, -2}, 5, 1230000000}, // 12300 : 12300.00000
{pql.Decimal{123, -2}, -1, 1230}, // 12300 : 1230
{pql.Decimal{123, 1}, -1, 1}, // 12.3 : 1
{pql.Decimal{123, 1}, -2, 0}, // 12.3 : 0
}
for i, test := range tests {
v := test.dec.ToInt64(test.scale)
if v != test.exp {
t.Fatalf("test %d expected: %d, but got: %d", i, test.exp, v)
}
}
})
t.Run("String", func(t *testing.T) {
tests := []struct {
s string
exp string
}{
{"123.4567", "123.4567"},
{" 123.4567", "123.4567"},
{" 123.4567 ", "123.4567"},
{"123.456700", "123.4567"},
{"00123.4567", "123.4567"},
{"+123.4567", "123.4567"},
{"-123.4567", "-123.4567"},
{"-00123.4567", "-123.4567"},
{"-12.25", "-12.25"},
{"123", "123"},
{"-12300", "-12300"},
{"+012300", "12300"},
{"12300", "12300"},
{"12300.", "12300"},
{"12300.0", "12300"},
{"123.0", "123"},
{"0.123", "0.123"},
{"0.001230", "0.00123"},
{" 0.001230 ", "0.00123"},
{"-0.001230 ", "-0.00123"},
}
for i, test := range tests {
dec, err := pql.ParseDecimal(test.s)
if err != nil {
t.Fatalf("parsing string `%s`: %s", test.s, err)
}
if str := dec.String(); str != test.exp {
t.Fatalf("test %d expected: %s, but got: %s", i, test.exp, str)
}
}
})
}