From f80a9142d9becee2a884323e1a49e48c3804c446 Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Wed, 25 Jul 2018 11:47:07 +0200 Subject: [PATCH] Handle negative big.Int amounts, add tests of amounts parser --- bchain/baseparser.go | 21 +++++++++------ bchain/baseparser_test.go | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 bchain/baseparser_test.go diff --git a/bchain/baseparser.go b/bchain/baseparser.go index d8d04fef..ce6dc947 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -65,18 +65,23 @@ func (p *BaseParser) AmountToBigInt(n json.Number) (big.Int, error) { // AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place func (p *BaseParser) AmountToDecimalString(a *big.Int) string { - s := a.String() - if len(s) <= p.AmountDecimalPoint { - s = zeros[:p.AmountDecimalPoint-len(s)+1] + s + n := a.String() + var s string + if n[0] == '-' { + n = n[1:] + s = "-" } - i := len(s) - p.AmountDecimalPoint - ad := strings.TrimRight(s[i:], "0") + if len(n) <= p.AmountDecimalPoint { + n = zeros[:p.AmountDecimalPoint-len(n)+1] + n + } + i := len(n) - p.AmountDecimalPoint + ad := strings.TrimRight(n[i:], "0") if len(ad) > 0 { - s = s[:i] + "." + ad + n = n[:i] + "." + ad } else { - s = s[:i] + n = n[:i] } - return s + return s + n } // ParseTxFromJson parses JSON message containing transaction and returns Tx struct diff --git a/bchain/baseparser_test.go b/bchain/baseparser_test.go new file mode 100644 index 00000000..cfb20a68 --- /dev/null +++ b/bchain/baseparser_test.go @@ -0,0 +1,56 @@ +package bchain + +import ( + "encoding/json" + "math/big" + "testing" +) + +func NewBaseParser(adp int) *BaseParser { + return &BaseParser{ + AmountDecimalPoint: adp, + } +} + +var amounts = []struct { + a *big.Int + s string + adp int + alternative string +}{ + {big.NewInt(123456789), "1.23456789", 8, "!"}, + {big.NewInt(2), "0.00000002", 8, "!"}, + {big.NewInt(300000000), "3", 8, "!"}, + {big.NewInt(498700000), "4.987", 8, "!"}, + {big.NewInt(567890), "0.00000000000056789", 18, "!"}, + {big.NewInt(-100000000), "-1", 8, "!"}, + {big.NewInt(-8), "-0.00000008", 8, "!"}, + {big.NewInt(-89012345678), "-890.12345678", 8, "!"}, + {big.NewInt(-12345), "-0.00012345", 8, "!"}, + {big.NewInt(12345678), "0.123456789012", 8, "0.12345678"}, // test of truncation of too many decimal places +} + +func TestBaseParser_AmountToDecimalString(t *testing.T) { + for _, tt := range amounts { + t.Run(tt.s, func(t *testing.T) { + if got := NewBaseParser(tt.adp).AmountToDecimalString(tt.a); got != tt.s && got != tt.alternative { + t.Errorf("BaseParser.AmountToDecimalString() = %v, want %v", got, tt.s) + } + }) + } +} + +func TestBaseParser_AmountToBigInt(t *testing.T) { + for _, tt := range amounts { + t.Run(tt.s, func(t *testing.T) { + got, err := NewBaseParser(tt.adp).AmountToBigInt(json.Number(tt.s)) + if err != nil { + t.Errorf("BaseParser.AmountToBigInt() error = %v", err) + return + } + if got.Cmp(tt.a) != 0 { + t.Errorf("BaseParser.AmountToBigInt() = %v, want %v", got, tt.a) + } + }) + } +}