github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/common/syscoins_test.go (about) 1 package common 2 3 import ( 4 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 5 "github.com/stretchr/testify/assert" 6 "testing" 7 8 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 9 "github.com/stretchr/testify/require" 10 ) 11 12 // ---------------------------------------------------------------------------- 13 // Coins tests 14 15 var ( 16 syscoinsTestDenom1 = "eos" 17 syscoinsTestDenom2 = "fibo" 18 ) 19 20 func TestIsZeroCoins(t *testing.T) { 21 cases := []struct { 22 inputOne sdk.SysCoins 23 expected bool 24 }{ 25 {sdk.SysCoins{}, true}, 26 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, true}, 27 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 0)}, true}, 28 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 1)}, false}, 29 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, false}, 30 } 31 32 for _, tc := range cases { 33 res := tc.inputOne.IsZero() 34 require.Equal(t, tc.expected, res) 35 } 36 } 37 38 func TestEqualCoins(t *testing.T) { 39 cases := []struct { 40 inputOne sdk.SysCoins 41 inputTwo sdk.SysCoins 42 expected bool 43 panics bool 44 }{ 45 {sdk.SysCoins{}, sdk.SysCoins{}, true, false}, 46 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, true, false}, 47 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, true, false}, 48 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom2, 0)}, false, true}, 49 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 1)}, false, false}, 50 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, false, false}, 51 {sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, sdk.SysCoins{sdk.NewInt64Coin(syscoinsTestDenom1, 0), sdk.NewInt64Coin(syscoinsTestDenom2, 1)}, true, false}, 52 } 53 54 for tcIndex, tc := range cases { 55 tc := tc 56 if tc.panics { 57 require.Panics(t, func() { tc.inputOne.IsEqual(tc.inputTwo) }) 58 } else { 59 res := tc.inputOne.IsEqual(tc.inputTwo) 60 require.Equal(t, tc.expected, res, "Equality is differed from exported. tc #%d, expected %b, actual %b.", tcIndex, tc.expected, res) 61 } 62 } 63 } 64 65 func TestAddCoins(t *testing.T) { 66 cases := []struct { 67 inputOne sdk.SysCoins 68 inputTwo sdk.SysCoins 69 expected sdk.SysCoins 70 shouldPanic bool 71 }{ 72 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}, {syscoinsTestDenom2, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}, {syscoinsTestDenom2, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}, {syscoinsTestDenom2, sdk.NewDec(2)}}, false}, 73 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(0)}, {syscoinsTestDenom2, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(0)}, {syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins{{syscoinsTestDenom2, sdk.NewDec(1)}}, false}, 74 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}}, sdk.SysCoins{{syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}}, false}, 75 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}, {syscoinsTestDenom2, sdk.NewDec(2)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}, {syscoinsTestDenom2, sdk.NewDec(2)}}, false}, 76 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(0)}, {syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(0)}, {syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins(nil), false}, 77 } 78 79 for tcIndex, tc := range cases { 80 tc := tc 81 if tc.shouldPanic { 82 require.Panics(t, func() { tc.inputOne.Add2(tc.inputTwo) }) 83 } else { 84 res := tc.inputOne.Add2(tc.inputTwo) 85 assert.True(t, res.IsValid()) 86 require.Equal(t, tc.expected, res, "sum of coins is incorrect, tc #%d", tcIndex) 87 } 88 } 89 } 90 91 func TestSubCoins(t *testing.T) { 92 testCases := []struct { 93 inputOne sdk.SysCoins 94 inputTwo sdk.SysCoins 95 expected sdk.SysCoins 96 shouldPanic bool 97 }{ 98 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}}, sdk.SysCoins{{syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}}, false}, 99 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom2, sdk.NewDec(0)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}}, false}, 100 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}, {syscoinsTestDenom2, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom2, sdk.NewDec(1)}}, false}, 101 {sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(1)}, {syscoinsTestDenom2, sdk.NewDec(1)}}, sdk.SysCoins{{syscoinsTestDenom1, sdk.NewDec(2)}}, sdk.SysCoins{}, true}, 102 } 103 104 for tcIndex, tc := range testCases { 105 tc := tc 106 if tc.shouldPanic { 107 require.Panics(t, func() { tc.inputOne.Sub(tc.inputTwo) }) 108 } else { 109 res := tc.inputOne.Sub(tc.inputTwo) 110 assert.True(t, res.IsValid()) 111 require.Equal(t, tc.expected, res, "sum of coins is incorrect, tc #%d", tcIndex) 112 } 113 } 114 } 115 116 func TestSortDecCoins(t *testing.T) { 117 good := sdk.SysCoins{ 118 {"gas", sdk.NewDec(1)}, 119 {"mineral", sdk.NewDec(1)}, 120 {"tree", sdk.NewDec(1)}, 121 } 122 mixedCase1 := sdk.SysCoins{ 123 {"gAs", sdk.NewDec(1)}, 124 {"MineraL", sdk.NewDec(1)}, 125 {"TREE", sdk.NewDec(1)}, 126 } 127 mixedCase2 := sdk.SysCoins{ 128 {"gAs", sdk.NewDec(1)}, 129 {"mineral", sdk.NewDec(1)}, 130 } 131 mixedCase3 := sdk.SysCoins{ 132 {"gAs", sdk.NewDec(1)}, 133 } 134 empty := sdk.NewCoins() 135 badSort1 := sdk.SysCoins{ 136 {"tree", sdk.NewDec(1)}, 137 {"gas", sdk.NewDec(1)}, 138 {"mineral", sdk.NewDec(1)}, 139 } 140 141 // both are after the first one, but the second and third are in the wrong order 142 badSort2 := sdk.SysCoins{ 143 {"gas", sdk.NewDec(1)}, 144 {"tree", sdk.NewDec(1)}, 145 {"mineral", sdk.NewDec(1)}, 146 } 147 badAmt := sdk.SysCoins{ 148 {"gas", sdk.NewDec(1)}, 149 {"tree", sdk.NewDec(0)}, 150 {"mineral", sdk.NewDec(1)}, 151 } 152 dup := sdk.SysCoins{ 153 {"gas", sdk.NewDec(1)}, 154 {"gas", sdk.NewDec(1)}, 155 {"mineral", sdk.NewDec(1)}, 156 } 157 neg := sdk.SysCoins{ 158 {"gas", sdk.NewDec(-1)}, 159 {"mineral", sdk.NewDec(1)}, 160 } 161 162 assert.True(t, good.IsValid(), "Coins are valid") 163 assert.False(t, mixedCase1.IsValid(), "Coins denoms contain upper case characters") 164 assert.False(t, mixedCase2.IsValid(), "First Coins denoms contain upper case characters") 165 assert.False(t, mixedCase3.IsValid(), "Single denom in Coins contains upper case characters") 166 assert.True(t, good.IsAllPositive(), "Expected coins to be positive: %v", good) 167 assert.False(t, empty.IsAllPositive(), "Expected coins to not be positive: %v", empty) 168 assert.True(t, good.IsAllGTE(empty), "Expected %v to be >= %v", good, empty) 169 assert.False(t, good.IsAllLT(empty), "Expected %v to be < %v", good, empty) 170 assert.True(t, empty.IsAllLT(good), "Expected %v to be < %v", empty, good) 171 assert.False(t, badSort1.IsValid(), "Coins are not sorted") 172 assert.False(t, badSort2.IsValid(), "Coins are not sorted") 173 assert.False(t, badAmt.IsValid(), "Coins cannot include 0 amounts") 174 assert.False(t, dup.IsValid(), "Duplicate coin") 175 assert.False(t, neg.IsValid(), "Negative first-denom coin") 176 } 177 178 func TestCoinsGT(t *testing.T) { 179 one := sdk.NewDec(1) 180 two := sdk.NewDec(2) 181 182 assert.False(t, sdk.SysCoins{}.IsAllGT(sdk.SysCoins{})) 183 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{})) 184 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 185 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom2, one}})) 186 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom2, one}})) 187 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom2, two}})) 188 } 189 190 func TestCoinsLT(t *testing.T) { 191 one := sdk.NewDec(1) 192 two := sdk.NewDec(2) 193 194 assert.False(t, sdk.SysCoins{}.IsAllLT(sdk.SysCoins{})) 195 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLT(sdk.SysCoins{})) 196 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 197 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom2, one}})) 198 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom2, one}})) 199 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom2, two}})) 200 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}})) 201 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom1, two}, {syscoinsTestDenom2, two}})) 202 assert.True(t, sdk.SysCoins{}.IsAllLT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 203 } 204 205 func TestCoinsLTE(t *testing.T) { 206 one := sdk.NewDec(1) 207 two := sdk.NewDec(2) 208 209 assert.True(t, sdk.SysCoins{}.IsAllLTE(sdk.SysCoins{})) 210 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLTE(sdk.SysCoins{})) 211 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 212 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom2, one}})) 213 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom2, one}})) 214 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom2, two}})) 215 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}})) 216 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 217 assert.True(t, sdk.SysCoins{}.IsAllLTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 218 } 219 220 func TestParse(t *testing.T) { 221 cases := []struct { 222 input string 223 valid bool // if false, we expect an error on parse 224 expected sdk.SysCoins // if valid is true, make sure this is returned 225 }{ 226 {"", true, nil}, 227 {"1foo", true, sdk.SysCoins{{"foo", sdk.NewDec(1)}}}, 228 {"10bar", true, sdk.SysCoins{{"bar", sdk.NewDec(10)}}}, 229 {"99bar,1foo", true, sdk.SysCoins{{"bar", sdk.NewDec(99)}, {"foo", sdk.NewDec(1)}}}, 230 {"98 bar , 1 foo ", true, sdk.SysCoins{{"bar", sdk.NewDec(98)}, {"foo", sdk.NewDec(1)}}}, 231 {" 55\t \t bling\n", true, sdk.SysCoins{{"bling", sdk.NewDec(55)}}}, 232 {"2foo, 97 bar", true, sdk.SysCoins{{"bar", sdk.NewDec(97)}, {"foo", sdk.NewDec(2)}}}, 233 {"5 mycoin,", false, nil}, // no empty coins in a list 234 {"2 3foo, 97 bar", false, nil}, // 3foo is invalid coin name 235 {"11me coin, 12you coin", false, nil}, // no spaces in coin names 236 //{"1.2btc", true, sdk.Coins{{"btc", sdk.NewDec(1.2)}}}, // amount must be integer 237 {"5foo-bar", false, nil}, // once more, only letters in coin name 238 } 239 240 for tcIndex, tc := range cases { 241 res, err := sdk.ParseCoins(tc.input) 242 if !tc.valid { 243 require.NotNil(t, err, "%s: %#v. tc #%d", tc.input, res, tcIndex) 244 } else if assert.Nil(t, err, "%s: %+v", tc.input, err) { 245 require.Equal(t, tc.expected, res, "coin parsing was incorrect, tc #%d", tcIndex) 246 } 247 } 248 } 249 250 func TestSortCoins(t *testing.T) { 251 good := sdk.SysCoins{ 252 sdk.NewInt64Coin("gas", 1), 253 sdk.NewInt64Coin("mineral", 1), 254 sdk.NewInt64Coin("tree", 1), 255 } 256 empty := sdk.SysCoins{ 257 sdk.NewInt64Coin("gold", 0), 258 } 259 badSort1 := sdk.SysCoins{ 260 sdk.NewInt64Coin("tree", 1), 261 sdk.NewInt64Coin("gas", 1), 262 sdk.NewInt64Coin("mineral", 1), 263 } 264 badSort2 := sdk.SysCoins{ // both are after the first one, but the second and third are in the wrong order 265 sdk.NewInt64Coin("gas", 1), 266 sdk.NewInt64Coin("tree", 1), 267 sdk.NewInt64Coin("mineral", 1), 268 } 269 badAmt := sdk.SysCoins{ 270 sdk.NewInt64Coin("gas", 1), 271 sdk.NewInt64Coin("tree", 0), 272 sdk.NewInt64Coin("mineral", 1), 273 } 274 dup := sdk.SysCoins{ 275 sdk.NewInt64Coin("gas", 1), 276 sdk.NewInt64Coin("gas", 1), 277 sdk.NewInt64Coin("mineral", 1), 278 } 279 280 cases := []struct { 281 coins sdk.SysCoins 282 before, after bool // valid before/after sort 283 }{ 284 {good, true, true}, 285 {empty, false, false}, 286 {badSort1, false, true}, 287 {badSort2, false, true}, 288 {badAmt, false, false}, 289 {dup, false, false}, 290 } 291 292 for tcIndex, tc := range cases { 293 require.Equal(t, tc.before, tc.coins.IsValid(), "coin validity is incorrect before sorting, tc #%d", tcIndex) 294 tc.coins.Sort() 295 require.Equal(t, tc.after, tc.coins.IsValid(), "coin validity is incorrect after sorting, tc #%d", tcIndex) 296 } 297 } 298 299 func TestAmountOf(t *testing.T) { 300 case0 := sdk.SysCoins{} 301 case1 := sdk.SysCoins{ 302 sdk.NewInt64Coin("gold", 0), 303 } 304 case2 := sdk.SysCoins{ 305 sdk.NewInt64Coin("gas", 1), 306 sdk.NewInt64Coin("mineral", 1), 307 sdk.NewInt64Coin("tree", 1), 308 } 309 case3 := sdk.SysCoins{ 310 sdk.NewInt64Coin("mineral", 1), 311 sdk.NewInt64Coin("tree", 1), 312 } 313 case4 := sdk.SysCoins{ 314 sdk.NewInt64Coin("gas", 8), 315 } 316 317 cases := []struct { 318 coins sdk.SysCoins 319 amountOf int64 320 amountOfSpace int64 321 amountOfGAS int64 322 amountOfMINERAL int64 323 amountOfTREE int64 324 }{ 325 {case0, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000}, 326 {case1, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000}, 327 {case2, 0.0000000000000000000, 0.000000000000000000, 1.000000000000000000, 1.000000000000000000, 1.000000000000000000}, 328 {case3, 0.000000000000000000, 0.000000000000000000, 0.000000000000000000, 1.000000000000000000, 1.000000000000000000}, 329 {case4, 0.000000000000000000, 0.000000000000000000, 8.000000000000000000, 0.000000000000000000, 0.000000000000000000}, 330 } 331 332 for _, tc := range cases { 333 assert.Equal(t, sdk.NewDec(tc.amountOfGAS), tc.coins.AmountOf("gas")) 334 assert.Equal(t, sdk.NewDec(tc.amountOfMINERAL), tc.coins.AmountOf("mineral")) 335 assert.Equal(t, sdk.NewDec(tc.amountOfTREE), tc.coins.AmountOf("tree")) 336 } 337 338 assert.Panics(t, func() { cases[0].coins.AmountOf("Invalid") }) 339 } 340 341 func TestCoinsIsAnyGTE(t *testing.T) { 342 one := sdk.NewDec(1) 343 two := sdk.NewDec(2) 344 345 assert.False(t, sdk.SysCoins{}.IsAnyGTE(sdk.SysCoins{})) 346 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAnyGTE(sdk.SysCoins{})) 347 assert.False(t, sdk.SysCoins{}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 348 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, two}})) 349 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom2, one}})) 350 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, two}, {syscoinsTestDenom2, one}})) 351 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 352 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, two}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 353 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 354 assert.True(t, sdk.SysCoins{{syscoinsTestDenom2, two}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 355 assert.False(t, sdk.SysCoins{{syscoinsTestDenom2, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 356 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}})) 357 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 358 assert.True(t, sdk.SysCoins{{"xxx", one}, {"yyy", one}}.IsAnyGTE(sdk.SysCoins{{syscoinsTestDenom2, one}, {"ccc", one}, {"yyy", one}, {"zzz", one}})) 359 } 360 361 func TestCoinsIsAllGT(t *testing.T) { 362 one := sdk.NewDec(1) 363 two := sdk.NewDec(2) 364 365 assert.False(t, sdk.SysCoins{}.IsAllGT(sdk.SysCoins{})) 366 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{})) 367 assert.False(t, sdk.SysCoins{}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 368 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, two}})) 369 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom2, one}})) 370 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, two}, {syscoinsTestDenom2, one}})) 371 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 372 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, two}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}})) 373 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 374 assert.False(t, sdk.SysCoins{{syscoinsTestDenom2, two}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 375 assert.False(t, sdk.SysCoins{{syscoinsTestDenom2, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 376 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}})) 377 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 378 assert.False(t, sdk.SysCoins{{"xxx", one}, {"yyy", one}}.IsAllGT(sdk.SysCoins{{syscoinsTestDenom2, one}, {"ccc", one}, {"yyy", one}, {"zzz", one}})) 379 } 380 381 func TestCoinsIsAllGTE(t *testing.T) { 382 one := sdk.NewDec(1) 383 two := sdk.NewDec(2) 384 385 assert.True(t, sdk.SysCoins{}.IsAllGTE(sdk.SysCoins{})) 386 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGTE(sdk.SysCoins{})) 387 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom2, one}})) 388 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom2, two}})) 389 assert.False(t, sdk.SysCoins{}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 390 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, two}})) 391 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom2, one}})) 392 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, two}, {syscoinsTestDenom2, one}})) 393 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 394 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, two}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}})) 395 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 396 assert.False(t, sdk.SysCoins{{syscoinsTestDenom2, two}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 397 assert.False(t, sdk.SysCoins{{syscoinsTestDenom2, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 398 assert.True(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}})) 399 assert.False(t, sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom1, one}, {syscoinsTestDenom2, two}})) 400 assert.False(t, sdk.SysCoins{{"xxx", one}, {"yyy", one}}.IsAllGTE(sdk.SysCoins{{syscoinsTestDenom2, one}, {"ccc", one}, {"yyy", one}, {"zzz", one}})) 401 } 402 403 func TestNewCoins(t *testing.T) { 404 tenatom := sdk.NewInt64Coin("atom", 10) 405 tenbtc := sdk.NewInt64Coin("btc", 10) 406 zeroeth := sdk.NewInt64Coin("eth", 0) 407 tests := []struct { 408 name string 409 coins sdk.SysCoins 410 want sdk.SysCoins 411 wantPanic bool 412 }{ 413 {"empty args", []sdk.SysCoin{}, sdk.SysCoins{}, false}, 414 {"one coin", []sdk.SysCoin{tenatom}, sdk.SysCoins{tenatom}, false}, 415 {"sort after create", []sdk.SysCoin{tenbtc, tenatom}, sdk.SysCoins{tenatom, tenbtc}, false}, 416 {"sort and remove zeroes", []sdk.SysCoin{zeroeth, tenbtc, tenatom}, sdk.SysCoins{tenatom, tenbtc}, false}, 417 {"panic on dups", []sdk.SysCoin{tenatom, tenatom}, sdk.SysCoins{}, true}, 418 } 419 for _, tt := range tests { 420 tt := tt 421 t.Run(tt.name, func(t *testing.T) { 422 if tt.wantPanic { 423 require.Panics(t, func() { sdk.NewCoins(tt.coins...) }) 424 return 425 } 426 got := sdk.NewCoins(tt.coins...) 427 require.True(t, got.IsEqual(tt.want)) 428 }) 429 } 430 } 431 432 func TestCoinsIsAnyGT(t *testing.T) { 433 twoAtom := sdk.NewInt64Coin("atom", 2) 434 fiveAtom := sdk.NewInt64Coin("atom", 5) 435 threeEth := sdk.NewInt64Coin("eth", 3) 436 sixEth := sdk.NewInt64Coin("eth", 6) 437 twoBtc := sdk.NewInt64Coin("btc", 2) 438 439 require.False(t, sdk.SysCoins{}.IsAnyGT(sdk.SysCoins{})) 440 441 require.False(t, sdk.SysCoins{fiveAtom}.IsAnyGT(sdk.SysCoins{})) 442 require.False(t, sdk.SysCoins{}.IsAnyGT(sdk.SysCoins{fiveAtom})) 443 require.True(t, sdk.SysCoins{fiveAtom}.IsAnyGT(sdk.SysCoins{twoAtom})) 444 require.False(t, sdk.SysCoins{twoAtom}.IsAnyGT(sdk.SysCoins{fiveAtom})) 445 446 require.True(t, sdk.SysCoins{twoAtom, sixEth}.IsAnyGT(sdk.SysCoins{twoBtc, fiveAtom, threeEth})) 447 require.False(t, sdk.SysCoins{twoBtc, twoAtom, threeEth}.IsAnyGT(sdk.SysCoins{fiveAtom, sixEth})) 448 require.False(t, sdk.SysCoins{twoAtom, sixEth}.IsAnyGT(sdk.SysCoins{twoBtc, fiveAtom})) 449 } 450 451 func TestMarshalJSONCoins(t *testing.T) { 452 cdc := codec.New() 453 sdk.RegisterCodec(cdc) 454 455 testCases := []struct { 456 name string 457 input sdk.SysCoins 458 strOutput string 459 }{ 460 {"nil coins", nil, `[]`}, 461 {"empty coins", sdk.SysCoins{}, `[]`}, 462 {"non-empty coins", sdk.NewCoins(sdk.NewInt64Coin("foo", 50)), `[{"denom":"foo","amount":"50.000000000000000000"}]`}, 463 } 464 465 for _, tc := range testCases { 466 tc := tc 467 t.Run(tc.name, func(t *testing.T) { 468 bz, err := cdc.MarshalJSON(tc.input) 469 require.NoError(t, err) 470 require.Equal(t, tc.strOutput, string(bz)) 471 472 var newCoins sdk.SysCoins 473 require.NoError(t, cdc.UnmarshalJSON(bz, &newCoins)) 474 475 if tc.input.Empty() { 476 require.Nil(t, newCoins) 477 } else { 478 require.Equal(t, tc.input, newCoins) 479 } 480 }) 481 } 482 } 483 484 func TestCoinsIsValid(t *testing.T) { 485 testCases := []struct { 486 input sdk.Coins 487 expected bool 488 }{ 489 {sdk.SysCoins{}, true}, 490 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(5)}}, true}, 491 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(5)}, sdk.DecCoin{Denom: syscoinsTestDenom2, Amount: sdk.NewDec(100000)}}, true}, 492 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(-5)}}, false}, 493 {sdk.SysCoins{sdk.DecCoin{Denom: "AAA", Amount: sdk.NewDec(5)}}, false}, 494 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(5)}, sdk.DecCoin{Denom: "B", Amount: sdk.NewDec(100000)}}, false}, 495 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(5)}, sdk.DecCoin{Denom: syscoinsTestDenom2, Amount: sdk.NewDec(-100000)}}, false}, 496 {sdk.SysCoins{sdk.DecCoin{Denom: syscoinsTestDenom1, Amount: sdk.NewDec(-5)}, sdk.DecCoin{Denom: syscoinsTestDenom2, Amount: sdk.NewDec(100000)}}, false}, 497 {sdk.SysCoins{sdk.DecCoin{Denom: "AAA", Amount: sdk.NewDec(5)}, sdk.DecCoin{Denom: syscoinsTestDenom2, Amount: sdk.NewDec(100000)}}, false}, 498 } 499 500 for i, tc := range testCases { 501 res := tc.input.IsValid() 502 require.Equal(t, tc.expected, res, "unexpected result for test case #%d, input: %v", i, tc.input) 503 } 504 } 505 506 func TestDecCoinsString(t *testing.T) { 507 testCases := []struct { 508 input sdk.SysCoins 509 expected string 510 }{ 511 {sdk.SysCoins{}, ""}, 512 { 513 sdk.SysCoins{ 514 sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5040000000000000000, sdk.Precision)), 515 sdk.NewDecCoinFromDec("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision)), 516 }, 517 "5.040000000000000000atom,0.004000000000000000stake", 518 }, 519 } 520 521 for i, tc := range testCases { 522 out := tc.input.String() 523 require.Equal(t, tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input) 524 } 525 } 526 527 func TestDecCoinsIntersect(t *testing.T) { 528 testCases := []struct { 529 input1 string 530 input2 string 531 expectedResult string 532 }{ 533 {"", "", ""}, 534 {"1.0stake", "", ""}, 535 {"1.0stake", "1.0stake", "1.0stake"}, 536 {"", "1.0stake", ""}, 537 {"1.0stake", "", ""}, 538 {"2.0stake,1.0trope", "1.9stake", "1.9stake"}, 539 {"2.0stake,1.0trope", "2.1stake", "2.0stake"}, 540 {"2.0stake,1.0trope", "0.9trope", "0.9trope"}, 541 {"2.0stake,1.0trope", "1.9stake,0.9trope", "1.9stake,0.9trope"}, 542 {"2.0stake,1.0trope", "1.9stake,0.9trope,20.0other", "1.9stake,0.9trope"}, 543 {"2.0stake,1.0trope", "1.0other", ""}, 544 } 545 546 for i, tc := range testCases { 547 in1, err := sdk.ParseDecCoins(tc.input1) 548 require.NoError(t, err, "unexpected parse error in %v", i) 549 in2, err := sdk.ParseDecCoins(tc.input2) 550 require.NoError(t, err, "unexpected parse error in %v", i) 551 exr, err := sdk.ParseDecCoins(tc.expectedResult) 552 require.NoError(t, err, "unexpected parse error in %v", i) 553 554 require.True(t, in1.Intersect(in2).IsEqual(exr), "in1.cap(in2) != exr in %v", i) 555 } 556 } 557 558 func TestDecCoinsTruncateDecimal(t *testing.T) { 559 decCoinA := sdk.NewDecCoinFromDec("bar", sdk.MustNewDecFromStr("5.41")) 560 decCoinB := sdk.NewDecCoinFromDec("foo", sdk.MustNewDecFromStr("6.00")) 561 562 testCases := []struct { 563 input sdk.DecCoins 564 truncatedCoins sdk.SysCoins 565 changeCoins sdk.DecCoins 566 }{ 567 {sdk.DecCoins{}, sdk.SysCoins(nil), sdk.DecCoins(nil)}, 568 { 569 sdk.DecCoins{decCoinA, decCoinB}, 570 sdk.SysCoins{sdk.NewInt64Coin(decCoinA.Denom, 5), sdk.NewInt64Coin(decCoinB.Denom, 6)}, 571 sdk.DecCoins{sdk.NewDecCoinFromDec(decCoinA.Denom, sdk.MustNewDecFromStr("0.41"))}, 572 }, 573 { 574 sdk.DecCoins{decCoinB}, 575 sdk.SysCoins{sdk.NewInt64Coin(decCoinB.Denom, 6)}, 576 sdk.DecCoins(nil), 577 }, 578 } 579 580 for i, tc := range testCases { 581 truncatedCoins, changeCoins := tc.input.TruncateDecimal() 582 require.Equal( 583 t, tc.truncatedCoins, truncatedCoins, 584 "unexpected truncated coins; tc #%d, input: %s", i, tc.input, 585 ) 586 require.Equal( 587 t, tc.changeCoins, changeCoins, 588 "unexpected change coins; tc #%d, input: %s", i, tc.input, 589 ) 590 } 591 } 592 593 func TestDecCoinsQuoDecTruncate(t *testing.T) { 594 x := sdk.MustNewDecFromStr("1.00") 595 y := sdk.MustNewDecFromStr("10000000000000000000.00") 596 597 testCases := []struct { 598 coins sdk.DecCoins 599 input sdk.Dec 600 result sdk.DecCoins 601 panics bool 602 }{ 603 {sdk.DecCoins{}, sdk.ZeroDec(), sdk.DecCoins(nil), true}, 604 {sdk.DecCoins{sdk.NewDecCoinFromDec("foo", x)}, y, sdk.DecCoins(nil), false}, 605 {sdk.DecCoins{sdk.NewInt64DecCoin("foo", 5)}, sdk.NewDec(2), sdk.DecCoins{sdk.NewDecCoinFromDec("foo", sdk.MustNewDecFromStr("2.5"))}, false}, 606 } 607 608 for i, tc := range testCases { 609 tc := tc 610 if tc.panics { 611 require.Panics(t, func() { tc.coins.QuoDecTruncate(tc.input) }) 612 } else { 613 res := tc.coins.QuoDecTruncate(tc.input) 614 require.Equal(t, tc.result, res, "unexpected result; tc #%d, coins: %s, input: %s", i, tc.coins, tc.input) 615 } 616 } 617 }