Merge PR #3818: Introduce sdk.NewCoins
This commit is contained in:
committed by
Jack Zampolin
parent
a24dee0155
commit
fbd79d0cad
@@ -130,6 +130,28 @@ func (coin Coin) IsNegative() bool {
|
||||
// Coins is a set of Coin, one per currency
|
||||
type Coins []Coin
|
||||
|
||||
// NewCoins constructs a new coin set.
|
||||
func NewCoins(coins ...Coin) Coins {
|
||||
// remove zeroes
|
||||
newCoins := removeZeroCoins(Coins(coins))
|
||||
if len(newCoins) == 0 {
|
||||
return Coins{}
|
||||
}
|
||||
|
||||
newCoins.Sort()
|
||||
|
||||
// detect duplicate Denoms
|
||||
if dupIndex := findDup(newCoins); dupIndex != -1 {
|
||||
panic(fmt.Errorf("find duplicate denom: %s", newCoins[dupIndex]))
|
||||
}
|
||||
|
||||
if !newCoins.IsValid() {
|
||||
panic(fmt.Errorf("invalid coin set: %s", newCoins))
|
||||
}
|
||||
|
||||
return newCoins
|
||||
}
|
||||
|
||||
func (coins Coins) String() string {
|
||||
if len(coins) == 0 {
|
||||
return ""
|
||||
@@ -552,3 +574,19 @@ func ParseCoins(coinsStr string) (coins Coins, err error) {
|
||||
|
||||
return coins, nil
|
||||
}
|
||||
|
||||
// findDup works on the assumption that coins is sorted
|
||||
func findDup(coins Coins) int {
|
||||
if len(coins) <= 1 {
|
||||
return -1
|
||||
}
|
||||
|
||||
prevDenom := coins[0]
|
||||
for i := 1; i < len(coins); i++ {
|
||||
if coins[i] == prevDenom {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
@@ -519,3 +519,31 @@ func TestCoinsIsAnyGTE(t *testing.T) {
|
||||
assert.True(t, Coins{{testDenom1, one}, {testDenom2, one}}.IsAnyGTE(Coins{{testDenom1, one}, {testDenom2, two}}))
|
||||
assert.True(t, Coins{{"xxx", one}, {"yyy", one}}.IsAnyGTE(Coins{{testDenom2, one}, {"ccc", one}, {"yyy", one}, {"zzz", one}}))
|
||||
}
|
||||
|
||||
func TestNewCoins(t *testing.T) {
|
||||
tenatom := NewInt64Coin("atom", 10)
|
||||
tenbtc := NewInt64Coin("btc", 10)
|
||||
zeroeth := NewInt64Coin("eth", 0)
|
||||
tests := []struct {
|
||||
name string
|
||||
coins Coins
|
||||
want Coins
|
||||
wantPanic bool
|
||||
}{
|
||||
{"empty args", []Coin{}, Coins{}, false},
|
||||
{"one coin", []Coin{tenatom}, Coins{tenatom}, false},
|
||||
{"sort after create", []Coin{tenbtc, tenatom}, Coins{tenatom, tenbtc}, false},
|
||||
{"sort and remove zeroes", []Coin{zeroeth, tenbtc, tenatom}, Coins{tenatom, tenbtc}, false},
|
||||
{"panic on dups", []Coin{tenatom, tenatom}, Coins{}, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantPanic {
|
||||
require.Panics(t, func() { NewCoins(tt.coins...) })
|
||||
return
|
||||
}
|
||||
got := NewCoins(tt.coins...)
|
||||
require.True(t, got.IsEqual(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user