Commit c1a8e6f5 authored by David Vorick's avatar David Vorick

100% currency type test coverage

parent 9e32fd16
......@@ -34,10 +34,10 @@ type Currency struct {
func NewCurrency(b *big.Int) (c Currency) {
c.i = *b
if c.Cmp(ZeroCurrency) < 0 {
c = Currency{}
if DEBUG {
panic("cannot have a negative currency")
}
c = Currency{}
}
return
}
......@@ -85,14 +85,13 @@ func (c Currency) MulFloat(x float64) (y Currency) {
if DEBUG {
panic("cannot multiple currency by a negative number")
}
return
} else {
yRat := new(big.Rat).Mul(
new(big.Rat).SetInt(&c.i),
new(big.Rat).SetFloat64(x),
)
y.i.Div(yRat.Num(), yRat.Denom())
}
yRat := new(big.Rat).Mul(
new(big.Rat).SetInt(&c.i),
new(big.Rat).SetFloat64(x),
)
y.i.Div(yRat.Num(), yRat.Denom())
return
}
......@@ -112,17 +111,18 @@ func (c Currency) Sqrt() (y Currency) {
return
}
// Sub returns a new Currency value y = c - x.
func (c Currency) Sub(x Currency) Currency {
var y Currency
y.i.Sub(&c.i, &x.i)
if y.Cmp(ZeroCurrency) < 0 {
// Sub returns a new Currency value y = c - x. Behavior is undefined when
// c < x.
func (c Currency) Sub(x Currency) (y Currency) {
if c.Cmp(x) < 0 {
y = c
if DEBUG {
panic("subtraction resulted in negative currency")
}
return x
} else {
y.i.Sub(&c.i, &x.i)
}
return y
return
}
// MarshalJSON implements the json.Marshaler interface.
......@@ -170,7 +170,7 @@ func (c *Currency) Scan(s fmt.ScanState, ch rune) error {
return err
}
if c.Cmp(ZeroCurrency) < 0 {
return errors.New("cannot have a negative currency")
return ErrNegativeCurrency
}
return nil
}
......@@ -2,6 +2,7 @@ package consensus
import (
"bytes"
"fmt"
"math/big"
"testing"
)
......@@ -17,6 +18,23 @@ func TestCurrencyToBig(t *testing.T) {
}
}
// TestCurrencyDiv checks that the div function has been correctly implemented.
func TestCurrencyDiv(t *testing.T) {
c9 := NewCurrency64(9)
c10 := NewCurrency64(10)
c90 := NewCurrency64(90)
c97 := NewCurrency64(97)
c90D10 := c90.Div(c10)
if c90D10.Cmp(c9) != 0 {
t.Error("Dividing 90 by 10 should produce 9")
}
c97D10 := c97.Div(c10)
if c97D10.Cmp(c9) != 0 {
t.Error("Dividing 97 by 10 should produce 9")
}
}
// TestCurrencySqrt checks that the sqrt function of the currency type has been
// correctly implemented.
func TestCurrencySqrt(t *testing.T) {
......@@ -34,8 +52,9 @@ func TestCurrencySqrt(t *testing.T) {
}
}
// TestMarshalJSON probes the MarshalJSON and UnmarshalJSON functions.
func TestMarshalJSON(t *testing.T) {
// TestCurrencyMarshalJSON probes the MarshalJSON and UnmarshalJSON functions
// of the currency type.
func TestCurrencyMarshalJSON(t *testing.T) {
b30 := big.NewInt(30)
c30 := NewCurrency64(30)
......@@ -59,10 +78,17 @@ func TestMarshalJSON(t *testing.T) {
if c30.Cmp(cUmar30) != 0 {
t.Error("Incorrect unmarshalling of currency type.")
}
cMar30[0] = 0
err = cUmar30.UnmarshalJSON(cMar30)
if err == nil {
t.Error("JSON decoded nonsense input")
}
}
// TestMarshalSia probes the MarshalSia and UnmarshalSia functions.
func TestMarshalSia(t *testing.T) {
// TestCurrencyMarshalSia probes the MarshalSia and UnmarshalSia functions of
// the currency type.
func TestCurrencyMarshalSia(t *testing.T) {
c := NewCurrency64(1656)
cMar := c.MarshalSia()
var cUmar Currency
......@@ -72,6 +98,32 @@ func TestMarshalSia(t *testing.T) {
}
}
// TestCurrencyString probes the String function of the currency type.
func TestCurrencyString(t *testing.T) {
b := big.NewInt(7135)
c := NewCurrency64(7135)
if b.String() != c.String() {
t.Error("string function not behaving as expected")
}
}
// TestCurrencyScan probes the Scan function of the currency type.
func TestCurrencyScan(t *testing.T) {
var c0 Currency
c1 := NewCurrency64(81293)
_, err := fmt.Sscan("81293", &c0)
if err != nil {
t.Fatal(err)
}
if c0.Cmp(c1) != 0 {
t.Error("scanned number does not equal expected value")
}
_, err = fmt.Sscan("z", &c0)
if err == nil {
t.Fatal("scan is accepting garbage input")
}
}
// TestNegativeCurrencyMulFloat checks that negative numbers are rejected when
// calling MulFloat on the currency type.
func TestNegativeCurrencyMulFloat(t *testing.T) {
......@@ -127,6 +179,16 @@ func TestNegativeCurrencyUnmarshalJSON(t *testing.T) {
}
}
// TestNegativeCurrencyScan tries to scan in a negative number and checks for
// an error.
func TestNegativeCurrencyScan(t *testing.T) {
var c Currency
_, err := fmt.Sscan("-23", &c)
if err != ErrNegativeCurrency {
t.Error("expecting ErrNegativeCurrency:", err)
}
}
// TestNegativeCurrencies tries an array of ways to produce a negative currency.
func TestNegativeNewCurrency(t *testing.T) {
// In debug mode, attempting to get a negative currency results in a panic.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment