github.com/cosmos/cosmos-sdk@v0.50.10/types/dec_coin_test.go (about) 1 package types_test 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/stretchr/testify/suite" 8 9 "cosmossdk.io/math" 10 11 sdk "github.com/cosmos/cosmos-sdk/types" 12 ) 13 14 type decCoinTestSuite struct { 15 suite.Suite 16 } 17 18 func TestDecCoinTestSuite(t *testing.T) { 19 suite.Run(t, new(decCoinTestSuite)) 20 } 21 22 func (s *decCoinTestSuite) TestNewDecCoin() { 23 s.Require().NotPanics(func() { 24 sdk.NewInt64DecCoin(testDenom1, 5) 25 }) 26 s.Require().NotPanics(func() { 27 sdk.NewInt64DecCoin(testDenom1, 0) 28 }) 29 s.Require().NotPanics(func() { 30 sdk.NewInt64DecCoin(strings.ToUpper(testDenom1), 5) 31 }) 32 s.Require().Panics(func() { 33 sdk.NewInt64DecCoin(testDenom1, -5) 34 }) 35 } 36 37 func (s *decCoinTestSuite) TestNewDecCoinFromDec() { 38 s.Require().NotPanics(func() { 39 sdk.NewDecCoinFromDec(testDenom1, math.LegacyNewDec(5)) 40 }) 41 s.Require().NotPanics(func() { 42 sdk.NewDecCoinFromDec(testDenom1, math.LegacyZeroDec()) 43 }) 44 s.Require().NotPanics(func() { 45 sdk.NewDecCoinFromDec(strings.ToUpper(testDenom1), math.LegacyNewDec(5)) 46 }) 47 s.Require().Panics(func() { 48 sdk.NewDecCoinFromDec(testDenom1, math.LegacyNewDec(-5)) 49 }) 50 } 51 52 func (s *decCoinTestSuite) TestNewDecCoinFromCoin() { 53 s.Require().NotPanics(func() { 54 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, math.NewInt(5)}) 55 }) 56 s.Require().NotPanics(func() { 57 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, math.NewInt(0)}) 58 }) 59 s.Require().NotPanics(func() { 60 sdk.NewDecCoinFromCoin(sdk.Coin{strings.ToUpper(testDenom1), math.NewInt(5)}) 61 }) 62 s.Require().Panics(func() { 63 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, math.NewInt(-5)}) 64 }) 65 } 66 67 func (s *decCoinTestSuite) TestDecCoinIsPositive() { 68 dc := sdk.NewInt64DecCoin(testDenom1, 5) 69 s.Require().True(dc.IsPositive()) 70 71 dc = sdk.NewInt64DecCoin(testDenom1, 0) 72 s.Require().False(dc.IsPositive()) 73 } 74 75 func (s *decCoinTestSuite) TestAddDecCoin() { 76 decCoinA1 := sdk.NewDecCoinFromDec(testDenom1, math.LegacyNewDecWithPrec(11, 1)) 77 decCoinA2 := sdk.NewDecCoinFromDec(testDenom1, math.LegacyNewDecWithPrec(22, 1)) 78 decCoinB1 := sdk.NewDecCoinFromDec(testDenom2, math.LegacyNewDecWithPrec(11, 1)) 79 80 // regular add 81 res := decCoinA1.Add(decCoinA1) 82 s.Require().Equal(decCoinA2, res, "sum of coins is incorrect") 83 84 // bad denom add 85 s.Require().Panics(func() { 86 decCoinA1.Add(decCoinB1) 87 }, "expected panic on sum of different denoms") 88 } 89 90 func (s *decCoinTestSuite) TestAddDecCoins() { 91 one := math.LegacyNewDec(1) 92 zero := math.LegacyNewDec(0) 93 two := math.LegacyNewDec(2) 94 95 cases := []struct { 96 inputOne sdk.DecCoins 97 inputTwo sdk.DecCoins 98 expected sdk.DecCoins 99 }{ 100 {sdk.DecCoins{{testDenom1, one}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, one}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, two}, {testDenom2, two}}}, 101 {sdk.DecCoins{{testDenom1, zero}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins{{testDenom2, one}}}, 102 {sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins(nil)}, 103 } 104 105 for tcIndex, tc := range cases { 106 res := tc.inputOne.Add(tc.inputTwo...) 107 s.Require().Equal(tc.expected, res, "sum of coins is incorrect, tc #%d", tcIndex) 108 } 109 } 110 111 func (s *decCoinTestSuite) TestFilteredZeroDecCoins() { 112 cases := []struct { 113 name string 114 input sdk.DecCoins 115 original string 116 expected string 117 panic bool 118 }{ 119 { 120 name: "all greater than zero", 121 input: sdk.DecCoins{ 122 {"testa", math.LegacyNewDec(1)}, 123 {"testb", math.LegacyNewDec(2)}, 124 {"testc", math.LegacyNewDec(3)}, 125 {"testd", math.LegacyNewDec(4)}, 126 {"teste", math.LegacyNewDec(5)}, 127 }, 128 original: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 129 expected: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 130 panic: false, 131 }, 132 { 133 name: "zero coin in middle", 134 input: sdk.DecCoins{ 135 {"testa", math.LegacyNewDec(1)}, 136 {"testb", math.LegacyNewDec(2)}, 137 {"testc", math.LegacyNewDec(0)}, 138 {"testd", math.LegacyNewDec(4)}, 139 {"teste", math.LegacyNewDec(5)}, 140 }, 141 original: "1.000000000000000000testa,2.000000000000000000testb,0.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 142 expected: "1.000000000000000000testa,2.000000000000000000testb,4.000000000000000000testd,5.000000000000000000teste", 143 panic: false, 144 }, 145 { 146 name: "zero coin end (unordered)", 147 input: sdk.DecCoins{ 148 {"teste", math.LegacyNewDec(5)}, 149 {"testc", math.LegacyNewDec(3)}, 150 {"testa", math.LegacyNewDec(1)}, 151 {"testd", math.LegacyNewDec(4)}, 152 {"testb", math.LegacyNewDec(0)}, 153 }, 154 original: "5.000000000000000000teste,3.000000000000000000testc,1.000000000000000000testa,4.000000000000000000testd,0.000000000000000000testb", 155 expected: "1.000000000000000000testa,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 156 panic: false, 157 }, 158 159 { 160 name: "panic when same denoms in multiple coins", 161 input: sdk.DecCoins{ 162 {"testa", math.LegacyNewDec(5)}, 163 {"testa", math.LegacyNewDec(3)}, 164 {"testa", math.LegacyNewDec(1)}, 165 {"testd", math.LegacyNewDec(4)}, 166 {"testb", math.LegacyNewDec(2)}, 167 }, 168 original: "5.000000000000000000teste,3.000000000000000000testc,1.000000000000000000testa,4.000000000000000000testd,0.000000000000000000testb", 169 expected: "1.000000000000000000testa,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 170 panic: true, 171 }, 172 } 173 174 for _, tt := range cases { 175 if tt.panic { 176 s.Require().Panics(func() { sdk.NewDecCoins(tt.input...) }, "Should panic due to multiple coins with same denom") 177 } else { 178 undertest := sdk.NewDecCoins(tt.input...) 179 s.Require().Equal(tt.expected, undertest.String(), "NewDecCoins must return expected results") 180 s.Require().Equal(tt.original, tt.input.String(), "input must be unmodified and match original") 181 } 182 } 183 } 184 185 func (s *decCoinTestSuite) TestIsValid() { 186 tests := []struct { 187 coin sdk.DecCoin 188 expectPass bool 189 msg string 190 }{ 191 { 192 sdk.NewDecCoin("mytoken", math.NewInt(10)), 193 true, 194 "valid coins should have passed", 195 }, 196 { 197 sdk.DecCoin{Denom: "BTC", Amount: math.LegacyNewDec(10)}, 198 true, 199 "valid uppercase denom", 200 }, 201 { 202 sdk.DecCoin{Denom: "Bitcoin", Amount: math.LegacyNewDec(10)}, 203 true, 204 "valid mixed case denom", 205 }, 206 { 207 sdk.DecCoin{Denom: "btc", Amount: math.LegacyNewDec(-10)}, 208 false, 209 "negative amount", 210 }, 211 } 212 213 for _, tc := range tests { 214 tc := tc 215 if tc.expectPass { 216 s.Require().True(tc.coin.IsValid(), tc.msg) 217 } else { 218 s.Require().False(tc.coin.IsValid(), tc.msg) 219 } 220 } 221 } 222 223 func (s *decCoinTestSuite) TestSubDecCoin() { 224 tests := []struct { 225 coin sdk.DecCoin 226 expectPass bool 227 msg string 228 }{ 229 { 230 sdk.NewDecCoin("mytoken", math.NewInt(20)), 231 true, 232 "valid coins should have passed", 233 }, 234 { 235 sdk.NewDecCoin("othertoken", math.NewInt(20)), 236 false, 237 "denom mismatch", 238 }, 239 { 240 sdk.NewDecCoin("mytoken", math.NewInt(9)), 241 false, 242 "negative amount", 243 }, 244 } 245 246 decCoin := sdk.NewDecCoin("mytoken", math.NewInt(10)) 247 248 for _, tc := range tests { 249 tc := tc 250 if tc.expectPass { 251 equal := tc.coin.Sub(decCoin) 252 s.Require().Equal(equal, decCoin, tc.msg) 253 } else { 254 s.Require().Panics(func() { tc.coin.Sub(decCoin) }, tc.msg) 255 } 256 } 257 } 258 259 func (s *decCoinTestSuite) TestSubDecCoins() { 260 tests := []struct { 261 coins sdk.DecCoins 262 expectPass bool 263 msg string 264 }{ 265 { 266 sdk.NewDecCoinsFromCoins(sdk.NewCoin("mytoken", math.NewInt(10)), sdk.NewCoin("btc", math.NewInt(20)), sdk.NewCoin("eth", math.NewInt(30))), 267 true, 268 "sorted coins should have passed", 269 }, 270 { 271 sdk.DecCoins{sdk.NewDecCoin("mytoken", math.NewInt(10)), sdk.NewDecCoin("btc", math.NewInt(20)), sdk.NewDecCoin("eth", math.NewInt(30))}, 272 false, 273 "unorted coins should panic", 274 }, 275 { 276 sdk.DecCoins{sdk.DecCoin{Denom: "BTC", Amount: math.LegacyNewDec(10)}, sdk.NewDecCoin("eth", math.NewInt(15)), sdk.NewDecCoin("mytoken", math.NewInt(5))}, 277 false, 278 "invalid denoms", 279 }, 280 } 281 282 decCoins := sdk.NewDecCoinsFromCoins(sdk.NewCoin("btc", math.NewInt(10)), sdk.NewCoin("eth", math.NewInt(15)), sdk.NewCoin("mytoken", math.NewInt(5))) 283 284 for _, tc := range tests { 285 tc := tc 286 if tc.expectPass { 287 equal := tc.coins.Sub(decCoins) 288 s.Require().Equal(equal, decCoins, tc.msg) 289 } else { 290 s.Require().Panics(func() { tc.coins.Sub(decCoins) }, tc.msg) 291 } 292 } 293 } 294 295 func (s *decCoinTestSuite) TestSortDecCoins() { 296 good := sdk.DecCoins{ 297 sdk.NewInt64DecCoin("gas", 1), 298 sdk.NewInt64DecCoin("mineral", 1), 299 sdk.NewInt64DecCoin("tree", 1), 300 } 301 empty := sdk.DecCoins{ 302 sdk.NewInt64DecCoin("gold", 0), 303 } 304 badSort1 := sdk.DecCoins{ 305 sdk.NewInt64DecCoin("tree", 1), 306 sdk.NewInt64DecCoin("gas", 1), 307 sdk.NewInt64DecCoin("mineral", 1), 308 } 309 badSort2 := sdk.DecCoins{ // both are after the first one, but the second and third are in the wrong order 310 sdk.NewInt64DecCoin("gas", 1), 311 sdk.NewInt64DecCoin("tree", 1), 312 sdk.NewInt64DecCoin("mineral", 1), 313 } 314 badAmt := sdk.DecCoins{ 315 sdk.NewInt64DecCoin("gas", 1), 316 sdk.NewInt64DecCoin("tree", 0), 317 sdk.NewInt64DecCoin("mineral", 1), 318 } 319 dup := sdk.DecCoins{ 320 sdk.NewInt64DecCoin("gas", 1), 321 sdk.NewInt64DecCoin("gas", 1), 322 sdk.NewInt64DecCoin("mineral", 1), 323 } 324 cases := []struct { 325 name string 326 coins sdk.DecCoins 327 before, after bool // valid before/after sort 328 }{ 329 {"valid coins", good, true, true}, 330 {"empty coins", empty, false, false}, 331 {"unsorted coins (1)", badSort1, false, true}, 332 {"unsorted coins (2)", badSort2, false, true}, 333 {"zero amount coins", badAmt, false, false}, 334 {"duplicate coins", dup, false, false}, 335 } 336 337 for _, tc := range cases { 338 s.Require().Equal(tc.before, tc.coins.IsValid(), "coin validity is incorrect before sorting; %s", tc.name) 339 tc.coins.Sort() 340 s.Require().Equal(tc.after, tc.coins.IsValid(), "coin validity is incorrect after sorting; %s", tc.name) 341 } 342 } 343 344 func (s *decCoinTestSuite) TestDecCoinsValidate() { 345 testCases := []struct { 346 input sdk.DecCoins 347 expectedPass bool 348 }{ 349 {sdk.DecCoins{}, true}, 350 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, true}, 351 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(100000)}}, true}, 352 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(-5)}}, false}, 353 {sdk.DecCoins{sdk.DecCoin{"BTC", math.LegacyNewDec(5)}}, true}, 354 {sdk.DecCoins{sdk.DecCoin{"0BTC", math.LegacyNewDec(5)}}, false}, 355 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}, sdk.DecCoin{"B", math.LegacyNewDec(100000)}}, false}, 356 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(-100000)}}, false}, 357 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(-5)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(100000)}}, false}, 358 {sdk.DecCoins{sdk.DecCoin{"BTC", math.LegacyNewDec(5)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(100000)}}, true}, 359 {sdk.DecCoins{sdk.DecCoin{"0BTC", math.LegacyNewDec(5)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(100000)}}, false}, 360 } 361 362 for i, tc := range testCases { 363 err := tc.input.Validate() 364 if tc.expectedPass { 365 s.Require().NoError(err, "unexpected result for test case #%d, input: %v", i, tc.input) 366 } else { 367 s.Require().Error(err, "unexpected result for test case #%d, input: %v", i, tc.input) 368 } 369 } 370 } 371 372 func (s *decCoinTestSuite) TestParseDecCoins() { 373 testCases := []struct { 374 input string 375 expectedResult sdk.DecCoins 376 expectedErr bool 377 }{ 378 {"", nil, false}, 379 {"4stake", sdk.DecCoins{sdk.NewDecCoinFromDec("stake", math.LegacyNewDecFromInt(math.NewInt(4)))}, false}, 380 {"5.5atom,4stake", sdk.DecCoins{ 381 sdk.NewDecCoinFromDec("atom", math.LegacyNewDecWithPrec(5500000000000000000, math.LegacyPrecision)), 382 sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(4)), 383 }, false}, 384 {"0.0stake", sdk.DecCoins{}, false}, // remove zero coins 385 {"10.0btc,1.0atom,20.0btc", nil, true}, 386 { 387 "0.004STAKE", 388 sdk.DecCoins{sdk.NewDecCoinFromDec("STAKE", math.LegacyNewDecWithPrec(4000000000000000, math.LegacyPrecision))}, 389 false, 390 }, 391 { 392 "0.004stake", 393 sdk.DecCoins{sdk.NewDecCoinFromDec("stake", math.LegacyNewDecWithPrec(4000000000000000, math.LegacyPrecision))}, 394 false, 395 }, 396 { 397 "5.04atom,0.004stake", 398 sdk.DecCoins{ 399 sdk.NewDecCoinFromDec("atom", math.LegacyNewDecWithPrec(5040000000000000000, math.LegacyPrecision)), 400 sdk.NewDecCoinFromDec("stake", math.LegacyNewDecWithPrec(4000000000000000, math.LegacyPrecision)), 401 }, 402 false, 403 }, 404 { 405 "0.0stake,0.004stake,5.04atom", // remove zero coins 406 sdk.DecCoins{ 407 sdk.NewDecCoinFromDec("atom", math.LegacyNewDecWithPrec(5040000000000000000, math.LegacyPrecision)), 408 sdk.NewDecCoinFromDec("stake", math.LegacyNewDecWithPrec(4000000000000000, math.LegacyPrecision)), 409 }, 410 false, 411 }, 412 } 413 414 for i, tc := range testCases { 415 res, err := sdk.ParseDecCoins(tc.input) 416 if tc.expectedErr { 417 s.Require().Error(err, "expected error for test case #%d, input: %v", i, tc.input) 418 } else { 419 s.Require().NoError(err, "unexpected error for test case #%d, input: %v", i, tc.input) 420 s.Require().Equal(tc.expectedResult, res, "unexpected result for test case #%d, input: %v", i, tc.input) 421 } 422 } 423 } 424 425 func (s *decCoinTestSuite) TestDecCoinsString() { 426 testCases := []struct { 427 input sdk.DecCoins 428 expected string 429 }{ 430 {sdk.DecCoins{}, ""}, 431 { 432 sdk.DecCoins{ 433 sdk.NewDecCoinFromDec("atom", math.LegacyNewDecWithPrec(5040000000000000000, math.LegacyPrecision)), 434 sdk.NewDecCoinFromDec("stake", math.LegacyNewDecWithPrec(4000000000000000, math.LegacyPrecision)), 435 }, 436 "5.040000000000000000atom,0.004000000000000000stake", 437 }, 438 } 439 440 for i, tc := range testCases { 441 out := tc.input.String() 442 s.Require().Equal(tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input) 443 } 444 } 445 446 func (s *decCoinTestSuite) TestDecCoinsIntersect() { 447 testCases := []struct { 448 input1 string 449 input2 string 450 expectedResult string 451 }{ 452 {"", "", ""}, 453 {"1.0stake", "", ""}, 454 {"1.0stake", "1.0stake", "1.0stake"}, 455 {"", "1.0stake", ""}, 456 {"1.0stake", "", ""}, 457 {"2.0stake,1.0trope", "1.9stake", "1.9stake"}, 458 {"2.0stake,1.0trope", "2.1stake", "2.0stake"}, 459 {"2.0stake,1.0trope", "0.9trope", "0.9trope"}, 460 {"2.0stake,1.0trope", "1.9stake,0.9trope", "1.9stake,0.9trope"}, 461 {"2.0stake,1.0trope", "1.9stake,0.9trope,20.0other", "1.9stake,0.9trope"}, 462 {"2.0stake,1.0trope", "1.0other", ""}, 463 } 464 465 for i, tc := range testCases { 466 in1, err := sdk.ParseDecCoins(tc.input1) 467 s.Require().NoError(err, "unexpected parse error in %v", i) 468 in2, err := sdk.ParseDecCoins(tc.input2) 469 s.Require().NoError(err, "unexpected parse error in %v", i) 470 exr, err := sdk.ParseDecCoins(tc.expectedResult) 471 s.Require().NoError(err, "unexpected parse error in %v", i) 472 s.Require().True(in1.Intersect(in2).Equal(exr), "in1.cap(in2) != exr in %v", i) 473 } 474 } 475 476 func (s *decCoinTestSuite) TestDecCoinsTruncateDecimal() { 477 decCoinA := sdk.NewDecCoinFromDec("bar", math.LegacyMustNewDecFromStr("5.41")) 478 decCoinB := sdk.NewDecCoinFromDec("foo", math.LegacyMustNewDecFromStr("6.00")) 479 480 testCases := []struct { 481 input sdk.DecCoins 482 truncatedCoins sdk.Coins 483 changeCoins sdk.DecCoins 484 }{ 485 {sdk.DecCoins{}, sdk.Coins(nil), sdk.DecCoins(nil)}, 486 { 487 sdk.DecCoins{decCoinA, decCoinB}, 488 sdk.Coins{sdk.NewInt64Coin(decCoinA.Denom, 5), sdk.NewInt64Coin(decCoinB.Denom, 6)}, 489 sdk.DecCoins{sdk.NewDecCoinFromDec(decCoinA.Denom, math.LegacyMustNewDecFromStr("0.41"))}, 490 }, 491 { 492 sdk.DecCoins{decCoinB}, 493 sdk.Coins{sdk.NewInt64Coin(decCoinB.Denom, 6)}, 494 sdk.DecCoins(nil), 495 }, 496 } 497 498 for i, tc := range testCases { 499 truncatedCoins, changeCoins := tc.input.TruncateDecimal() 500 s.Require().Equal( 501 tc.truncatedCoins, truncatedCoins, 502 "unexpected truncated coins; tc #%d, input: %s", i, tc.input, 503 ) 504 s.Require().Equal( 505 tc.changeCoins, changeCoins, 506 "unexpected change coins; tc #%d, input: %s", i, tc.input, 507 ) 508 } 509 } 510 511 func (s *decCoinTestSuite) TestDecCoinsQuoDecTruncate() { 512 x := math.LegacyMustNewDecFromStr("1.00") 513 y := math.LegacyMustNewDecFromStr("10000000000000000000.00") 514 515 testCases := []struct { 516 coins sdk.DecCoins 517 input math.LegacyDec 518 result sdk.DecCoins 519 panics bool 520 }{ 521 {sdk.DecCoins{}, math.LegacyZeroDec(), sdk.DecCoins(nil), true}, 522 {sdk.DecCoins{sdk.NewDecCoinFromDec("foo", x)}, y, sdk.DecCoins(nil), false}, 523 {sdk.DecCoins{sdk.NewInt64DecCoin("foo", 5)}, math.LegacyNewDec(2), sdk.DecCoins{sdk.NewDecCoinFromDec("foo", math.LegacyMustNewDecFromStr("2.5"))}, false}, 524 } 525 526 for i, tc := range testCases { 527 tc := tc 528 if tc.panics { 529 s.Require().Panics(func() { tc.coins.QuoDecTruncate(tc.input) }) 530 } else { 531 res := tc.coins.QuoDecTruncate(tc.input) 532 s.Require().Equal(tc.result, res, "unexpected result; tc #%d, coins: %s, input: %s", i, tc.coins, tc.input) 533 } 534 } 535 } 536 537 func (s *decCoinTestSuite) TestNewDecCoinsWithIsValid() { 538 fake1 := append(sdk.NewDecCoins(sdk.NewDecCoin("mytoken", math.NewInt(10))), sdk.DecCoin{Denom: "10BTC", Amount: math.LegacyNewDec(10)}) 539 fake2 := append(sdk.NewDecCoins(sdk.NewDecCoin("mytoken", math.NewInt(10))), sdk.DecCoin{Denom: "BTC", Amount: math.LegacyNewDec(-10)}) 540 541 tests := []struct { 542 coin sdk.DecCoins 543 expectPass bool 544 msg string 545 }{ 546 { 547 sdk.NewDecCoins(sdk.NewDecCoin("mytoken", math.NewInt(10))), 548 true, 549 "valid coins should have passed", 550 }, 551 { 552 fake1, 553 false, 554 "invalid denoms", 555 }, 556 { 557 fake2, 558 false, 559 "negative amount", 560 }, 561 } 562 563 for _, tc := range tests { 564 tc := tc 565 if tc.expectPass { 566 s.Require().True(tc.coin.IsValid(), tc.msg) 567 } else { 568 s.Require().False(tc.coin.IsValid(), tc.msg) 569 } 570 } 571 } 572 573 func (s *decCoinTestSuite) TestNewDecCoinsWithZeroCoins() { 574 zeroCoins := append(sdk.NewCoins(sdk.NewCoin("mytoken", math.NewInt(0))), sdk.Coin{Denom: "wbtc", Amount: math.NewInt(10)}) 575 576 tests := []struct { 577 coins sdk.Coins 578 expectLength int 579 }{ 580 { 581 sdk.NewCoins(sdk.NewCoin("mytoken", math.NewInt(10)), sdk.NewCoin("wbtc", math.NewInt(10))), 582 2, 583 }, 584 { 585 zeroCoins, 586 1, 587 }, 588 } 589 590 for _, tc := range tests { 591 tc := tc 592 s.Require().Equal(sdk.NewDecCoinsFromCoins(tc.coins...).Len(), tc.expectLength) 593 } 594 } 595 596 func (s *decCoinTestSuite) TestDecCoins_AddDecCoinWithIsValid() { 597 lengthTestDecCoins := sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", math.NewInt(10))).Add(sdk.DecCoin{Denom: "BTC", Amount: math.LegacyNewDec(10)}) 598 s.Require().Equal(2, len(lengthTestDecCoins), "should be 2") 599 600 tests := []struct { 601 coin sdk.DecCoins 602 expectPass bool 603 msg string 604 }{ 605 { 606 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", math.NewInt(10))), 607 true, 608 "valid coins should have passed", 609 }, 610 { 611 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", math.NewInt(10))).Add(sdk.DecCoin{Denom: "0BTC", Amount: math.LegacyNewDec(10)}), 612 false, 613 "invalid denoms", 614 }, 615 { 616 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", math.NewInt(10))).Add(sdk.DecCoin{Denom: "BTC", Amount: math.LegacyNewDec(-10)}), 617 false, 618 "negative amount", 619 }, 620 } 621 622 for _, tc := range tests { 623 tc := tc 624 if tc.expectPass { 625 s.Require().True(tc.coin.IsValid(), tc.msg) 626 } else { 627 s.Require().False(tc.coin.IsValid(), tc.msg) 628 } 629 } 630 } 631 632 func (s *decCoinTestSuite) TestDecCoins_Empty() { 633 testCases := []struct { 634 input sdk.DecCoins 635 expectedResult bool 636 msg string 637 }{ 638 {sdk.DecCoins{}, true, "No coins as expected."}, 639 {sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, false, "DecCoins is not empty"}, 640 } 641 642 for _, tc := range testCases { 643 if tc.expectedResult { 644 s.Require().True(tc.input.Empty(), tc.msg) 645 } else { 646 s.Require().False(tc.input.Empty(), tc.msg) 647 } 648 } 649 } 650 651 func (s *decCoinTestSuite) TestDecCoins_GetDenomByIndex() { 652 testCases := []struct { 653 name string 654 input sdk.DecCoins 655 index int 656 expectedResult string 657 expectedErr bool 658 }{ 659 { 660 "No DecCoins in Slice", 661 sdk.DecCoins{}, 662 0, 663 "", 664 true, 665 }, 666 {"When index out of bounds", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, 2, "", true}, 667 {"When negative index", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, -1, "", true}, 668 { 669 "Appropriate index case", 670 sdk.DecCoins{ 671 sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}, 672 sdk.DecCoin{testDenom2, math.LegacyNewDec(57)}, 673 }, 674 1, testDenom2, false, 675 }, 676 } 677 678 for i, tc := range testCases { 679 tc := tc 680 s.T().Run(tc.name, func(t *testing.T) { 681 if tc.expectedErr { 682 s.Require().Panics(func() { tc.input.GetDenomByIndex(tc.index) }, "Test should have panicked") 683 } else { 684 res := tc.input.GetDenomByIndex(tc.index) 685 s.Require().Equal(tc.expectedResult, res, "Unexpected result for test case #%d, expected output: %s, input: %v", i, tc.expectedResult, tc.input) 686 } 687 }) 688 } 689 } 690 691 func (s *decCoinTestSuite) TestDecCoins_IsAllPositive() { 692 testCases := []struct { 693 name string 694 input sdk.DecCoins 695 expectedResult bool 696 }{ 697 {"No Coins", sdk.DecCoins{}, false}, 698 699 {"One Coin - Zero value", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}}, false}, 700 701 {"One Coin - Positive value", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, true}, 702 703 {"One Coin - Negative value", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(-15)}}, false}, 704 705 {"Multiple Coins - All positive value", sdk.DecCoins{ 706 sdk.DecCoin{testDenom1, math.LegacyNewDec(51)}, 707 sdk.DecCoin{testDenom1, math.LegacyNewDec(123)}, 708 sdk.DecCoin{testDenom1, math.LegacyNewDec(50)}, 709 sdk.DecCoin{testDenom1, math.LegacyNewDec(92233720)}, 710 }, true}, 711 712 {"Multiple Coins - Some negative value", sdk.DecCoins{ 713 sdk.DecCoin{testDenom1, math.LegacyNewDec(51)}, 714 sdk.DecCoin{testDenom1, math.LegacyNewDec(-123)}, 715 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 716 sdk.DecCoin{testDenom1, math.LegacyNewDec(92233720)}, 717 }, false}, 718 } 719 720 for i, tc := range testCases { 721 tc := tc 722 s.T().Run(tc.name, func(t *testing.T) { 723 if tc.expectedResult { 724 s.Require().True(tc.input.IsAllPositive(), "Test case #%d: %s", i, tc.name) 725 } else { 726 s.Require().False(tc.input.IsAllPositive(), "Test case #%d: %s", i, tc.name) 727 } 728 }) 729 } 730 } 731 732 func (s *decCoinTestSuite) TestDecCoin_IsLT() { 733 testCases := []struct { 734 name string 735 coin sdk.DecCoin 736 otherCoin sdk.DecCoin 737 expectedResult bool 738 expectedPanic bool 739 }{ 740 {"Same Denom - Less than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(19)}, true, false}, 741 742 {"Same Denom - Greater than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(343340)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(14)}, false, false}, 743 744 {"Same Denom - Same as other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, false, false}, 745 746 {"Different Denom - Less than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(19)}, true, true}, 747 748 {"Different Denom - Greater than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(343340)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(14)}, true, true}, 749 750 {"Different Denom - Same as other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(20)}, true, true}, 751 } 752 753 for i, tc := range testCases { 754 s.T().Run(tc.name, func(t *testing.T) { 755 if tc.expectedPanic { 756 s.Require().Panics(func() { tc.coin.IsLT(tc.otherCoin) }, "Test case #%d: %s", i, tc.name) 757 } else { 758 res := tc.coin.IsLT(tc.otherCoin) 759 if tc.expectedResult { 760 s.Require().True(res, "Test case #%d: %s", i, tc.name) 761 } else { 762 s.Require().False(res, "Test case #%d: %s", i, tc.name) 763 } 764 } 765 }) 766 } 767 } 768 769 func (s *decCoinTestSuite) TestDecCoin_IsGTE() { 770 testCases := []struct { 771 name string 772 coin sdk.DecCoin 773 otherCoin sdk.DecCoin 774 expectedResult bool 775 expectedPanic bool 776 }{ 777 {"Same Denom - Less than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(19)}, false, false}, 778 779 {"Same Denom - Greater than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(343340)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(14)}, true, false}, 780 781 {"Same Denom - Same as other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, true, false}, 782 783 {"Different Denom - Less than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(19)}, true, true}, 784 785 {"Different Denom - Greater than other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(343340)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(14)}, true, true}, 786 787 {"Different Denom - Same as other coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, sdk.DecCoin{testDenom2, math.LegacyNewDec(20)}, true, true}, 788 } 789 790 for i, tc := range testCases { 791 tc := tc 792 s.T().Run(tc.name, func(t *testing.T) { 793 if tc.expectedPanic { 794 s.Require().Panics(func() { tc.coin.IsGTE(tc.otherCoin) }, "Test case #%d: %s", i, tc.name) 795 } else { 796 res := tc.coin.IsGTE(tc.otherCoin) 797 if tc.expectedResult { 798 s.Require().True(res, "Test case #%d: %s", i, tc.name) 799 } else { 800 s.Require().False(res, "Test case #%d: %s", i, tc.name) 801 } 802 } 803 }) 804 } 805 } 806 807 func (s *decCoinTestSuite) TestDecCoins_IsZero() { 808 testCases := []struct { 809 name string 810 coins sdk.DecCoins 811 expectedResult bool 812 }{ 813 {"No Coins", sdk.DecCoins{}, true}, 814 815 {"One Coin - Zero value", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}}, true}, 816 817 {"One Coin - Positive value", sdk.DecCoins{sdk.DecCoin{testDenom1, math.LegacyNewDec(5)}}, false}, 818 819 {"Multiple Coins - All zero value", sdk.DecCoins{ 820 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 821 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 822 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 823 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 824 }, true}, 825 826 {"Multiple Coins - Some positive value", sdk.DecCoins{ 827 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 828 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 829 sdk.DecCoin{testDenom1, math.LegacyNewDec(0)}, 830 sdk.DecCoin{testDenom1, math.LegacyNewDec(92233720)}, 831 }, false}, 832 } 833 834 for i, tc := range testCases { 835 tc := tc 836 s.T().Run(tc.name, func(t *testing.T) { 837 if tc.expectedResult { 838 s.Require().True(tc.coins.IsZero(), "Test case #%d: %s", i, tc.name) 839 } else { 840 s.Require().False(tc.coins.IsZero(), "Test case #%d: %s", i, tc.name) 841 } 842 }) 843 } 844 } 845 846 func (s *decCoinTestSuite) TestDecCoins_MulDec() { 847 testCases := []struct { 848 name string 849 coins sdk.DecCoins 850 multiplier math.LegacyDec 851 expectedResult sdk.DecCoins 852 }{ 853 {"No Coins", sdk.DecCoins{}, math.LegacyNewDec(1), sdk.DecCoins(nil)}, 854 855 {"Multiple coins - zero multiplier", sdk.DecCoins{ 856 sdk.DecCoin{testDenom1, math.LegacyNewDec(10)}, 857 sdk.DecCoin{testDenom1, math.LegacyNewDec(30)}, 858 }, math.LegacyNewDec(0), sdk.DecCoins(nil)}, 859 860 {"Multiple coins - positive multiplier", sdk.DecCoins{ 861 sdk.DecCoin{testDenom1, math.LegacyNewDec(1)}, 862 sdk.DecCoin{testDenom1, math.LegacyNewDec(2)}, 863 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 864 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 865 }, math.LegacyNewDec(2), sdk.DecCoins{ 866 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 867 }}, 868 869 {"Multiple coins - negative multiplier", sdk.DecCoins{ 870 sdk.DecCoin{testDenom1, math.LegacyNewDec(1)}, 871 sdk.DecCoin{testDenom1, math.LegacyNewDec(2)}, 872 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 873 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 874 }, math.LegacyNewDec(-2), sdk.DecCoins{ 875 sdk.DecCoin{testDenom1, math.LegacyNewDec(-20)}, 876 }}, 877 878 {"Multiple coins - Different denom", sdk.DecCoins{ 879 sdk.DecCoin{testDenom1, math.LegacyNewDec(1)}, 880 sdk.DecCoin{testDenom2, math.LegacyNewDec(2)}, 881 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 882 sdk.DecCoin{testDenom2, math.LegacyNewDec(4)}, 883 }, math.LegacyNewDec(2), sdk.DecCoins{ 884 sdk.DecCoin{testDenom1, math.LegacyNewDec(8)}, 885 sdk.DecCoin{testDenom2, math.LegacyNewDec(12)}, 886 }}, 887 } 888 889 for i, tc := range testCases { 890 tc := tc 891 s.T().Run(tc.name, func(t *testing.T) { 892 res := tc.coins.MulDec(tc.multiplier) 893 s.Require().Equal(tc.expectedResult, res, "Test case #%d: %s", i, tc.name) 894 }) 895 } 896 } 897 898 func (s *decCoinTestSuite) TestDecCoins_MulDecTruncate() { 899 testCases := []struct { 900 name string 901 coins sdk.DecCoins 902 multiplier math.LegacyDec 903 expectedResult sdk.DecCoins 904 expectedPanic bool 905 }{ 906 {"No Coins", sdk.DecCoins{}, math.LegacyNewDec(1), sdk.DecCoins(nil), false}, 907 908 {"Multiple coins - zero multiplier", sdk.DecCoins{ 909 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(10, 3)}, 910 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(30, 2)}, 911 }, math.LegacyNewDec(0), sdk.DecCoins{}, false}, 912 913 {"Multiple coins - positive multiplier", sdk.DecCoins{ 914 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 915 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 916 }, math.LegacyNewDec(1), sdk.DecCoins{ 917 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(3, 0)}, 918 }, false}, 919 920 {"Multiple coins - positive multiplier", sdk.DecCoins{ 921 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 922 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 923 }, math.LegacyNewDec(-2), sdk.DecCoins{ 924 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(-6, 0)}, 925 }, false}, 926 927 {"Multiple coins - Different denom", sdk.DecCoins{ 928 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 929 sdk.DecCoin{testDenom2, math.LegacyNewDecWithPrec(3333, 4)}, 930 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(15, 1)}, 931 sdk.DecCoin{testDenom2, math.LegacyNewDecWithPrec(333, 4)}, 932 }, math.LegacyNewDec(10), sdk.DecCoins{ 933 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(30, 0)}, 934 sdk.DecCoin{testDenom2, math.LegacyNewDecWithPrec(3666, 3)}, 935 }, false}, 936 } 937 938 for i, tc := range testCases { 939 tc := tc 940 s.T().Run(tc.name, func(t *testing.T) { 941 if tc.expectedPanic { 942 s.Require().Panics(func() { tc.coins.MulDecTruncate(tc.multiplier) }, "Test case #%d: %s", i, tc.name) 943 } else { 944 res := tc.coins.MulDecTruncate(tc.multiplier) 945 s.Require().Equal(tc.expectedResult, res, "Test case #%d: %s", i, tc.name) 946 } 947 }) 948 } 949 } 950 951 func (s *decCoinTestSuite) TestDecCoins_QuoDec() { 952 testCases := []struct { 953 name string 954 coins sdk.DecCoins 955 input math.LegacyDec 956 expectedResult sdk.DecCoins 957 panics bool 958 }{ 959 {"No Coins", sdk.DecCoins{}, math.LegacyNewDec(1), sdk.DecCoins(nil), false}, 960 961 {"Multiple coins - zero input", sdk.DecCoins{ 962 sdk.DecCoin{testDenom1, math.LegacyNewDec(10)}, 963 sdk.DecCoin{testDenom1, math.LegacyNewDec(30)}, 964 }, math.LegacyNewDec(0), sdk.DecCoins(nil), true}, 965 966 {"Multiple coins - positive input", sdk.DecCoins{ 967 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 968 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 969 }, math.LegacyNewDec(2), sdk.DecCoins{ 970 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(35, 1)}, 971 }, false}, 972 973 {"Multiple coins - negative input", sdk.DecCoins{ 974 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 975 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 976 }, math.LegacyNewDec(-2), sdk.DecCoins{ 977 sdk.DecCoin{testDenom1, math.LegacyNewDecWithPrec(-35, 1)}, 978 }, false}, 979 980 {"Multiple coins - Different input", sdk.DecCoins{ 981 sdk.DecCoin{testDenom1, math.LegacyNewDec(1)}, 982 sdk.DecCoin{testDenom2, math.LegacyNewDec(2)}, 983 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 984 sdk.DecCoin{testDenom2, math.LegacyNewDec(4)}, 985 }, math.LegacyNewDec(2), sdk.DecCoins{ 986 sdk.DecCoin{testDenom1, math.LegacyNewDec(2)}, 987 sdk.DecCoin{testDenom2, math.LegacyNewDec(3)}, 988 }, false}, 989 } 990 991 for i, tc := range testCases { 992 tc := tc 993 s.T().Run(tc.name, func(t *testing.T) { 994 if tc.panics { 995 s.Require().Panics(func() { tc.coins.QuoDec(tc.input) }, "Test case #%d: %s", i, tc.name) 996 } else { 997 res := tc.coins.QuoDec(tc.input) 998 s.Require().Equal(tc.expectedResult, res, "Test case #%d: %s", i, tc.name) 999 } 1000 }) 1001 } 1002 } 1003 1004 func (s *decCoinTestSuite) TestDecCoin_IsEqual() { 1005 testCases := []struct { 1006 name string 1007 coin sdk.DecCoin 1008 otherCoin sdk.DecCoin 1009 expectedResult bool 1010 }{ 1011 { 1012 "Different Denom Same Amount", 1013 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 1014 sdk.DecCoin{testDenom2, math.LegacyNewDec(20)}, 1015 false, 1016 }, 1017 1018 { 1019 "Different Denom Different Amount", 1020 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 1021 sdk.DecCoin{testDenom2, math.LegacyNewDec(10)}, 1022 false, 1023 }, 1024 1025 { 1026 "Same Denom Different Amount", 1027 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 1028 sdk.DecCoin{testDenom1, math.LegacyNewDec(10)}, 1029 false, 1030 }, 1031 1032 { 1033 "Same Denom Same Amount", 1034 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 1035 sdk.DecCoin{testDenom1, math.LegacyNewDec(20)}, 1036 true, 1037 }, 1038 } 1039 1040 for i, tc := range testCases { 1041 s.T().Run(tc.name, func(t *testing.T) { 1042 res := tc.coin.IsEqual(tc.otherCoin) 1043 if tc.expectedResult { 1044 s.Require().True(res, "Test case #%d: %s", i, tc.name) 1045 } else { 1046 s.Require().False(res, "Test case #%d: %s", i, tc.name) 1047 } 1048 }) 1049 } 1050 } 1051 1052 func (s *decCoinTestSuite) TestDecCoins_IsEqual() { 1053 testCases := []struct { 1054 name string 1055 coinsA sdk.DecCoins 1056 coinsB sdk.DecCoins 1057 expectedResult bool 1058 }{ 1059 {"Different length sets", sdk.DecCoins{ 1060 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 1061 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 1062 }, sdk.DecCoins{ 1063 sdk.DecCoin{testDenom1, math.LegacyNewDec(35)}, 1064 }, false}, 1065 1066 {"Same length - different denoms", sdk.DecCoins{ 1067 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 1068 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 1069 }, sdk.DecCoins{ 1070 sdk.DecCoin{testDenom2, math.LegacyNewDec(3)}, 1071 sdk.DecCoin{testDenom2, math.LegacyNewDec(4)}, 1072 }, false}, 1073 1074 {"Same length - different amounts", sdk.DecCoins{ 1075 sdk.DecCoin{testDenom1, math.LegacyNewDec(3)}, 1076 sdk.DecCoin{testDenom1, math.LegacyNewDec(4)}, 1077 }, sdk.DecCoins{ 1078 sdk.DecCoin{testDenom1, math.LegacyNewDec(41)}, 1079 sdk.DecCoin{testDenom1, math.LegacyNewDec(343)}, 1080 }, false}, 1081 1082 {"Same length - same amounts", sdk.DecCoins{ 1083 sdk.DecCoin{testDenom1, math.LegacyNewDec(33)}, 1084 sdk.DecCoin{testDenom1, math.LegacyNewDec(344)}, 1085 }, sdk.DecCoins{ 1086 sdk.DecCoin{testDenom1, math.LegacyNewDec(33)}, 1087 sdk.DecCoin{testDenom1, math.LegacyNewDec(344)}, 1088 }, true}, 1089 } 1090 1091 for i, tc := range testCases { 1092 s.T().Run(tc.name, func(t *testing.T) { 1093 res := tc.coinsA.Equal(tc.coinsB) 1094 if tc.expectedResult { 1095 s.Require().True(res, "Test case #%d: %s", i, tc.name) 1096 } else { 1097 s.Require().False(res, "Test case #%d: %s", i, tc.name) 1098 } 1099 }) 1100 } 1101 } 1102 1103 func (s *decCoinTestSuite) TestDecCoin_Validate() { 1104 var empty sdk.DecCoin 1105 testCases := []struct { 1106 name string 1107 input sdk.DecCoin 1108 expectedPass bool 1109 }{ 1110 {"Uninitialized deccoin", empty, false}, 1111 1112 {"Invalid denom string", sdk.DecCoin{"(){9**&})", math.LegacyNewDec(33)}, false}, 1113 1114 {"Negative coin amount", sdk.DecCoin{testDenom1, math.LegacyNewDec(-33)}, false}, 1115 1116 {"Valid coin", sdk.DecCoin{testDenom1, math.LegacyNewDec(33)}, true}, 1117 } 1118 1119 for i, tc := range testCases { 1120 s.T().Run(tc.name, func(t *testing.T) { 1121 err := tc.input.Validate() 1122 if tc.expectedPass { 1123 s.Require().NoError(err, "unexpected result for test case #%d %s, input: %v", i, tc.name, tc.input) 1124 } else { 1125 s.Require().Error(err, "unexpected result for test case #%d %s, input: %v", i, tc.name, tc.input) 1126 } 1127 }) 1128 } 1129 } 1130 1131 func (s *decCoinTestSuite) TestDecCoin_ParseDecCoin() { 1132 var empty sdk.DecCoin 1133 testCases := []struct { 1134 name string 1135 input string 1136 expectedResult sdk.DecCoin 1137 expectedErr bool 1138 }{ 1139 {"Empty input", "", empty, true}, 1140 1141 {"Bad input", "✨🌟⭐", empty, true}, 1142 1143 {"Invalid decimal coin", "9.3.0stake", empty, true}, 1144 1145 {"Precision over limit", "9.11111111111111111111stake", empty, true}, 1146 1147 {"Valid upper case denom", "9.3STAKE", sdk.DecCoin{"STAKE", math.LegacyNewDecWithPrec(93, 1)}, false}, 1148 1149 {"Valid input - amount and denom separated by space", "9.3 stake", sdk.DecCoin{"stake", math.LegacyNewDecWithPrec(93, 1)}, false}, 1150 1151 {"Valid input - amount and denom concatenated", "9.3stake", sdk.DecCoin{"stake", math.LegacyNewDecWithPrec(93, 1)}, false}, 1152 } 1153 1154 for i, tc := range testCases { 1155 s.T().Run(tc.name, func(t *testing.T) { 1156 res, err := sdk.ParseDecCoin(tc.input) 1157 if tc.expectedErr { 1158 s.Require().Error(err, "expected error for test case #%d %s, input: %v", i, tc.name, tc.input) 1159 } else { 1160 s.Require().NoError(err, "unexpected error for test case #%d %s, input: %v", i, tc.name, tc.input) 1161 s.Require().Equal(tc.expectedResult, res, "unexpected result for test case #%d %s, input: %v", i, tc.name, tc.input) 1162 } 1163 }) 1164 } 1165 }