mirror of
https://github.com/aclindsa/moneygo.git
synced 2024-11-01 00:10:06 -04:00
Aaron Lindsay
a357d38eee
This adds 'shadow' types used only by the store/db internal package whch handle converting these types to their DB-equivalent values. This change should allow reports to be generated significantly faster since it allows a large portion of the computation to be shifted to the database engines.
160 lines
3.9 KiB
Go
160 lines
3.9 KiB
Go
package models_test
|
|
|
|
import (
|
|
"github.com/aclindsa/moneygo/internal/models"
|
|
"testing"
|
|
)
|
|
|
|
func expectedPrecision(t *testing.T, amount *models.Amount, precision uint64) {
|
|
t.Helper()
|
|
if amount.Precision() != precision {
|
|
t.Errorf("Expected precision %d for %s, found %d", precision, amount.String(), amount.Precision())
|
|
}
|
|
}
|
|
|
|
func TestAmountPrecision(t *testing.T) {
|
|
var a models.Amount
|
|
a.SetString("1.1928712")
|
|
expectedPrecision(t, &a, 7)
|
|
a.SetString("0")
|
|
expectedPrecision(t, &a, 0)
|
|
a.SetString("-0.7")
|
|
expectedPrecision(t, &a, 1)
|
|
a.SetString("-1.1837281037509137509173049173052130957210361309572047598275398265926351231426357130289523647634895285603247284245928712")
|
|
expectedPrecision(t, &a, 118)
|
|
a.SetInt64(1050)
|
|
expectedPrecision(t, &a, 0)
|
|
}
|
|
|
|
func TestAmountRound(t *testing.T) {
|
|
var a models.Amount
|
|
tests := []struct {
|
|
String string
|
|
RoundTo uint64
|
|
Expected string
|
|
}{
|
|
{"0", 5, "0"},
|
|
{"929.92928", 2, "929.93"},
|
|
{"-105.499999", 4, "-105.5"},
|
|
{"0.5111111", 1, "0.5"},
|
|
{"0.5111111", 0, "1"},
|
|
{"9.876456", 3, "9.876"},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
a.SetString(test.String)
|
|
a.Round(test.RoundTo)
|
|
if a.String() != test.Expected {
|
|
t.Errorf("Expected '%s' after Round(%d) to be %s intead of %s\n", test.String, test.RoundTo, test.Expected, a.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAmountString(t *testing.T) {
|
|
var a models.Amount
|
|
for _, s := range []string{
|
|
"1.1928712",
|
|
"0",
|
|
"-0.7",
|
|
"-1.1837281037509137509173049173052130957210361309572047598275398265926351231426357130289523647634895285603247284245928712",
|
|
"1050",
|
|
} {
|
|
a.SetString(s)
|
|
if s != a.String() {
|
|
t.Errorf("Expected '%s', found '%s'", s, a.String())
|
|
}
|
|
}
|
|
|
|
a.SetString("+182.27")
|
|
if "182.27" != a.String() {
|
|
t.Errorf("Expected '182.27', found '%s'", a.String())
|
|
}
|
|
a.SetString("-0")
|
|
if "0" != a.String() {
|
|
t.Errorf("Expected '0', found '%s'", a.String())
|
|
}
|
|
}
|
|
|
|
func TestWhole(t *testing.T) {
|
|
var a models.Amount
|
|
tests := []struct {
|
|
String string
|
|
Whole int64
|
|
}{
|
|
{"0", 0},
|
|
{"-0", 0},
|
|
{"181.1293871230", 181},
|
|
{"-0.1821", 0},
|
|
{"99992737.9", 99992737},
|
|
{"-7380.000009", -7380},
|
|
{"4108740192740912741", 4108740192740912741},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
a.SetString(test.String)
|
|
val, err := a.Whole()
|
|
if err != nil {
|
|
t.Errorf("Unexpected error: %s\n", err)
|
|
} else if val != test.Whole {
|
|
t.Errorf("Expected '%s'.Whole() to return %d intead of %d\n", test.String, test.Whole, val)
|
|
}
|
|
}
|
|
|
|
a.SetString("81367662642302823790328492349823472634926342")
|
|
_, err := a.Whole()
|
|
if err == nil {
|
|
t.Errorf("Expected error for overflowing int64")
|
|
}
|
|
}
|
|
|
|
func TestFractional(t *testing.T) {
|
|
var a models.Amount
|
|
tests := []struct {
|
|
String string
|
|
Precision uint64
|
|
Fractional int64
|
|
}{
|
|
{"0", 5, 0},
|
|
{"181.1293871230", 9, 129387123},
|
|
{"181.1293871230", 10, 1293871230},
|
|
{"181.1293871230", 15, 129387123000000},
|
|
{"1828.37", 7, 3700000},
|
|
{"-0.748", 5, -74800},
|
|
{"-9", 5, 0},
|
|
{"-9.9", 1, -9},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
a.SetString(test.String)
|
|
val, err := a.Fractional(test.Precision)
|
|
if err != nil {
|
|
t.Errorf("Unexpected error: %s\n", err)
|
|
} else if val != test.Fractional {
|
|
t.Errorf("Expected '%s'.Fractional(%d) to return %d intead of %d\n", test.String, test.Precision, test.Fractional, val)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFromParts(t *testing.T) {
|
|
var a models.Amount
|
|
tests := []struct {
|
|
Whole int64
|
|
Fractional int64
|
|
Precision uint64
|
|
Result string
|
|
}{
|
|
{839, 9080, 4, "839.908"},
|
|
{-10, 0, 5, "-10"},
|
|
{0, 900, 10, "0.00000009"},
|
|
{9128713621, 87272727, 20, "9128713621.00000000000087272727"},
|
|
{89, 1, 0, "90"}, // Not sure if this should really be supported, but it is
|
|
}
|
|
|
|
for _, test := range tests {
|
|
a.FromParts(test.Whole, test.Fractional, test.Precision)
|
|
if a.String() != test.Result {
|
|
t.Errorf("Expected Amount.FromParts(%d, %d, %d) to return %s intead of %s\n", test.Whole, test.Fractional, test.Precision, test.Result, a.String())
|
|
}
|
|
}
|
|
}
|