github.com/Finschia/finschia-sdk@v0.48.1/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 sdk "github.com/Finschia/finschia-sdk/types" 10 ) 11 12 type decCoinTestSuite struct { 13 suite.Suite 14 } 15 16 func TestDecCoinTestSuite(t *testing.T) { 17 suite.Run(t, new(decCoinTestSuite)) 18 } 19 20 func (s *decCoinTestSuite) TestNewDecCoin() { 21 s.Require().NotPanics(func() { 22 sdk.NewInt64DecCoin(testDenom1, 5) 23 }) 24 s.Require().NotPanics(func() { 25 sdk.NewInt64DecCoin(testDenom1, 0) 26 }) 27 s.Require().NotPanics(func() { 28 sdk.NewInt64DecCoin(strings.ToUpper(testDenom1), 5) 29 }) 30 s.Require().Panics(func() { 31 sdk.NewInt64DecCoin(testDenom1, -5) 32 }) 33 } 34 35 func (s *decCoinTestSuite) TestNewDecCoinFromDec() { 36 s.Require().NotPanics(func() { 37 sdk.NewDecCoinFromDec(testDenom1, sdk.NewDec(5)) 38 }) 39 s.Require().NotPanics(func() { 40 sdk.NewDecCoinFromDec(testDenom1, sdk.ZeroDec()) 41 }) 42 s.Require().NotPanics(func() { 43 sdk.NewDecCoinFromDec(strings.ToUpper(testDenom1), sdk.NewDec(5)) 44 }) 45 s.Require().Panics(func() { 46 sdk.NewDecCoinFromDec(testDenom1, sdk.NewDec(-5)) 47 }) 48 } 49 50 func (s *decCoinTestSuite) TestNewDecCoinFromCoin() { 51 s.Require().NotPanics(func() { 52 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, sdk.NewInt(5)}) 53 }) 54 s.Require().NotPanics(func() { 55 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, sdk.NewInt(0)}) 56 }) 57 s.Require().NotPanics(func() { 58 sdk.NewDecCoinFromCoin(sdk.Coin{strings.ToUpper(testDenom1), sdk.NewInt(5)}) 59 }) 60 s.Require().Panics(func() { 61 sdk.NewDecCoinFromCoin(sdk.Coin{testDenom1, sdk.NewInt(-5)}) 62 }) 63 } 64 65 func (s *decCoinTestSuite) TestDecCoinIsPositive() { 66 dc := sdk.NewInt64DecCoin(testDenom1, 5) 67 s.Require().True(dc.IsPositive()) 68 69 dc = sdk.NewInt64DecCoin(testDenom1, 0) 70 s.Require().False(dc.IsPositive()) 71 } 72 73 func (s *decCoinTestSuite) TestAddDecCoin() { 74 decCoinA1 := sdk.NewDecCoinFromDec(testDenom1, sdk.NewDecWithPrec(11, 1)) 75 decCoinA2 := sdk.NewDecCoinFromDec(testDenom1, sdk.NewDecWithPrec(22, 1)) 76 decCoinB1 := sdk.NewDecCoinFromDec(testDenom2, sdk.NewDecWithPrec(11, 1)) 77 78 // regular add 79 res := decCoinA1.Add(decCoinA1) 80 s.Require().Equal(decCoinA2, res, "sum of coins is incorrect") 81 82 // bad denom add 83 s.Require().Panics(func() { 84 decCoinA1.Add(decCoinB1) 85 }, "expected panic on sum of different denoms") 86 } 87 88 func (s *decCoinTestSuite) TestAddDecCoins() { 89 one := sdk.NewDec(1) 90 zero := sdk.NewDec(0) 91 two := sdk.NewDec(2) 92 93 cases := []struct { 94 inputOne sdk.DecCoins 95 inputTwo sdk.DecCoins 96 expected sdk.DecCoins 97 }{ 98 {sdk.DecCoins{{testDenom1, one}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, one}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, two}, {testDenom2, two}}}, 99 {sdk.DecCoins{{testDenom1, zero}, {testDenom2, one}}, sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins{{testDenom2, one}}}, 100 {sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins{{testDenom1, zero}, {testDenom2, zero}}, sdk.DecCoins(nil)}, 101 } 102 103 for tcIndex, tc := range cases { 104 res := tc.inputOne.Add(tc.inputTwo...) 105 s.Require().Equal(tc.expected, res, "sum of coins is incorrect, tc #%d", tcIndex) 106 } 107 } 108 109 func (s *decCoinTestSuite) TestFilteredZeroDecCoins() { 110 cases := []struct { 111 name string 112 input sdk.DecCoins 113 original string 114 expected string 115 }{ 116 { 117 name: "all greater than zero", 118 input: sdk.DecCoins{ 119 {"testa", sdk.NewDec(1)}, 120 {"testb", sdk.NewDec(2)}, 121 {"testc", sdk.NewDec(3)}, 122 {"testd", sdk.NewDec(4)}, 123 {"teste", sdk.NewDec(5)}, 124 }, 125 original: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 126 expected: "1.000000000000000000testa,2.000000000000000000testb,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 127 }, 128 { 129 name: "zero coin in middle", 130 input: sdk.DecCoins{ 131 {"testa", sdk.NewDec(1)}, 132 {"testb", sdk.NewDec(2)}, 133 {"testc", sdk.NewDec(0)}, 134 {"testd", sdk.NewDec(4)}, 135 {"teste", sdk.NewDec(5)}, 136 }, 137 original: "1.000000000000000000testa,2.000000000000000000testb,0.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 138 expected: "1.000000000000000000testa,2.000000000000000000testb,4.000000000000000000testd,5.000000000000000000teste", 139 }, 140 { 141 name: "zero coin end (unordered)", 142 input: sdk.DecCoins{ 143 {"teste", sdk.NewDec(5)}, 144 {"testc", sdk.NewDec(3)}, 145 {"testa", sdk.NewDec(1)}, 146 {"testd", sdk.NewDec(4)}, 147 {"testb", sdk.NewDec(0)}, 148 }, 149 original: "5.000000000000000000teste,3.000000000000000000testc,1.000000000000000000testa,4.000000000000000000testd,0.000000000000000000testb", 150 expected: "1.000000000000000000testa,3.000000000000000000testc,4.000000000000000000testd,5.000000000000000000teste", 151 }, 152 } 153 154 for _, tt := range cases { 155 undertest := sdk.NewDecCoins(tt.input...) 156 s.Require().Equal(tt.expected, undertest.String(), "NewDecCoins must return expected results") 157 s.Require().Equal(tt.original, tt.input.String(), "input must be unmodified and match original") 158 } 159 } 160 161 func (s *decCoinTestSuite) TestIsValid() { 162 tests := []struct { 163 coin sdk.DecCoin 164 expectPass bool 165 msg string 166 }{ 167 { 168 sdk.NewDecCoin("mytoken", sdk.NewInt(10)), 169 true, 170 "valid coins should have passed", 171 }, 172 { 173 sdk.DecCoin{Denom: "BTC", Amount: sdk.NewDec(10)}, 174 true, 175 "valid uppercase denom", 176 }, 177 { 178 sdk.DecCoin{Denom: "Bitcoin", Amount: sdk.NewDec(10)}, 179 true, 180 "valid mixed case denom", 181 }, 182 { 183 sdk.DecCoin{Denom: "btc", Amount: sdk.NewDec(-10)}, 184 false, 185 "negative amount", 186 }, 187 } 188 189 for _, tc := range tests { 190 tc := tc 191 if tc.expectPass { 192 s.Require().True(tc.coin.IsValid(), tc.msg) 193 } else { 194 s.Require().False(tc.coin.IsValid(), tc.msg) 195 } 196 } 197 } 198 199 func (s *decCoinTestSuite) TestSubDecCoin() { 200 tests := []struct { 201 coin sdk.DecCoin 202 expectPass bool 203 msg string 204 }{ 205 { 206 sdk.NewDecCoin("mytoken", sdk.NewInt(20)), 207 true, 208 "valid coins should have passed", 209 }, 210 { 211 sdk.NewDecCoin("othertoken", sdk.NewInt(20)), 212 false, 213 "denom mismatch", 214 }, 215 { 216 sdk.NewDecCoin("mytoken", sdk.NewInt(9)), 217 false, 218 "negative amount", 219 }, 220 } 221 222 decCoin := sdk.NewDecCoin("mytoken", sdk.NewInt(10)) 223 224 for _, tc := range tests { 225 tc := tc 226 if tc.expectPass { 227 equal := tc.coin.Sub(decCoin) 228 s.Require().Equal(equal, decCoin, tc.msg) 229 } else { 230 s.Require().Panics(func() { tc.coin.Sub(decCoin) }, tc.msg) 231 } 232 } 233 } 234 235 func (s *decCoinTestSuite) TestSubDecCoins() { 236 tests := []struct { 237 coins sdk.DecCoins 238 expectPass bool 239 msg string 240 }{ 241 { 242 sdk.NewDecCoinsFromCoins(sdk.NewCoin("mytoken", sdk.NewInt(10)), sdk.NewCoin("btc", sdk.NewInt(20)), sdk.NewCoin("eth", sdk.NewInt(30))), 243 true, 244 "sorted coins should have passed", 245 }, 246 { 247 sdk.DecCoins{sdk.NewDecCoin("mytoken", sdk.NewInt(10)), sdk.NewDecCoin("btc", sdk.NewInt(20)), sdk.NewDecCoin("eth", sdk.NewInt(30))}, 248 false, 249 "unorted coins should panic", 250 }, 251 { 252 sdk.DecCoins{sdk.DecCoin{Denom: "BTC", Amount: sdk.NewDec(10)}, sdk.NewDecCoin("eth", sdk.NewInt(15)), sdk.NewDecCoin("mytoken", sdk.NewInt(5))}, 253 false, 254 "invalid denoms", 255 }, 256 } 257 258 decCoins := sdk.NewDecCoinsFromCoins(sdk.NewCoin("btc", sdk.NewInt(10)), sdk.NewCoin("eth", sdk.NewInt(15)), sdk.NewCoin("mytoken", sdk.NewInt(5))) 259 260 for _, tc := range tests { 261 tc := tc 262 if tc.expectPass { 263 equal := tc.coins.Sub(decCoins) 264 s.Require().Equal(equal, decCoins, tc.msg) 265 } else { 266 s.Require().Panics(func() { tc.coins.Sub(decCoins) }, tc.msg) 267 } 268 } 269 } 270 271 func (s *decCoinTestSuite) TestSortDecCoins() { 272 good := sdk.DecCoins{ 273 sdk.NewInt64DecCoin("gas", 1), 274 sdk.NewInt64DecCoin("mineral", 1), 275 sdk.NewInt64DecCoin("tree", 1), 276 } 277 empty := sdk.DecCoins{ 278 sdk.NewInt64DecCoin("gold", 0), 279 } 280 badSort1 := sdk.DecCoins{ 281 sdk.NewInt64DecCoin("tree", 1), 282 sdk.NewInt64DecCoin("gas", 1), 283 sdk.NewInt64DecCoin("mineral", 1), 284 } 285 badSort2 := sdk.DecCoins{ // both are after the first one, but the second and third are in the wrong order 286 sdk.NewInt64DecCoin("gas", 1), 287 sdk.NewInt64DecCoin("tree", 1), 288 sdk.NewInt64DecCoin("mineral", 1), 289 } 290 badAmt := sdk.DecCoins{ 291 sdk.NewInt64DecCoin("gas", 1), 292 sdk.NewInt64DecCoin("tree", 0), 293 sdk.NewInt64DecCoin("mineral", 1), 294 } 295 dup := sdk.DecCoins{ 296 sdk.NewInt64DecCoin("gas", 1), 297 sdk.NewInt64DecCoin("gas", 1), 298 sdk.NewInt64DecCoin("mineral", 1), 299 } 300 cases := []struct { 301 name string 302 coins sdk.DecCoins 303 before, after bool // valid before/after sort 304 }{ 305 {"valid coins", good, true, true}, 306 {"empty coins", empty, false, false}, 307 {"unsorted coins (1)", badSort1, false, true}, 308 {"unsorted coins (2)", badSort2, false, true}, 309 {"zero amount coins", badAmt, false, false}, 310 {"duplicate coins", dup, false, false}, 311 } 312 313 for _, tc := range cases { 314 s.Require().Equal(tc.before, tc.coins.IsValid(), "coin validity is incorrect before sorting; %s", tc.name) 315 tc.coins.Sort() 316 s.Require().Equal(tc.after, tc.coins.IsValid(), "coin validity is incorrect after sorting; %s", tc.name) 317 } 318 } 319 320 func (s *decCoinTestSuite) TestDecCoinsValidate() { 321 testCases := []struct { 322 input sdk.DecCoins 323 expectedPass bool 324 }{ 325 {sdk.DecCoins{}, true}, 326 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(5)}}, true}, 327 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(5)}, sdk.DecCoin{testDenom2, sdk.NewDec(100000)}}, true}, 328 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(-5)}}, false}, 329 {sdk.DecCoins{sdk.DecCoin{"BTC", sdk.NewDec(5)}}, true}, 330 {sdk.DecCoins{sdk.DecCoin{"0BTC", sdk.NewDec(5)}}, false}, 331 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(5)}, sdk.DecCoin{"B", sdk.NewDec(100000)}}, false}, 332 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(5)}, sdk.DecCoin{testDenom2, sdk.NewDec(-100000)}}, false}, 333 {sdk.DecCoins{sdk.DecCoin{testDenom1, sdk.NewDec(-5)}, sdk.DecCoin{testDenom2, sdk.NewDec(100000)}}, false}, 334 {sdk.DecCoins{sdk.DecCoin{"BTC", sdk.NewDec(5)}, sdk.DecCoin{testDenom2, sdk.NewDec(100000)}}, true}, 335 {sdk.DecCoins{sdk.DecCoin{"0BTC", sdk.NewDec(5)}, sdk.DecCoin{testDenom2, sdk.NewDec(100000)}}, false}, 336 } 337 338 for i, tc := range testCases { 339 err := tc.input.Validate() 340 if tc.expectedPass { 341 s.Require().NoError(err, "unexpected result for test case #%d, input: %v", i, tc.input) 342 } else { 343 s.Require().Error(err, "unexpected result for test case #%d, input: %v", i, tc.input) 344 } 345 } 346 } 347 348 func (s *decCoinTestSuite) TestParseDecCoins() { 349 testCases := []struct { 350 input string 351 expectedResult sdk.DecCoins 352 expectedErr bool 353 }{ 354 {"", nil, false}, 355 {"4stake", sdk.DecCoins{sdk.NewDecCoinFromDec("stake", sdk.NewDecFromInt(sdk.NewInt(4)))}, false}, 356 {"5.5atom,4stake", sdk.DecCoins{ 357 sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5500000000000000000, sdk.Precision)), 358 sdk.NewDecCoinFromDec("stake", sdk.NewDec(4)), 359 }, false}, 360 {"0.0stake", sdk.DecCoins{}, false}, // remove zero coins 361 {"10.0btc,1.0atom,20.0btc", nil, true}, 362 { 363 "0.004STAKE", 364 sdk.DecCoins{sdk.NewDecCoinFromDec("STAKE", sdk.NewDecWithPrec(4000000000000000, sdk.Precision))}, 365 false, 366 }, 367 { 368 "0.004stake", 369 sdk.DecCoins{sdk.NewDecCoinFromDec("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision))}, 370 false, 371 }, 372 { 373 "5.04atom,0.004stake", 374 sdk.DecCoins{ 375 sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5040000000000000000, sdk.Precision)), 376 sdk.NewDecCoinFromDec("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision)), 377 }, 378 false, 379 }, 380 { 381 "0.0stake,0.004stake,5.04atom", // remove zero coins 382 sdk.DecCoins{ 383 sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5040000000000000000, sdk.Precision)), 384 sdk.NewDecCoinFromDec("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision)), 385 }, 386 false, 387 }, 388 } 389 390 for i, tc := range testCases { 391 res, err := sdk.ParseDecCoins(tc.input) 392 if tc.expectedErr { 393 s.Require().Error(err, "expected error for test case #%d, input: %v", i, tc.input) 394 } else { 395 s.Require().NoError(err, "unexpected error for test case #%d, input: %v", i, tc.input) 396 s.Require().Equal(tc.expectedResult, res, "unexpected result for test case #%d, input: %v", i, tc.input) 397 } 398 } 399 } 400 401 func (s *decCoinTestSuite) TestDecCoinsString() { 402 testCases := []struct { 403 input sdk.DecCoins 404 expected string 405 }{ 406 {sdk.DecCoins{}, ""}, 407 { 408 sdk.DecCoins{ 409 sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5040000000000000000, sdk.Precision)), 410 sdk.NewDecCoinFromDec("stake", sdk.NewDecWithPrec(4000000000000000, sdk.Precision)), 411 }, 412 "5.040000000000000000atom,0.004000000000000000stake", 413 }, 414 } 415 416 for i, tc := range testCases { 417 out := tc.input.String() 418 s.Require().Equal(tc.expected, out, "unexpected result for test case #%d, input: %v", i, tc.input) 419 } 420 } 421 422 func (s *decCoinTestSuite) TestDecCoinsIntersect() { 423 testCases := []struct { 424 input1 string 425 input2 string 426 expectedResult string 427 }{ 428 {"", "", ""}, 429 {"1.0stake", "", ""}, 430 {"1.0stake", "1.0stake", "1.0stake"}, 431 {"", "1.0stake", ""}, 432 {"1.0stake", "", ""}, 433 {"2.0stake,1.0trope", "1.9stake", "1.9stake"}, 434 {"2.0stake,1.0trope", "2.1stake", "2.0stake"}, 435 {"2.0stake,1.0trope", "0.9trope", "0.9trope"}, 436 {"2.0stake,1.0trope", "1.9stake,0.9trope", "1.9stake,0.9trope"}, 437 {"2.0stake,1.0trope", "1.9stake,0.9trope,20.0other", "1.9stake,0.9trope"}, 438 {"2.0stake,1.0trope", "1.0other", ""}, 439 } 440 441 for i, tc := range testCases { 442 in1, err := sdk.ParseDecCoins(tc.input1) 443 s.Require().NoError(err, "unexpected parse error in %v", i) 444 in2, err := sdk.ParseDecCoins(tc.input2) 445 s.Require().NoError(err, "unexpected parse error in %v", i) 446 exr, err := sdk.ParseDecCoins(tc.expectedResult) 447 s.Require().NoError(err, "unexpected parse error in %v", i) 448 s.Require().True(in1.Intersect(in2).IsEqual(exr), "in1.cap(in2) != exr in %v", i) 449 } 450 } 451 452 func (s *decCoinTestSuite) TestDecCoinsTruncateDecimal() { 453 decCoinA := sdk.NewDecCoinFromDec("bar", sdk.MustNewDecFromStr("5.41")) 454 decCoinB := sdk.NewDecCoinFromDec("foo", sdk.MustNewDecFromStr("6.00")) 455 456 testCases := []struct { 457 input sdk.DecCoins 458 truncatedCoins sdk.Coins 459 changeCoins sdk.DecCoins 460 }{ 461 {sdk.DecCoins{}, sdk.Coins(nil), sdk.DecCoins(nil)}, 462 { 463 sdk.DecCoins{decCoinA, decCoinB}, 464 sdk.Coins{sdk.NewInt64Coin(decCoinA.Denom, 5), sdk.NewInt64Coin(decCoinB.Denom, 6)}, 465 sdk.DecCoins{sdk.NewDecCoinFromDec(decCoinA.Denom, sdk.MustNewDecFromStr("0.41"))}, 466 }, 467 { 468 sdk.DecCoins{decCoinB}, 469 sdk.Coins{sdk.NewInt64Coin(decCoinB.Denom, 6)}, 470 sdk.DecCoins(nil), 471 }, 472 } 473 474 for i, tc := range testCases { 475 truncatedCoins, changeCoins := tc.input.TruncateDecimal() 476 s.Require().Equal( 477 tc.truncatedCoins, truncatedCoins, 478 "unexpected truncated coins; tc #%d, input: %s", i, tc.input, 479 ) 480 s.Require().Equal( 481 tc.changeCoins, changeCoins, 482 "unexpected change coins; tc #%d, input: %s", i, tc.input, 483 ) 484 } 485 } 486 487 func (s *decCoinTestSuite) TestDecCoinsQuoDecTruncate() { 488 x := sdk.MustNewDecFromStr("1.00") 489 y := sdk.MustNewDecFromStr("10000000000000000000.00") 490 491 testCases := []struct { 492 coins sdk.DecCoins 493 input sdk.Dec 494 result sdk.DecCoins 495 panics bool 496 }{ 497 {sdk.DecCoins{}, sdk.ZeroDec(), sdk.DecCoins(nil), true}, 498 {sdk.DecCoins{sdk.NewDecCoinFromDec("foo", x)}, y, sdk.DecCoins(nil), false}, 499 {sdk.DecCoins{sdk.NewInt64DecCoin("foo", 5)}, sdk.NewDec(2), sdk.DecCoins{sdk.NewDecCoinFromDec("foo", sdk.MustNewDecFromStr("2.5"))}, false}, 500 } 501 502 for i, tc := range testCases { 503 tc := tc 504 if tc.panics { 505 s.Require().Panics(func() { tc.coins.QuoDecTruncate(tc.input) }) 506 } else { 507 res := tc.coins.QuoDecTruncate(tc.input) 508 s.Require().Equal(tc.result, res, "unexpected result; tc #%d, coins: %s, input: %s", i, tc.coins, tc.input) 509 } 510 } 511 } 512 513 func (s *decCoinTestSuite) TestNewDecCoinsWithIsValid() { 514 fake1 := append(sdk.NewDecCoins(sdk.NewDecCoin("mytoken", sdk.NewInt(10))), sdk.DecCoin{Denom: "10BTC", Amount: sdk.NewDec(10)}) 515 fake2 := append(sdk.NewDecCoins(sdk.NewDecCoin("mytoken", sdk.NewInt(10))), sdk.DecCoin{Denom: "BTC", Amount: sdk.NewDec(-10)}) 516 517 tests := []struct { 518 coin sdk.DecCoins 519 expectPass bool 520 msg string 521 }{ 522 { 523 sdk.NewDecCoins(sdk.NewDecCoin("mytoken", sdk.NewInt(10))), 524 true, 525 "valid coins should have passed", 526 }, 527 { 528 fake1, 529 false, 530 "invalid denoms", 531 }, 532 { 533 fake2, 534 false, 535 "negative amount", 536 }, 537 } 538 539 for _, tc := range tests { 540 tc := tc 541 if tc.expectPass { 542 s.Require().True(tc.coin.IsValid(), tc.msg) 543 } else { 544 s.Require().False(tc.coin.IsValid(), tc.msg) 545 } 546 } 547 } 548 549 func (s *decCoinTestSuite) TestDecCoins_AddDecCoinWithIsValid() { 550 lengthTestDecCoins := sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", sdk.NewInt(10))).Add(sdk.DecCoin{Denom: "BTC", Amount: sdk.NewDec(10)}) 551 s.Require().Equal(2, len(lengthTestDecCoins), "should be 2") 552 553 tests := []struct { 554 coin sdk.DecCoins 555 expectPass bool 556 msg string 557 }{ 558 { 559 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", sdk.NewInt(10))), 560 true, 561 "valid coins should have passed", 562 }, 563 { 564 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", sdk.NewInt(10))).Add(sdk.DecCoin{Denom: "0BTC", Amount: sdk.NewDec(10)}), 565 false, 566 "invalid denoms", 567 }, 568 { 569 sdk.NewDecCoins().Add(sdk.NewDecCoin("mytoken", sdk.NewInt(10))).Add(sdk.DecCoin{Denom: "BTC", Amount: sdk.NewDec(-10)}), 570 false, 571 "negative amount", 572 }, 573 } 574 575 for _, tc := range tests { 576 tc := tc 577 if tc.expectPass { 578 s.Require().True(tc.coin.IsValid(), tc.msg) 579 } else { 580 s.Require().False(tc.coin.IsValid(), tc.msg) 581 } 582 } 583 }