Skip to content

Commit

Permalink
Merge PR cosmos#1626: Increase coverage of types/
Browse files Browse the repository at this point in the history
  • Loading branch information
mossid authored and cwgoes committed Aug 6, 2018
1 parent 12c2c23 commit 93457aa
Show file tree
Hide file tree
Showing 14 changed files with 1,018 additions and 28 deletions.
132 changes: 132 additions & 0 deletions types/account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package types_test

import (
"encoding/hex"
"math/rand"
"testing"

"github.com/stretchr/testify/require"

"github.com/tendermint/tendermint/crypto/ed25519"

"github.com/cosmos/cosmos-sdk/types"
)

var invalidstrs = []string{
"",
"hello, world!",
"0xAA",
"AAA",
types.Bech32PrefixAccAddr + "AB0C",
types.Bech32PrefixAccPub + "1234",
types.Bech32PrefixValAddr + "5678",
types.Bech32PrefixValPub + "BBAB",
}

func testMarshal(t *testing.T, original interface{}, res interface{}, marshal func() ([]byte, error), unmarshal func([]byte) error) {
bz, err := marshal()
require.Nil(t, err)
err = unmarshal(bz)
require.Nil(t, err)
require.Equal(t, original, res)
}

func TestRandBech32PubkeyConsistency(t *testing.T) {
var pub ed25519.PubKeyEd25519

for i := 0; i < 1000; i++ {
rand.Read(pub[:])

mustbech32accpub := types.MustBech32ifyAccPub(pub)
bech32accpub, err := types.Bech32ifyAccPub(pub)
require.Nil(t, err)
require.Equal(t, bech32accpub, mustbech32accpub)

mustbech32valpub := types.MustBech32ifyValPub(pub)
bech32valpub, err := types.Bech32ifyValPub(pub)
require.Nil(t, err)
require.Equal(t, bech32valpub, mustbech32valpub)

mustaccpub := types.MustGetAccPubKeyBech32(bech32accpub)
accpub, err := types.GetAccPubKeyBech32(bech32accpub)
require.Nil(t, err)
require.Equal(t, accpub, mustaccpub)

mustvalpub := types.MustGetValPubKeyBech32(bech32valpub)
valpub, err := types.GetValPubKeyBech32(bech32valpub)
require.Nil(t, err)
require.Equal(t, valpub, mustvalpub)

require.Equal(t, valpub, accpub)
}
}

func TestRandBech32AccAddrConsistency(t *testing.T) {
var pub ed25519.PubKeyEd25519

for i := 0; i < 1000; i++ {
rand.Read(pub[:])

acc := types.AccAddress(pub.Address())
res := types.AccAddress{}

testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON)
testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal)

str := acc.String()
res, err := types.AccAddressFromBech32(str)
require.Nil(t, err)
require.Equal(t, acc, res)

str = hex.EncodeToString(acc)
res, err = types.AccAddressFromHex(str)
require.Nil(t, err)
require.Equal(t, acc, res)
}

for _, str := range invalidstrs {
_, err := types.AccAddressFromHex(str)
require.NotNil(t, err)

_, err = types.AccAddressFromBech32(str)
require.NotNil(t, err)

err = (*types.AccAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\""))
require.NotNil(t, err)
}
}

func TestValAddr(t *testing.T) {
var pub ed25519.PubKeyEd25519

for i := 0; i < 20; i++ {
rand.Read(pub[:])

acc := types.ValAddress(pub.Address())
res := types.ValAddress{}

testMarshal(t, &acc, &res, acc.MarshalJSON, (&res).UnmarshalJSON)
testMarshal(t, &acc, &res, acc.Marshal, (&res).Unmarshal)

str := acc.String()
res, err := types.ValAddressFromBech32(str)
require.Nil(t, err)
require.Equal(t, acc, res)

str = hex.EncodeToString(acc)
res, err = types.ValAddressFromHex(str)
require.Nil(t, err)
require.Equal(t, acc, res)
}

for _, str := range invalidstrs {
_, err := types.ValAddressFromHex(str)
require.NotNil(t, err)

_, err = types.ValAddressFromBech32(str)
require.NotNil(t, err)

err = (*types.ValAddress)(nil).UnmarshalJSON([]byte("\"" + str + "\""))
require.NotNil(t, err)
}
}
42 changes: 42 additions & 0 deletions types/coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,46 @@ func TestMinusCoin(t *testing.T) {

}

func TestIsZeroCoins(t *testing.T) {
cases := []struct {
inputOne Coins
expected bool
}{
{Coins{}, true},
{Coins{NewCoin("A", 0)}, true},
{Coins{NewCoin("A", 0), NewCoin("B", 0)}, true},
{Coins{NewCoin("A", 1)}, false},
{Coins{NewCoin("A", 0), NewCoin("B", 1)}, false},
}

for _, tc := range cases {
res := tc.inputOne.IsZero()
require.Equal(t, tc.expected, res)
}
}

func TestEqualCoins(t *testing.T) {
cases := []struct {
inputOne Coins
inputTwo Coins
expected bool
}{
{Coins{}, Coins{}, true},
{Coins{NewCoin("A", 0)}, Coins{NewCoin("A", 0)}, true},
{Coins{NewCoin("A", 0), NewCoin("B", 1)}, Coins{NewCoin("A", 0), NewCoin("B", 1)}, true},
{Coins{NewCoin("A", 0)}, Coins{NewCoin("B", 0)}, false},
{Coins{NewCoin("A", 0)}, Coins{NewCoin("A", 1)}, false},
{Coins{NewCoin("A", 0)}, Coins{NewCoin("A", 0), NewCoin("B", 1)}, false},
// TODO: is it expected behaviour? shouldn't we sort the coins before comparing them?
{Coins{NewCoin("A", 0), NewCoin("B", 1)}, Coins{NewCoin("B", 1), NewCoin("A", 0)}, false},
}

for tcnum, tc := range cases {
res := tc.inputOne.IsEqual(tc.inputTwo)
require.Equal(t, tc.expected, res, "Equality is differed from expected. tc #%d, expected %b, actual %b.", tcnum, tc.expected, res)
}
}

func TestCoins(t *testing.T) {

//Define the coins to be used in tests
Expand All @@ -160,6 +200,7 @@ func TestCoins(t *testing.T) {
empty := Coins{
{"GOLD", NewInt(0)},
}
null := Coins{}
badSort1 := Coins{
{"TREE", NewInt(1)},
{"GAS", NewInt(1)},
Expand All @@ -184,6 +225,7 @@ func TestCoins(t *testing.T) {

assert.True(t, good.IsValid(), "Coins are valid")
assert.True(t, good.IsPositive(), "Expected coins to be positive: %v", good)
assert.False(t, null.IsPositive(), "Expected coins to not be positive: %v", null)
assert.True(t, good.IsGTE(empty), "Expected %v to be >= %v", good, empty)
assert.False(t, neg.IsPositive(), "Expected neg coins to not be positive: %v", neg)
assert.Zero(t, len(sum), "Expected 0 coins")
Expand Down
81 changes: 81 additions & 0 deletions types/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,84 @@ func TestLogContext(t *testing.T) {
ctx.Logger().Error("error")
require.Equal(t, *logger.logs, []string{"debug", "info", "error"})
}

type dummy int64

func (d dummy) Clone() interface{} {
return d
}

// Testing saving/loading primitive values to/from the context
func TestContextWithPrimitive(t *testing.T) {
ctx := types.NewContext(nil, abci.Header{}, false, log.NewNopLogger())

clonerkey := "cloner"
stringkey := "string"
int32key := "int32"
uint32key := "uint32"
uint64key := "uint64"

keys := []string{clonerkey, stringkey, int32key, uint32key, uint64key}

for _, key := range keys {
require.Nil(t, ctx.Value(key))
}

clonerval := dummy(1)
stringval := "string"
int32val := int32(1)
uint32val := uint32(2)
uint64val := uint64(3)

ctx = ctx.
WithCloner(clonerkey, clonerval).
WithString(stringkey, stringval).
WithInt32(int32key, int32val).
WithUint32(uint32key, uint32val).
WithUint64(uint64key, uint64val)

require.Equal(t, clonerval, ctx.Value(clonerkey))
require.Equal(t, stringval, ctx.Value(stringkey))
require.Equal(t, int32val, ctx.Value(int32key))
require.Equal(t, uint32val, ctx.Value(uint32key))
require.Equal(t, uint64val, ctx.Value(uint64key))
}

// Testing saving/loading sdk type values to/from the context
func TestContextWithCustom(t *testing.T) {
var ctx types.Context
require.True(t, ctx.IsZero())

require.Panics(t, func() { ctx.BlockHeader() })
require.Panics(t, func() { ctx.BlockHeight() })
require.Panics(t, func() { ctx.ChainID() })
require.Panics(t, func() { ctx.TxBytes() })
require.Panics(t, func() { ctx.Logger() })
require.Panics(t, func() { ctx.SigningValidators() })
require.Panics(t, func() { ctx.GasMeter() })

header := abci.Header{}
height := int64(1)
chainid := "chainid"
ischeck := true
txbytes := []byte("txbytes")
logger := NewMockLogger()
signvals := []abci.SigningValidator{abci.SigningValidator{}}
meter := types.NewGasMeter(10000)

ctx = types.NewContext(nil, header, ischeck, logger).
WithBlockHeight(height).
WithChainID(chainid).
WithTxBytes(txbytes).
WithSigningValidators(signvals).
WithGasMeter(meter)

require.Equal(t, header, ctx.BlockHeader())
require.Equal(t, height, ctx.BlockHeight())
require.Equal(t, chainid, ctx.ChainID())
require.Equal(t, txbytes, ctx.TxBytes())
require.Equal(t, logger, ctx.Logger())
require.Equal(t, signvals, ctx.SigningValidators())
require.Equal(t, meter, ctx.GasMeter())

}
6 changes: 5 additions & 1 deletion types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ const (
MaximumCodespace CodespaceType = 65535
)

func unknownCodeMsg(code CodeType) string {
return fmt.Sprintf("unknown code %d", code)
}

// NOTE: Don't stringer this, we'll put better messages in later.
// nolint: gocyclo
func CodeToDefaultMsg(code CodeType) string {
Expand Down Expand Up @@ -96,7 +100,7 @@ func CodeToDefaultMsg(code CodeType) string {
case CodeMemoTooLarge:
return "memo too large"
default:
return fmt.Sprintf("unknown code %d", code)
return unknownCodeMsg(code)
}
}

Expand Down
28 changes: 21 additions & 7 deletions types/errors_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package types

import (
"strings"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -14,8 +13,13 @@ var codeTypes = []CodeType{
CodeUnauthorized,
CodeInsufficientFunds,
CodeUnknownRequest,
CodeUnknownAddress,
CodeInvalidAddress,
CodeInvalidPubKey,
CodeUnknownAddress,
CodeInsufficientCoins,
CodeInvalidCoins,
CodeOutOfGas,
CodeMemoTooLarge,
}

type errFn func(msg string) Error
Expand All @@ -27,24 +31,34 @@ var errFns = []errFn{
ErrUnauthorized,
ErrInsufficientFunds,
ErrUnknownRequest,
ErrUnknownAddress,
ErrInvalidAddress,
ErrInvalidPubKey,
ErrUnknownAddress,
ErrInsufficientCoins,
ErrInvalidCoins,
ErrOutOfGas,
ErrMemoTooLarge,
}

func TestCodeType(t *testing.T) {
require.True(t, ABCICodeOK.IsOK())

for _, c := range codeTypes {
for tcnum, c := range codeTypes {
msg := CodeToDefaultMsg(c)
require.False(t, strings.HasPrefix(msg, "Unknown code"))
require.NotEqual(t, unknownCodeMsg(c), msg, "Code expected to be known. tc #%d, code %d, msg %s", tcnum, c, msg)
}

msg := CodeToDefaultMsg(CodeOK)
require.Equal(t, unknownCodeMsg(CodeOK), msg)
}

func TestErrFn(t *testing.T) {
for i, errFn := range errFns {
err := errFn("")
codeType := codeTypes[i]
require.Equal(t, err.Code(), codeType)
require.Equal(t, err.Result().Code, ToABCICode(CodespaceRoot, codeType))
require.Equal(t, err.Code(), codeType, "Err function expected to return proper code. tc #%d", i)
require.Equal(t, err.Result().Code, ToABCICode(CodespaceRoot, codeType), "Err function expected to return proper ABCICode. tc #%d")
}

require.Equal(t, ABCICodeOK, ToABCICode(CodespaceRoot, CodeOK))
}
Loading

0 comments on commit 93457aa

Please sign in to comment.