github.com/lino-network/lino@v0.6.11/types/coin_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  
     9  	wire "github.com/cosmos/cosmos-sdk/codec"
    10  	sdk "github.com/cosmos/cosmos-sdk/types"
    11  )
    12  
    13  var (
    14  	bigString = "1000000000000000000000000"
    15  	bigInt, _ = new(big.Int).SetString(bigString, 10)
    16  
    17  	doubleBigString = "2000000000000000000000000"
    18  	// doubleBigInt, _  = new(big.Int).SetString(doubleBigString, 10)
    19  	bigCoin, _       = NewCoinFromString(bigString)
    20  	doubleBigCoin, _ = NewCoinFromString(doubleBigString)
    21  )
    22  
    23  func TestNewCoinFromInt64(t *testing.T) {
    24  	testCases := []struct {
    25  		testName     string
    26  		inputInt64   int64
    27  		expectedCoin Coin
    28  	}{
    29  		{
    30  			testName:     "amount 1",
    31  			inputInt64:   1,
    32  			expectedCoin: NewCoinFromBigInt(new(big.Int).SetInt64(1)),
    33  		},
    34  		{
    35  			testName:     "amount 0",
    36  			inputInt64:   0,
    37  			expectedCoin: NewCoinFromBigInt(new(big.Int).SetInt64(0)),
    38  		},
    39  		{
    40  			testName:     "amount -1",
    41  			inputInt64:   -1,
    42  			expectedCoin: NewCoinFromBigInt(new(big.Int).SetInt64(-1)),
    43  		},
    44  		{
    45  			testName:     "amount 9223372036854775807",
    46  			inputInt64:   9223372036854775807,
    47  			expectedCoin: NewCoinFromBigInt(new(big.Int).SetInt64(9223372036854775807)),
    48  		},
    49  		{
    50  			testName:     "amount -9223372036854775808",
    51  			inputInt64:   -9223372036854775808,
    52  			expectedCoin: NewCoinFromBigInt(new(big.Int).SetInt64(-9223372036854775808)),
    53  		},
    54  	}
    55  
    56  	for _, tc := range testCases {
    57  		coin := NewCoinFromInt64(tc.inputInt64)
    58  		if !coin.IsEqual(tc.expectedCoin) {
    59  			t.Errorf("%s: diff coin, got %v, want %v", tc.testName, coin.Amount, tc.expectedCoin)
    60  		}
    61  	}
    62  }
    63  
    64  func TestNewCoinFromBigInt(t *testing.T) {
    65  	testCases := []struct {
    66  		testName    string
    67  		inputBigInt *big.Int
    68  		expectCoin  Coin
    69  	}{
    70  		{
    71  			testName:    "amount 1",
    72  			inputBigInt: new(big.Int).SetInt64(1),
    73  			expectCoin:  NewCoinFromInt64(1),
    74  		},
    75  		{
    76  			testName:    "amount 0",
    77  			inputBigInt: new(big.Int).SetInt64(0),
    78  			expectCoin:  NewCoinFromInt64(0),
    79  		},
    80  		{
    81  			testName:    "amount -1",
    82  			inputBigInt: new(big.Int).SetInt64(-1),
    83  			expectCoin:  NewCoinFromInt64(-1),
    84  		},
    85  		{
    86  			testName:    "amount 100",
    87  			inputBigInt: new(big.Int).SetInt64(100),
    88  			expectCoin:  NewCoinFromInt64(100),
    89  		},
    90  		{
    91  			testName:    "amount 9223372036854775807",
    92  			inputBigInt: new(big.Int).SetInt64(9223372036854775807),
    93  			expectCoin:  NewCoinFromInt64(9223372036854775807),
    94  		},
    95  		{
    96  			testName:    "amount -9223372036854775808",
    97  			inputBigInt: new(big.Int).SetInt64(-9223372036854775808),
    98  			expectCoin:  NewCoinFromInt64(-9223372036854775808),
    99  		},
   100  		{
   101  			testName:    "amount bigInt",
   102  			inputBigInt: bigInt,
   103  			expectCoin:  bigCoin,
   104  		},
   105  	}
   106  
   107  	for _, tc := range testCases {
   108  		coin := NewCoinFromBigInt(tc.inputBigInt)
   109  		if !coin.IsEqual(tc.expectCoin) {
   110  			t.Errorf("%s: diff amount, got %v, want %v", tc.testName, coin.Amount, tc.expectCoin.Amount)
   111  		}
   112  	}
   113  }
   114  
   115  func TestLNOToCoin(t *testing.T) {
   116  	testCases := []struct {
   117  		testName     string
   118  		inputString  string
   119  		expectCoin   Coin
   120  		expectResult sdk.Error
   121  	}{
   122  		{
   123  			testName:     "LNO 1",
   124  			inputString:  "1",
   125  			expectCoin:   NewCoinFromInt64(1 * Decimals),
   126  			expectResult: nil,
   127  		},
   128  		{
   129  			testName:     "LNO 92233720368547",
   130  			inputString:  "92233720368547",
   131  			expectCoin:   NewCoinFromInt64(92233720368547 * Decimals),
   132  			expectResult: nil,
   133  		},
   134  		{
   135  			testName:     "LNO 0.001",
   136  			inputString:  "0.001",
   137  			expectCoin:   NewCoinFromInt64(0.001 * Decimals),
   138  			expectResult: nil,
   139  		},
   140  		{
   141  			testName:     "LNO 0.0001",
   142  			inputString:  "0.0001",
   143  			expectCoin:   NewCoinFromInt64(0.0001 * Decimals),
   144  			expectResult: nil,
   145  		},
   146  		{
   147  			testName:     "LNO 0.00001",
   148  			inputString:  "0.00001",
   149  			expectCoin:   NewCoinFromInt64(0.00001 * Decimals),
   150  			expectResult: nil,
   151  		},
   152  		{
   153  			testName:     "less than lower bound LNO is invalid",
   154  			inputString:  "0.000001",
   155  			expectCoin:   NewCoinFromInt64(0),
   156  			expectResult: ErrInvalidCoins("LNO can't be less than lower bound"),
   157  		},
   158  		{
   159  			testName:     "0 LNO is invalid",
   160  			inputString:  "0",
   161  			expectCoin:   NewCoinFromInt64(0),
   162  			expectResult: ErrInvalidCoins("LNO can't be less than lower bound"),
   163  		},
   164  		{
   165  			testName:     "negative LNO is invalid",
   166  			inputString:  "-1",
   167  			expectCoin:   NewCoinFromInt64(0),
   168  			expectResult: ErrInvalidCoins("LNO can't be less than lower bound"),
   169  		},
   170  		{
   171  			testName:     "negative -0.1 LNO is invalid",
   172  			inputString:  "-0.1",
   173  			expectCoin:   NewCoinFromInt64(0),
   174  			expectResult: ErrInvalidCoins("LNO can't be less than lower bound"),
   175  		},
   176  		{
   177  			testName:     "overflow LNO is invalid",
   178  			inputString:  "92233720368548",
   179  			expectCoin:   NewCoinFromInt64(0),
   180  			expectResult: ErrInvalidCoins("LNO overflow"),
   181  		},
   182  		{
   183  			testName:     "illegal coin",
   184  			inputString:  "1$",
   185  			expectCoin:   NewCoinFromInt64(0),
   186  			expectResult: ErrInvalidCoins("Illegal LNO"),
   187  		},
   188  		{
   189  			testName:     "large amount of coin",
   190  			inputString:  "1e9999999999999999",
   191  			expectCoin:   NewCoinFromInt64(0),
   192  			expectResult: ErrInvalidCoins("Illegal LNO"),
   193  		},
   194  	}
   195  
   196  	for _, tc := range testCases {
   197  		coin, err := LinoToCoin(tc.inputString)
   198  		if !assert.Equal(t, tc.expectResult, err) {
   199  			t.Errorf("%s: diff err, got %v, want %v", tc.testName, err, tc.expectResult)
   200  		}
   201  		if !coin.IsEqual(tc.expectCoin) {
   202  			t.Errorf("%s: diff coin, got %v, want %v", tc.testName, coin, tc.expectCoin)
   203  		}
   204  	}
   205  }
   206  
   207  func TestRatToCoin(t *testing.T) {
   208  	assert := assert.New(t)
   209  	testCases := []struct {
   210  		testName    string
   211  		inputString string
   212  		expectCoin  Coin
   213  	}{
   214  		{
   215  			testName:    "Coin 1",
   216  			inputString: "1",
   217  			expectCoin:  NewCoinFromInt64(1),
   218  		},
   219  		{
   220  			testName:    "Coin 0",
   221  			inputString: "0",
   222  			expectCoin:  NewCoinFromInt64(0),
   223  		},
   224  		{
   225  			testName:    "Coin -1",
   226  			inputString: "-1",
   227  			expectCoin:  NewCoinFromInt64(-1),
   228  		},
   229  		{
   230  			testName:    "Coin 100000",
   231  			inputString: "100000",
   232  			expectCoin:  NewCoinFromInt64(100000),
   233  		},
   234  		{
   235  			testName:    "Coin 0.5",
   236  			inputString: "0.5",
   237  			expectCoin:  NewCoinFromInt64(0),
   238  		},
   239  		{
   240  			testName:    "Coin 0.6 will be rounded to 1",
   241  			inputString: "0.6",
   242  			expectCoin:  NewCoinFromInt64(1),
   243  		},
   244  		{
   245  			testName:    "Coin 1.4 will be rounded to 1",
   246  			inputString: "1.4",
   247  			expectCoin:  NewCoinFromInt64(1),
   248  		},
   249  		{
   250  			testName:    "Coin 1 will be rounded to 2",
   251  			inputString: "1.5",
   252  			expectCoin:  NewCoinFromInt64(2),
   253  		},
   254  		{
   255  			testName:    "Coin 9223372036854775807",
   256  			inputString: "9223372036854775807",
   257  			expectCoin:  NewCoinFromInt64(9223372036854775807),
   258  		},
   259  		{
   260  			testName:    "Coin -9223372036854775807",
   261  			inputString: "-9223372036854775807",
   262  			expectCoin:  NewCoinFromInt64(-9223372036854775807),
   263  		},
   264  		{
   265  			testName:    "Coin bigString",
   266  			inputString: bigString,
   267  			expectCoin:  bigCoin,
   268  		},
   269  	}
   270  
   271  	for _, tc := range testCases {
   272  		dec, err := sdk.NewDecFromStr(tc.inputString)
   273  		assert.Nil(err)
   274  		coin := DecToCoin(dec)
   275  		if !coin.IsEqual(tc.expectCoin) {
   276  			t.Errorf("%s: diff coin, got %v, want %v", tc.testName, coin, tc.expectCoin)
   277  		}
   278  	}
   279  }
   280  
   281  func TestIsPositiveCoin(t *testing.T) {
   282  	testCases := []struct {
   283  		testName     string
   284  		inputOne     Coin
   285  		expectResult bool
   286  	}{
   287  		{
   288  			testName:     "1 is positive",
   289  			inputOne:     NewCoinFromInt64(1),
   290  			expectResult: true,
   291  		},
   292  		{
   293  			testName:     "0 is not positive",
   294  			inputOne:     NewCoinFromInt64(0),
   295  			expectResult: false,
   296  		},
   297  		{
   298  			testName:     "-1 is not positive",
   299  			inputOne:     NewCoinFromInt64(-1),
   300  			expectResult: false,
   301  		},
   302  		{
   303  			testName:     "bigInt128 is positive",
   304  			inputOne:     bigCoin,
   305  			expectResult: true,
   306  		},
   307  		{
   308  			testName:     "doubleBigInt128 is not positive",
   309  			inputOne:     doubleBigCoin,
   310  			expectResult: true,
   311  		},
   312  	}
   313  
   314  	for _, tc := range testCases {
   315  		res := tc.inputOne.IsPositive()
   316  		if res != tc.expectResult {
   317  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   318  		}
   319  	}
   320  }
   321  
   322  func TestIsNotNegativeCoin(t *testing.T) {
   323  	testCases := []struct {
   324  		testName     string
   325  		inputOne     Coin
   326  		expectResult bool
   327  	}{
   328  		{
   329  			testName:     "1 is not negative",
   330  			inputOne:     NewCoinFromInt64(1),
   331  			expectResult: true,
   332  		},
   333  		{
   334  			testName:     "0 is not negative",
   335  			inputOne:     NewCoinFromInt64(0),
   336  			expectResult: true,
   337  		},
   338  		{
   339  			testName:     "-1 is negative",
   340  			inputOne:     NewCoinFromInt64(-1),
   341  			expectResult: false,
   342  		},
   343  		{
   344  			testName:     "bigInt128 is not negative",
   345  			inputOne:     bigCoin,
   346  			expectResult: true,
   347  		},
   348  		{
   349  			testName:     "doubleBigInt128 is not negative",
   350  			inputOne:     doubleBigCoin,
   351  			expectResult: true,
   352  		},
   353  	}
   354  
   355  	for _, tc := range testCases {
   356  		res := tc.inputOne.IsNotNegative()
   357  		if res != tc.expectResult {
   358  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   359  		}
   360  	}
   361  }
   362  
   363  func TestIsGTECoin(t *testing.T) {
   364  	testCases := []struct {
   365  		testName     string
   366  		inputOne     Coin
   367  		inputTwo     Coin
   368  		expectResult bool
   369  	}{
   370  		{
   371  			testName:     "inputs 1 are equal",
   372  			inputOne:     NewCoinFromInt64(1),
   373  			inputTwo:     NewCoinFromInt64(1),
   374  			expectResult: true,
   375  		},
   376  		{
   377  			testName:     "inputOne is bigger than inputTwo",
   378  			inputOne:     NewCoinFromInt64(2),
   379  			inputTwo:     NewCoinFromInt64(1),
   380  			expectResult: true,
   381  		},
   382  		{
   383  			testName:     "inputOne is less than inputTwo",
   384  			inputOne:     NewCoinFromInt64(-1),
   385  			inputTwo:     NewCoinFromInt64(5),
   386  			expectResult: false,
   387  		},
   388  		{
   389  			testName:     "bigInt128 is bigger than 5",
   390  			inputOne:     bigCoin,
   391  			inputTwo:     NewCoinFromInt64(5),
   392  			expectResult: true,
   393  		},
   394  		{
   395  			testName:     "inputs bigInt128 are equal",
   396  			inputOne:     bigCoin,
   397  			inputTwo:     bigCoin,
   398  			expectResult: true,
   399  		},
   400  		{
   401  			testName:     "doubleBigInt128 is bigger than bigInt128",
   402  			inputOne:     doubleBigCoin,
   403  			inputTwo:     bigCoin,
   404  			expectResult: true,
   405  		},
   406  	}
   407  
   408  	for _, tc := range testCases {
   409  		res := tc.inputOne.IsGTE(tc.inputTwo)
   410  		if res != tc.expectResult {
   411  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   412  		}
   413  	}
   414  }
   415  
   416  func TestIsGTCoin(t *testing.T) {
   417  	testCases := []struct {
   418  		testName     string
   419  		inputOne     Coin
   420  		inputTwo     Coin
   421  		expectResult bool
   422  	}{
   423  		{
   424  			testName:     "1 equals to 1",
   425  			inputOne:     NewCoinFromInt64(1),
   426  			inputTwo:     NewCoinFromInt64(1),
   427  			expectResult: false,
   428  		},
   429  		{
   430  			testName:     "2 is bigger than 1",
   431  			inputOne:     NewCoinFromInt64(2),
   432  			inputTwo:     NewCoinFromInt64(1),
   433  			expectResult: true,
   434  		},
   435  		{
   436  			testName:     "-1 is less than 5",
   437  			inputOne:     NewCoinFromInt64(-1),
   438  			inputTwo:     NewCoinFromInt64(5),
   439  			expectResult: false,
   440  		},
   441  		{
   442  			testName:     "bigInt128 is bigger than 5",
   443  			inputOne:     bigCoin,
   444  			inputTwo:     NewCoinFromInt64(5),
   445  			expectResult: true,
   446  		},
   447  		{
   448  			testName:     "bigInt128 is not bigger than bigInt128",
   449  			inputOne:     bigCoin,
   450  			inputTwo:     bigCoin,
   451  			expectResult: false,
   452  		},
   453  		{
   454  			testName:     "doubleBigInt128 is bigger than bigInt128",
   455  			inputOne:     doubleBigCoin,
   456  			inputTwo:     bigCoin,
   457  			expectResult: true,
   458  		},
   459  	}
   460  
   461  	for _, tc := range testCases {
   462  		res := tc.inputOne.IsGT(tc.inputTwo)
   463  		if res != tc.expectResult {
   464  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   465  		}
   466  	}
   467  }
   468  
   469  func TestIsEqualCoin(t *testing.T) {
   470  	testCases := []struct {
   471  		testName     string
   472  		inputOne     Coin
   473  		inputTwo     Coin
   474  		expectResult bool
   475  	}{
   476  		{
   477  			testName:     "bigInt128 equals to bigInt128",
   478  			inputOne:     bigCoin,
   479  			inputTwo:     bigCoin,
   480  			expectResult: true,
   481  		},
   482  		{
   483  			testName:     "1 equals to 1",
   484  			inputOne:     NewCoinFromInt64(1),
   485  			inputTwo:     NewCoinFromInt64(1),
   486  			expectResult: true,
   487  		},
   488  		{
   489  			testName:     "1 is not equal to 10",
   490  			inputOne:     NewCoinFromInt64(1),
   491  			inputTwo:     NewCoinFromInt64(10),
   492  			expectResult: false,
   493  		},
   494  		{
   495  			testName:     "-11 is not equal to 10",
   496  			inputOne:     NewCoinFromInt64(-11),
   497  			inputTwo:     NewCoinFromInt64(10),
   498  			expectResult: false,
   499  		},
   500  		{
   501  			testName:     "1 equals to int128 1",
   502  			inputOne:     NewCoinFromInt64(1),
   503  			inputTwo:     NewCoinFromBigInt(new(big.Int).SetInt64(1)),
   504  			expectResult: true,
   505  		},
   506  		{
   507  			testName:     "1 equals to coin1",
   508  			inputOne:     NewCoinFromInt64(1),
   509  			inputTwo:     NewCoinFromBigInt(new(big.Int).SetInt64(1)),
   510  			expectResult: true,
   511  		},
   512  	}
   513  
   514  	for _, tc := range testCases {
   515  		res := tc.inputOne.IsEqual(tc.inputTwo)
   516  		if res != tc.expectResult {
   517  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   518  		}
   519  	}
   520  }
   521  
   522  func TestPlusCoin(t *testing.T) {
   523  	testCases := []struct {
   524  		testName     string
   525  		inputOne     Coin
   526  		inputTwo     Coin
   527  		expectResult Coin
   528  	}{
   529  		{
   530  			testName:     "0 + 1 = 1",
   531  			inputOne:     NewCoinFromInt64(0),
   532  			inputTwo:     NewCoinFromInt64(1),
   533  			expectResult: NewCoinFromInt64(1),
   534  		},
   535  		{
   536  			testName:     "1 + 0 = 1",
   537  			inputOne:     NewCoinFromInt64(1),
   538  			inputTwo:     NewCoinFromInt64(0),
   539  			expectResult: NewCoinFromInt64(1),
   540  		},
   541  		{
   542  			testName:     "1 + 1 = 2",
   543  			inputOne:     NewCoinFromInt64(1),
   544  			inputTwo:     NewCoinFromInt64(1),
   545  			expectResult: NewCoinFromInt64(2),
   546  		},
   547  		{
   548  			testName:     "-4 + 5 = 1",
   549  			inputOne:     NewCoinFromInt64(-4),
   550  			inputTwo:     NewCoinFromInt64(5),
   551  			expectResult: NewCoinFromInt64(1),
   552  		},
   553  		{
   554  			testName:     "-1 + 1 = 0",
   555  			inputOne:     NewCoinFromInt64(-1),
   556  			inputTwo:     NewCoinFromInt64(1),
   557  			expectResult: NewCoinFromInt64(0),
   558  		},
   559  		{
   560  			testName:     "bigInt128 + bigInt128 = doubleBigInt128",
   561  			inputOne:     bigCoin,
   562  			inputTwo:     bigCoin,
   563  			expectResult: doubleBigCoin,
   564  		},
   565  	}
   566  
   567  	for _, tc := range testCases {
   568  		res := tc.inputOne.Plus(tc.inputTwo)
   569  		if !res.IsEqual(tc.expectResult) {
   570  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   571  		}
   572  	}
   573  }
   574  
   575  func TestMinusCoin(t *testing.T) {
   576  	testCases := []struct {
   577  		testName     string
   578  		inputOne     Coin
   579  		inputTwo     Coin
   580  		expectResult Coin
   581  	}{
   582  		{
   583  			testName:     "0 - 0 = 0",
   584  			inputOne:     NewCoinFromInt64(0),
   585  			inputTwo:     NewCoinFromInt64(0),
   586  			expectResult: NewCoinFromInt64(0),
   587  		},
   588  		{
   589  			testName:     "1 - 0 = 1",
   590  			inputOne:     NewCoinFromInt64(1),
   591  			inputTwo:     NewCoinFromInt64(0),
   592  			expectResult: NewCoinFromInt64(1),
   593  		},
   594  		{
   595  			testName:     "1 - 1 = 0",
   596  			inputOne:     NewCoinFromInt64(1),
   597  			inputTwo:     NewCoinFromInt64(1),
   598  			expectResult: NewCoinFromInt64(0),
   599  		},
   600  		{
   601  			testName:     "1 - (-1) = 2",
   602  			inputOne:     NewCoinFromInt64(1),
   603  			inputTwo:     NewCoinFromInt64(-1),
   604  			expectResult: NewCoinFromInt64(2),
   605  		},
   606  		{
   607  			testName:     "-1 - (-1) = 0",
   608  			inputOne:     NewCoinFromInt64(-1),
   609  			inputTwo:     NewCoinFromInt64(-1),
   610  			expectResult: NewCoinFromInt64(0),
   611  		},
   612  		{
   613  			testName:     "-4 - 5 = -9",
   614  			inputOne:     NewCoinFromInt64(-4),
   615  			inputTwo:     NewCoinFromInt64(5),
   616  			expectResult: NewCoinFromInt64(-9),
   617  		},
   618  		{
   619  			testName:     "10 - 1 = 9",
   620  			inputOne:     NewCoinFromInt64(10),
   621  			inputTwo:     NewCoinFromInt64(1),
   622  			expectResult: NewCoinFromInt64(9),
   623  		},
   624  		{
   625  			testName:     "bigInt128 - bigInt128 = 0",
   626  			inputOne:     bigCoin,
   627  			inputTwo:     bigCoin,
   628  			expectResult: NewCoinFromInt64(0),
   629  		},
   630  	}
   631  
   632  	for _, tc := range testCases {
   633  		res := tc.inputOne.Minus(tc.inputTwo)
   634  		if !res.IsEqual(tc.expectResult) {
   635  			t.Errorf("%s: diff result, got %v, want %v", tc.testName, res, tc.expectResult)
   636  		}
   637  	}
   638  }
   639  
   640  var cdc = wire.New() //var jsonCdc JSONCodec // TODO wire.Codec
   641  
   642  func TestSerializationGoWire(t *testing.T) {
   643  	r := bigCoin
   644  
   645  	//bz, err := json.Marshal(r)
   646  	bz, err := cdc.MarshalJSON(r)
   647  	if err != nil {
   648  		t.Errorf("TestSerializationGoWire: failed to marshal, got err %v", err)
   649  	}
   650  
   651  	//str, err := r.MarshalJSON()
   652  	//require.Nil(t, err)
   653  
   654  	r2 := NewCoinFromInt64(0)
   655  	//err = json.Unmarshal([]byte(bz), &r2)
   656  	err = cdc.UnmarshalJSON(bz, &r2)
   657  	//panic(fmt.Sprintf("debug bz: %v\n", string(bz)))
   658  	if err != nil {
   659  		t.Errorf("TestSerializationGoWire: failed to unmarshal, got err %v", err)
   660  	}
   661  
   662  	if !r2.IsEqual(r) {
   663  		t.Errorf("TestSerializationGoWire: diff result, got %v, want %v", r2, r)
   664  	}
   665  }