gitlab.com/jokerrs1/Sia@v1.3.2/types/currency_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math"
     5  	"math/big"
     6  	"testing"
     7  )
     8  
     9  // TestNewCurrency initializes a standard new currency.
    10  func TestNewCurrency(t *testing.T) {
    11  	b := big.NewInt(481)
    12  	c := NewCurrency(b)
    13  	if b.String() != c.String() {
    14  		t.Error("NewCurrency does't seem to work properly")
    15  	}
    16  }
    17  
    18  // TestCurrencyAdd probes the addition function of the currency type.
    19  func TestCurrencyAdd(t *testing.T) {
    20  	c7 := NewCurrency64(7)
    21  	c12 := NewCurrency64(12)
    22  	c19 := NewCurrency64(19)
    23  
    24  	if c7.Add(c12).Cmp(c19) != 0 {
    25  		t.Error("Add doesn't seem to work right")
    26  	}
    27  }
    28  
    29  // TestCurrencyToBig tests the Big method for the currency type
    30  func TestCurrencyToBig(t *testing.T) {
    31  	c := NewCurrency64(125)
    32  	cb := c.Big()
    33  	b := big.NewInt(125)
    34  
    35  	if b.Cmp(cb) != 0 {
    36  		t.Error("currency to big has failed")
    37  	}
    38  }
    39  
    40  // TestCurrencyCmp tests the Cmp method for the currency type
    41  func TestCurrencyCmp(t *testing.T) {
    42  	tests := []struct {
    43  		x, y Currency
    44  		exp  int
    45  	}{
    46  		{NewCurrency64(0), NewCurrency64(0), 0},
    47  		{NewCurrency64(0), NewCurrency64(1), -1},
    48  		{NewCurrency64(1), NewCurrency64(0), 1},
    49  		{NewCurrency64(100), NewCurrency64(7), 1},
    50  		{NewCurrency64(777), NewCurrency(big.NewInt(777)), 0},
    51  		{NewCurrency(big.NewInt(7)), NewCurrency(big.NewInt(8)), -1},
    52  	}
    53  
    54  	for _, test := range tests {
    55  		if c := test.x.Cmp(test.y); c != test.exp {
    56  			t.Errorf("expected %v.Cmp(%v) == %v, got %v", test.x, test.y, test.exp, c)
    57  		} else if bc := test.x.Big().Cmp(test.y.Big()); c != bc {
    58  			t.Errorf("Currency.Cmp (%v) does not match big.Int.Cmp (%v) for %v.Cmp(%v)", c, bc, test.x, test.y)
    59  		}
    60  	}
    61  }
    62  
    63  // TestCurrencyCmp64 tests the Cmp64 method for the currency type
    64  func TestCurrencyCmp64(t *testing.T) {
    65  	tests := []struct {
    66  		x   Currency
    67  		y   uint64
    68  		exp int
    69  	}{
    70  		{NewCurrency64(0), 0, 0},
    71  		{NewCurrency64(0), 1, -1},
    72  		{NewCurrency64(1), 0, 1},
    73  		{NewCurrency64(100), 7, 1},
    74  		{NewCurrency64(777), 777, 0},
    75  		{NewCurrency(big.NewInt(7)), 8, -1},
    76  	}
    77  
    78  	for _, test := range tests {
    79  		if c := test.x.Cmp64(test.y); c != test.exp {
    80  			t.Errorf("expected %v.Cmp64(%v) == %v, got %v", test.x, test.y, test.exp, c)
    81  		} else if bc := test.x.Big().Cmp(big.NewInt(int64(test.y))); c != bc {
    82  			t.Errorf("Currency.Cmp64 (%v) does not match big.Int.Cmp (%v) for %v.Cmp64(%v)", c, bc, test.x, test.y)
    83  		}
    84  	}
    85  }
    86  
    87  // TestCurrencyDiv checks that the div function has been correctly implemented.
    88  func TestCurrencyDiv(t *testing.T) {
    89  	c9 := NewCurrency64(9)
    90  	c10 := NewCurrency64(10)
    91  	c90 := NewCurrency64(90)
    92  	c97 := NewCurrency64(97)
    93  
    94  	c90D10 := c90.Div(c10)
    95  	if c90D10.Cmp(c9) != 0 {
    96  		t.Error("Dividing 90 by 10 should produce 9")
    97  	}
    98  	c97D10 := c97.Div(c10)
    99  	if c97D10.Cmp(c9) != 0 {
   100  		t.Error("Dividing 97 by 10 should produce 9")
   101  	}
   102  }
   103  
   104  // TestCurrencyDiv64 checks that the Div64 function has been correctly implemented.
   105  func TestCurrencyDiv64(t *testing.T) {
   106  	c9 := NewCurrency64(9)
   107  	u10 := uint64(10)
   108  	c90 := NewCurrency64(90)
   109  	c97 := NewCurrency64(97)
   110  
   111  	c90D10 := c90.Div64(u10)
   112  	if c90D10.Cmp(c9) != 0 {
   113  		t.Error("Dividing 90 by 10 should produce 9")
   114  	}
   115  	c97D10 := c97.Div64(u10)
   116  	if c97D10.Cmp(c9) != 0 {
   117  		t.Error("Dividing 97 by 10 should produce 9")
   118  	}
   119  }
   120  
   121  // TestCurrencyEquals tests the Equals method for the currency type
   122  func TestCurrencyEquals(t *testing.T) {
   123  	tests := []struct {
   124  		x, y Currency
   125  		exp  bool
   126  	}{
   127  		{NewCurrency64(0), NewCurrency64(0), true},
   128  		{NewCurrency64(0), NewCurrency64(1), false},
   129  		{NewCurrency64(1), NewCurrency64(0), false},
   130  		{NewCurrency64(100), NewCurrency64(7), false},
   131  		{NewCurrency64(777), NewCurrency(big.NewInt(777)), true},
   132  		{NewCurrency(big.NewInt(7)), NewCurrency(big.NewInt(8)), false},
   133  	}
   134  
   135  	for _, test := range tests {
   136  		if eq := test.x.Equals(test.y); eq != test.exp {
   137  			t.Errorf("expected %v.Equals(%v) == %v, got %v", test.x, test.y, test.exp, eq)
   138  		} else if bc := test.x.Big().Cmp(test.y.Big()); (bc == 0) != eq {
   139  			t.Errorf("Currency.Equals (%v) does not match big.Int.Cmp (%v) for %v.Equals(%v)", eq, bc, test.x, test.y)
   140  		}
   141  	}
   142  }
   143  
   144  // TestCurrencyEquals64 tests the Equals64 method for the currency type
   145  func TestCurrencyEquals64(t *testing.T) {
   146  	tests := []struct {
   147  		x   Currency
   148  		y   uint64
   149  		exp bool
   150  	}{
   151  		{NewCurrency64(0), 0, true},
   152  		{NewCurrency64(0), 1, false},
   153  		{NewCurrency64(1), 0, false},
   154  		{NewCurrency64(100), 7, false},
   155  		{NewCurrency64(777), 777, true},
   156  		{NewCurrency(big.NewInt(7)), 8, false},
   157  	}
   158  
   159  	for _, test := range tests {
   160  		if eq := test.x.Equals64(test.y); eq != test.exp {
   161  			t.Errorf("expected %v.Equals64(%v) == %v, got %v", test.x, test.y, test.exp, eq)
   162  		} else if bc := test.x.Big().Cmp(big.NewInt(int64(test.y))); (bc == 0) != eq {
   163  			t.Errorf("Currency.Equals64 (%v) does not match big.Int.Cmp (%v) for %v.Equals64(%v)", eq, bc, test.x, test.y)
   164  		}
   165  	}
   166  }
   167  
   168  // TestCurrencyMul probes the Mul function of the currency type.
   169  func TestCurrencyMul(t *testing.T) {
   170  	c5 := NewCurrency64(5)
   171  	c6 := NewCurrency64(6)
   172  	c30 := NewCurrency64(30)
   173  	if c5.Mul(c6).Cmp(c30) != 0 {
   174  		t.Error("Multiplying 5 by 6 should equal 30")
   175  	}
   176  }
   177  
   178  // TestCurrencyMul64 probes the Mul64 function of the currency type.
   179  func TestCurrencyMul64(t *testing.T) {
   180  	c5 := NewCurrency64(5)
   181  	u6 := uint64(6)
   182  	c30 := NewCurrency64(30)
   183  	if c5.Mul64(u6).Cmp(c30) != 0 {
   184  		t.Error("Multiplying 5 by 6 should equal 30")
   185  	}
   186  }
   187  
   188  // TestCurrencyMulRat probes the MulRat function of the currency type.
   189  func TestCurrencyMulRat(t *testing.T) {
   190  	c5 := NewCurrency64(5)
   191  	c7 := NewCurrency64(7)
   192  	c10 := NewCurrency64(10)
   193  	if c5.MulRat(big.NewRat(2, 1)).Cmp(c10) != 0 {
   194  		t.Error("Multiplying 5 by 2 should return 10")
   195  	}
   196  	if c5.MulRat(big.NewRat(3, 2)).Cmp(c7) != 0 {
   197  		t.Error("Multiplying 5 by 1.5 should return 7")
   198  	}
   199  }
   200  
   201  // TestCurrencyRoundDown probes the RoundDown function of the currency type.
   202  func TestCurrencyRoundDown(t *testing.T) {
   203  	// 10,000 is chosen because that's how many siafunds there usually are.
   204  	c40000 := NewCurrency64(40000)
   205  	c45000 := NewCurrency64(45000)
   206  	if c45000.RoundDown(NewCurrency64(10000)).Cmp(c40000) != 0 {
   207  		t.Error("rounding down 45000 to the nearest 10000 didn't work")
   208  	}
   209  }
   210  
   211  // TestCurrencyIsZero probes the IsZero function of the currency type.
   212  func TestCurrencyIsZero(t *testing.T) {
   213  	c0 := NewCurrency64(0)
   214  	c1 := NewCurrency64(1)
   215  	if !c0.IsZero() {
   216  		t.Error("IsZero returns wrong value for 0")
   217  	}
   218  	if c1.IsZero() {
   219  		t.Error("IsZero returns wrong value for 1")
   220  	}
   221  }
   222  
   223  // TestCurrencySqrt probes the Sqrt function of the currency type.
   224  func TestCurrencySqrt(t *testing.T) {
   225  	c8 := NewCurrency64(8)
   226  	c64 := NewCurrency64(64)
   227  	c80 := NewCurrency64(80)
   228  	sqrt64 := c64.Sqrt()
   229  	sqrt80 := c80.Sqrt()
   230  
   231  	if c8.Cmp(sqrt64) != 0 {
   232  		t.Error("square root of 64 should be 8")
   233  	}
   234  	if c8.Cmp(sqrt80) != 0 {
   235  		t.Error("square root of 80 should be 8")
   236  	}
   237  }
   238  
   239  // TestCurrencySub probes the Sub function of the currency type.
   240  func TestCurrencySub(t *testing.T) {
   241  	c3 := NewCurrency64(3)
   242  	c13 := NewCurrency64(13)
   243  	c16 := NewCurrency64(16)
   244  	if c16.Sub(c3).Cmp(c13) != 0 {
   245  		t.Error("16 minus 3 should equal 13")
   246  	}
   247  }
   248  
   249  // TestNegativeCurrencyMulRat checks that negative numbers are rejected when
   250  // calling MulRat on the currency type.
   251  func TestNegativeCurrencyMulRat(t *testing.T) {
   252  	// In debug mode, attempting to get a negative currency results in a panic.
   253  	defer func() {
   254  		r := recover()
   255  		if r == nil {
   256  			t.Error("no panic occurred when trying to create a negative currency")
   257  		}
   258  	}()
   259  
   260  	c := NewCurrency64(12)
   261  	_ = c.MulRat(big.NewRat(-1, 1))
   262  }
   263  
   264  // TestNegativeCurrencySub checks that negative numbers are prevented when
   265  // using subtraction on the currency type.
   266  func TestNegativeCurrencySub(t *testing.T) {
   267  	// In debug mode, attempting to get a negative currency results in a panic.
   268  	defer func() {
   269  		r := recover()
   270  		if r == nil {
   271  			t.Error("no panic occurred when trying to create a negative currency")
   272  		}
   273  	}()
   274  
   275  	c1 := NewCurrency64(1)
   276  	c2 := NewCurrency64(2)
   277  	_ = c1.Sub(c2)
   278  }
   279  
   280  // TestNegativeCurrencies tries an array of ways to produce a negative currency.
   281  func TestNegativeNewCurrency(t *testing.T) {
   282  	// In debug mode, attempting to get a negative currency results in a panic.
   283  	defer func() {
   284  		r := recover()
   285  		if r == nil {
   286  			t.Error("no panic occurred when trying to create a negative currency")
   287  		}
   288  	}()
   289  
   290  	// Try to create a new currency from a negative number.
   291  	negBig := big.NewInt(-1)
   292  	_ = NewCurrency(negBig)
   293  }
   294  
   295  // TestCurrencyUint64 tests that a currency is correctly converted to a uint64.
   296  func TestCurrencyUint64(t *testing.T) {
   297  	// Try a set of valid values.
   298  	values := []uint64{0, 1, 2, 3, 4, 25e3, math.MaxUint64 - 1e6, math.MaxUint64}
   299  	for _, value := range values {
   300  		c := NewCurrency64(value)
   301  		result, err := c.Uint64()
   302  		if err != nil {
   303  			t.Error(err)
   304  		}
   305  		if value != result {
   306  			t.Error("uint64 conversion failed")
   307  		}
   308  	}
   309  
   310  	// Try an overflow.
   311  	c := NewCurrency64(math.MaxUint64)
   312  	c = c.Mul(NewCurrency64(2))
   313  	result, err := c.Uint64()
   314  	if err != ErrUint64Overflow {
   315  		t.Error(err)
   316  	}
   317  	if result != 0 {
   318  		t.Error("result is not being zeroed in the event of an error")
   319  	}
   320  }