diff --git a/ante/fee_test.go b/ante/fee_test.go index 50e322c2e..617a23da9 100644 --- a/ante/fee_test.go +++ b/ante/fee_test.go @@ -159,7 +159,8 @@ var _ = Describe("Fee tests on DeliverTx", func() { s := new(AnteTestSuite) BeforeEach(func() { - s.SetupTest(false) // setup + err := s.SetupTest(false) // setup + Expect(err).To(BeNil(), "Error on creating test app") s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() }) diff --git a/ante/testutil_test.go b/ante/testutil_test.go index 8097f247a..1782b687d 100644 --- a/ante/testutil_test.go +++ b/ante/testutil_test.go @@ -42,8 +42,11 @@ type AnteTestSuite struct { } // returns context and app with params set on account keeper -func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { - app := simapp.SetupForGinkgo(isCheckTx) +func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context, error) { + app, err := simapp.Setup(isCheckTx) + if err != nil { + return nil, sdk.Context{}, err + } ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams()) @@ -53,7 +56,7 @@ func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { resourceFeeParams := resourcetypes.DefaultGenesis().FeeParams app.ResourceKeeper.SetParams(ctx, *resourceFeeParams) - return app, ctx + return app, ctx, nil } // func TestAnteTestSuite(t *testing.T) { @@ -62,7 +65,11 @@ func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { // SetupTest setups a new test, with new app, context, and anteHandler. func (s *AnteTestSuite) SetupTest(isCheckTx bool) error { - s.app, s.ctx = createTestApp(isCheckTx) + var err error + s.app, s.ctx, err = createTestApp(isCheckTx) + if err != nil { + return err + } s.ctx = s.ctx.WithBlockHeight(1) // Set up TxConfig. encodingConfig := cheqdapp.MakeTestEncodingConfig() diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index d8ca01666..31488d556 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -6,11 +6,10 @@ import ( "encoding/json" "fmt" "math/rand" + "reflect" "strconv" - "testing" "time" - "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" @@ -85,12 +84,12 @@ func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, cheqdapp.GenesisStat } // NewSimappWithCustomOptions initializes a new SimApp with custom options. -func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *SimApp { - t.Helper() - +func NewSimappWithCustomOptions(isCheckTx bool, options SetupOptions) (*SimApp, error) { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() - require.NoError(t, err) + if err != nil { + return nil, err + } // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) @@ -105,12 +104,17 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio app := NewSimApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts) genesisState := cheqdapp.NewDefaultGenesisState(app.appCodec) - genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) + genesisState, err = genesisStateWithValSet(app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) + if err != nil { + return nil, err + } if !isCheckTx { // init chain must be called to stop deliverState from being nil stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") - require.NoError(t, err) + if err != nil { + return nil, err + } // Initialize the chain app.InitChain( @@ -122,16 +126,16 @@ func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptio ) } - return app + return app, nil } // Setup initializes a new SimApp. A Nop logger is set in SimApp. -func Setup(t *testing.T, isCheckTx bool) *SimApp { - t.Helper() - +func Setup(isCheckTx bool) (*SimApp, error) { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() - require.NoError(t, err) + if err != nil { + return nil, err + } // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) @@ -145,16 +149,46 @@ func Setup(t *testing.T, isCheckTx bool) *SimApp { Coins: sdk.NewCoins(sdk.NewCoin(didtypes.BaseMinimalDenom, sdk.NewInt(100000000000000))), } - app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) + app, err := SetupWithGenesisValSet(valSet, []authtypes.GenesisAccount{acc}, balance) + if err != nil { + return nil, err + } - return app + return app, nil } -func genesisStateWithValSet(t *testing.T, +// Setup initializes a new SimApp. A Nop logger is set in SimApp. +func SetupTest(isCheckTx bool) (*SimApp, error) { + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() + if err != nil { + return nil, err + } + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(didtypes.BaseMinimalDenom, sdk.NewInt(100000000000000))), + } + + app, err := SetupWithGenesisValSet(valSet, []authtypes.GenesisAccount{acc}, balance) + if err != nil { + return nil, err + } + + return app, nil +} + +func genesisStateWithValSet( app *SimApp, genesisState cheqdapp.GenesisState, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance, -) cheqdapp.GenesisState { +) (cheqdapp.GenesisState, error) { // set genesis accounts authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) @@ -166,9 +200,13 @@ func genesisStateWithValSet(t *testing.T, for _, val := range valSet.Validators { pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) - require.NoError(t, err) + if err != nil { + return nil, err + } pkAny, err := codectypes.NewAnyWithValue(pk) - require.NoError(t, err) + if err != nil { + return nil, err + } validator := stakingtypes.Validator{ OperatorAddress: sdk.ValAddress(val.Address).String(), ConsensusPubkey: pkAny, @@ -219,21 +257,24 @@ func genesisStateWithValSet(t *testing.T, resourceGenesis := resourcetypes.DefaultGenesis() genesisState[resourcetypes.ModuleName] = app.AppCodec().MustMarshalJSON(resourceGenesis) - return genesisState + return genesisState, nil } // SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit in the default token of the simapp from first genesis // account. A Nop logger is set in SimApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { - t.Helper() - +func SetupWithGenesisValSet(valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) (*SimApp, error) { app, genesisState := setup(true, 5) - genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...) + genesisState, err := genesisStateWithValSet(app, genesisState, valSet, genAccs, balances...) + if err != nil { + return nil, err + } stateBytes, err := json.MarshalIndent(genesisState, "", " ") - require.NoError(t, err) + if err != nil { + return nil, err + } // init chain will set the validator set and initialize the genesis accounts app.InitChain( @@ -253,33 +294,33 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs NextValidatorsHash: valSet.Hash(), }}) - return app + return app, nil } // SetupWithGenesisAccounts initializes a new SimApp with the provided genesis // accounts and possible balances. -func SetupWithGenesisAccounts(t *testing.T, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { - t.Helper() - +func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) (*SimApp, error) { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() - require.NoError(t, err) + if err != nil { + return nil, err + } // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - return SetupWithGenesisValSet(t, valSet, genAccs, balances...) + return SetupWithGenesisValSet(valSet, genAccs, balances...) } // GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts // that also act as delegators. -func GenesisStateWithSingleValidator(t *testing.T, app *SimApp) cheqdapp.GenesisState { - t.Helper() - +func GenesisStateWithSingleValidator(app *SimApp) (cheqdapp.GenesisState, error) { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() - require.NoError(t, err) + if err != nil { + return nil, err + } // create validator set with single validator validator := tmtypes.NewValidator(pubKey, 1) @@ -296,9 +337,80 @@ func GenesisStateWithSingleValidator(t *testing.T, app *SimApp) cheqdapp.Genesis } genesisState := cheqdapp.NewDefaultGenesisState(app.appCodec) - genesisState = genesisStateWithValSet(t, app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) + genesisState, err = genesisStateWithValSet(app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) + if err != nil { + return nil, err + } + + return genesisState, nil +} - return genesisState +// CheckBalance checks the balance of an account. +func CheckBalance(app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { + ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) + if reflect.DeepEqual(balances, app.BankKeeper.GetAllBalances(ctxCheck, addr)) { + panic("Invalid balance of account") + } +} + +// SignCheckDeliver checks a generated signed transaction and simulates a +// block commitment with the given transaction. A test assertion is made using +// the parameter 'expPass' against the result. A corresponding result is +// returned. +func SignCheckDeliver( + txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, + chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, +) (sdk.GasInfo, *sdk.Result, error) { + tx, err := helpers.GenSignedMockTx( + rand.New(rand.NewSource(time.Now().UnixNano())), + txCfg, + msgs, + sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, + helpers.DefaultGenTxGas, + chainID, + accNums, + accSeqs, + priv..., + ) + if err != nil { + return sdk.GasInfo{}, nil, err + } + txBytes, err := txCfg.TxEncoder()(tx) + if err != nil { + return sdk.GasInfo{}, nil, err + } + + // Must simulate now as CheckTx doesn't run Msgs anymore + _, res, err := app.Simulate(txBytes) + + if expSimPass { + if err != nil || res == nil { + return sdk.GasInfo{}, nil, err + } + } else { + if err == nil || res != nil { + return sdk.GasInfo{}, nil, err + } + } + + // Simulate a sending a transaction and committing a block + app.BeginBlock(abci.RequestBeginBlock{Header: header}) + gInfo, res, err := app.SimDeliver(txCfg.TxEncoder(), tx) + + if expPass { + if err != nil || res == nil { + return sdk.GasInfo{}, nil, err + } + } else { + if err == nil || res != nil { + return sdk.GasInfo{}, nil, err + } + } + + app.EndBlock(abci.RequestEndBlock{}) + app.Commit() + + return gInfo, res, err } type GenerateAccountStrategy func(int) []sdk.AccAddress @@ -413,64 +525,6 @@ func TestAddr(addr string, bech string) (sdk.AccAddress, error) { return res, nil } -// CheckBalance checks the balance of an account. -func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - require.True(t, balances.IsEqual(app.BankKeeper.GetAllBalances(ctxCheck, addr))) -} - -// SignCheckDeliver checks a generated signed transaction and simulates a -// block commitment with the given transaction. A test assertion is made using -// the parameter 'expPass' against the result. A corresponding result is -// returned. -func SignCheckDeliver( - t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, -) (sdk.GasInfo, *sdk.Result, error) { - tx, err := helpers.GenSignedMockTx( - rand.New(rand.NewSource(time.Now().UnixNano())), - txCfg, - msgs, - sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, - helpers.DefaultGenTxGas, - chainID, - accNums, - accSeqs, - priv..., - ) - require.NoError(t, err) - txBytes, err := txCfg.TxEncoder()(tx) - require.Nil(t, err) - - // Must simulate now as CheckTx doesn't run Msgs anymore - _, res, err := app.Simulate(txBytes) - - if expSimPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - - // Simulate a sending a transaction and committing a block - app.BeginBlock(abci.RequestBeginBlock{Header: header}) - gInfo, res, err := app.SimDeliver(txCfg.TxEncoder(), tx) - - if expPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - - app.EndBlock(abci.RequestEndBlock{}) - app.Commit() - - return gInfo, res, err -} - // GenSequenceOfTxs generates a set of signed transactions of messages, such // that they differ only by having the sequence numbers incremented between // every transaction. diff --git a/simapp/test_simapp.go b/simapp/test_simapp.go deleted file mode 100644 index 3d0853531..000000000 --- a/simapp/test_simapp.go +++ /dev/null @@ -1,346 +0,0 @@ -package simapp - -import ( - "encoding/json" - "math/rand" - "reflect" - "time" - - abci "github.com/tendermint/tendermint/abci/types" - tmjson "github.com/tendermint/tendermint/libs/json" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - - bam "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - "github.com/cosmos/cosmos-sdk/testutil/mock" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - // cheqd specific imports - cheqdapp "github.com/cheqd/cheqd-node/app" - didtypes "github.com/cheqd/cheqd-node/x/did/types" - resourcetypes "github.com/cheqd/cheqd-node/x/resource/types" -) - -// NewSimappWithCustomOptions initializes a new SimApp with custom options. -func NewSimappWithCustomOptionsForGinkgo(isCheckTx bool, options SetupOptions) *SimApp { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - if err != nil { - panic(err) - } - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), - } - - app := NewSimApp(options.Logger, options.DB, nil, true, options.SkipUpgradeHeights, options.HomePath, options.InvCheckPeriod, options.EncConfig, options.AppOpts) - genesisState := cheqdapp.NewDefaultGenesisState(app.appCodec) - genesisState = genesisStateWithValSetForGinkgo(app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balance) - - if !isCheckTx { - // init chain must be called to stop deliverState from being nil - stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } - - // Initialize the chain - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) - } - - return app -} - -// Setup initializes a new SimApp. A Nop logger is set in SimApp. -func SetupForGinkgo(isCheckTx bool) *SimApp { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - if err != nil { - panic(err) - } - - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(didtypes.BaseMinimalDenom, sdk.NewInt(100000000000000))), - } - - app := SetupWithGenesisValSetForGinkgo(valSet, []authtypes.GenesisAccount{acc}, balance) - - return app -} - -// Setup initializes a new SimApp. A Nop logger is set in SimApp. -func SetupTest(isCheckTx bool) *SimApp { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - if err != nil { - panic(err) - } - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(didtypes.BaseMinimalDenom, sdk.NewInt(100000000000000))), - } - - app := SetupWithGenesisValSetForGinkgo(valSet, []authtypes.GenesisAccount{acc}, balance) - - return app -} - -func genesisStateWithValSetForGinkgo( - app *SimApp, genesisState cheqdapp.GenesisState, - valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, - balances ...banktypes.Balance, -) cheqdapp.GenesisState { - // set genesis accounts - authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - - validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) - delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) - - bondAmt := sdk.DefaultPowerReduction - - for _, val := range valSet.Validators { - pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) - if err != nil { - panic(err) - } - pkAny, err := codectypes.NewAnyWithValue(pk) - if err != nil { - panic(err) - } - validator := stakingtypes.Validator{ - OperatorAddress: sdk.ValAddress(val.Address).String(), - ConsensusPubkey: pkAny, - Jailed: false, - Status: stakingtypes.Bonded, - Tokens: bondAmt, - DelegatorShares: sdk.OneDec(), - Description: stakingtypes.Description{}, - UnbondingHeight: int64(0), - UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), - MinSelfDelegation: sdk.ZeroInt(), - } - validators = append(validators, validator) - delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec())) - - } - // set validators and delegations - stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) - genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis) - - totalSupply := sdk.NewCoins() - for _, b := range balances { - // add genesis acc tokens to total supply - totalSupply = totalSupply.Add(b.Coins...) - } - - for range delegations { - // add delegated tokens to total supply - totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) - } - - // add bonded amount to bonded pool module account - balances = append(balances, banktypes.Balance{ - Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, - }) - - // update total supply - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}) - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) - - // set did module genesis state - didGenesis := didtypes.DefaultGenesis() - genesisState[didtypes.ModuleName] = app.AppCodec().MustMarshalJSON(didGenesis) - - // set resource module genesis state - resourceGenesis := resourcetypes.DefaultGenesis() - genesisState[resourcetypes.ModuleName] = app.AppCodec().MustMarshalJSON(resourceGenesis) - - return genesisState -} - -// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts -// that also act as delegators. For simplicity, each validator is bonded with a delegation -// of one consensus engine unit in the default token of the simapp from first genesis -// account. A Nop logger is set in SimApp. -func SetupWithGenesisValSetForGinkgo(valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { - app, genesisState := setup(true, 5) - genesisState = genesisStateWithValSetForGinkgo(app, genesisState, valSet, genAccs, balances...) - - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } - - // init chain will set the validator set and initialize the genesis accounts - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) - - // commit genesis changes - app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ - Height: app.LastBlockHeight() + 1, - AppHash: app.LastCommitID().Hash, - ValidatorsHash: valSet.Hash(), - NextValidatorsHash: valSet.Hash(), - }}) - - return app -} - -// SetupWithGenesisAccounts initializes a new SimApp with the provided genesis -// accounts and possible balances. -func SetupWithGenesisAccountsForGinkgo(genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - if err != nil { - panic(err) - } - - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - return SetupWithGenesisValSetForGinkgo(valSet, genAccs, balances...) -} - -// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts -// that also act as delegators. -func GenesisStateWithSingleValidatorForGinkgo(app *SimApp) cheqdapp.GenesisState { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - if err != nil { - panic(err) - } - - // create validator set with single validator - validator := tmtypes.NewValidator(pubKey, 1) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balances := []banktypes.Balance{ - { - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), - }, - } - - genesisState := cheqdapp.NewDefaultGenesisState(app.appCodec) - genesisState = genesisStateWithValSetForGinkgo(app, genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...) - - return genesisState -} - -// CheckBalance checks the balance of an account. -func CheckBalanceForGinkgo(app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - if reflect.DeepEqual(balances, app.BankKeeper.GetAllBalances(ctxCheck, addr)) { - panic("Invalid balance of account") - } -} - -// SignCheckDeliver checks a generated signed transaction and simulates a -// block commitment with the given transaction. A test assertion is made using -// the parameter 'expPass' against the result. A corresponding result is -// returned. -func SignCheckDeliverForGinkgo( - txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, -) (sdk.GasInfo, *sdk.Result, error) { - tx, err := helpers.GenSignedMockTx( - rand.New(rand.NewSource(time.Now().UnixNano())), - txCfg, - msgs, - sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, - helpers.DefaultGenTxGas, - chainID, - accNums, - accSeqs, - priv..., - ) - if err != nil { - panic(err) - } - txBytes, err := txCfg.TxEncoder()(tx) - if err != nil { - panic(err) - } - - // Must simulate now as CheckTx doesn't run Msgs anymore - _, res, err := app.Simulate(txBytes) - - if expSimPass { - if err != nil || res == nil { - panic(err) - } - } else { - if err == nil || res != nil { - panic(err) - } - } - - // Simulate a sending a transaction and committing a block - app.BeginBlock(abci.RequestBeginBlock{Header: header}) - gInfo, res, err := app.SimDeliver(txCfg.TxEncoder(), tx) - - if expPass { - if err != nil || res == nil { - panic(err) - } - } else { - if err == nil || res != nil { - panic(err) - } - } - - app.EndBlock(abci.RequestEndBlock{}) - app.Commit() - - return gInfo, res, err -} diff --git a/x/did/keeper/keeper_param_change_proposal_test.go b/x/did/keeper/keeper_param_change_proposal_test.go index 40de8c767..daf1fade1 100644 --- a/x/did/keeper/keeper_param_change_proposal_test.go +++ b/x/did/keeper/keeper_param_change_proposal_test.go @@ -1,8 +1,6 @@ package keeper_test import ( - "testing" - "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -13,6 +11,9 @@ import ( govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ) type HandlerTestSuite struct { @@ -23,36 +24,49 @@ type HandlerTestSuite struct { govHandler govv1beta1.Handler } -func (suite *HandlerTestSuite) SetupTest() { - suite.app = cheqdsimapp.Setup(suite.T(), false) +func (suite *HandlerTestSuite) SetupTest() error { + var err error + suite.app, err = cheqdsimapp.Setup(false) + if err != nil { + return err + } suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) suite.govHandler = params.NewParamChangeProposalHandler(suite.app.ParamsKeeper) -} - -func TestHandlerTestSuite(t *testing.T) { - suite.Run(t, new(HandlerTestSuite)) + return nil } func testProposal(changes ...proposal.ParamChange) *proposal.ParameterChangeProposal { return proposal.NewParameterChangeProposal("title", "description", changes) } -func (suite *HandlerTestSuite) TestProposalHandler() { - testCases := []struct { - name string - proposal *proposal.ParameterChangeProposal - onHandle func() - expErr bool - errMsg string - }{ - { - "all fields", +type TestCaseKeeperProposal struct { + proposal *proposal.ParameterChangeProposal + onHandle func(*HandlerTestSuite) + expErr bool + errMsg string +} + +var _ = DescribeTable("Proposal Handler", func(testCase TestCaseKeeperProposal) { + handlerSuite := new(HandlerTestSuite) + err := handlerSuite.SetupTest() + Expect(err).To(BeNil()) + + err = handlerSuite.govHandler(handlerSuite.ctx, testCase.proposal) + if testCase.expErr { + Expect(err).NotTo(BeNil()) + } else { + Expect(err).To(BeNil()) + testCase.onHandle(handlerSuite) + } +}, + Entry("all fields", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "10000000000"}, "update_did": {"denom": "ncheq", "amount": "4000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() { + func(handlerSuite *HandlerTestSuite) { expectedFeeParams := didtypes.FeeParams{ TxTypes: map[string]sdk.Coin{ didtypes.DefaultKeyCreateDid: {Denom: didtypes.BaseMinimalDenom, Amount: sdk.NewInt(10000000000)}, @@ -62,21 +76,21 @@ func (suite *HandlerTestSuite) TestProposalHandler() { BurnFactor: sdk.MustNewDecFromStr("0.600000000000000000"), } - feeParams := suite.app.DidKeeper.GetParams(suite.ctx) + feeParams := handlerSuite.app.DidKeeper.GetParams(handlerSuite.ctx) - suite.Require().Equal(expectedFeeParams, feeParams) + Expect(expectedFeeParams).To(Equal(feeParams)) }, false, "", - }, - { - "new msg type added", + }), + Entry("new msg type added", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "5000000000"}, "update_did": {"denom": "ncheq", "amount": "2000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "1000000000"}, "new_msg_type": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.500000000000000000"}`, }), - func() { + func(handlerSuite *HandlerTestSuite) { expectedFeeParams := didtypes.FeeParams{ TxTypes: map[string]sdk.Coin{ didtypes.DefaultKeyCreateDid: {Denom: didtypes.BaseMinimalDenom, Amount: sdk.NewInt(didtypes.DefaultCreateDidTxFee)}, @@ -87,109 +101,101 @@ func (suite *HandlerTestSuite) TestProposalHandler() { BurnFactor: sdk.MustNewDecFromStr(didtypes.DefaultBurnFactor), } - feeParams := suite.app.DidKeeper.GetParams(suite.ctx) + feeParams := handlerSuite.app.DidKeeper.GetParams(handlerSuite.ctx) - suite.Require().Equal(expectedFeeParams, feeParams) + Expect(expectedFeeParams).To(Equal(feeParams)) }, false, "", - }, - { - "empty value", + }), + Entry("empty value", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - { - "omit fields", + ), + Entry("omit fields", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: ` - { - "tx_types": { - "create_did": {"denom": "ncheq", "amount": "10000000000"}, - "update_did": {"denom": "ncheq", "amount": "4000000000"} - }, - "burn_factor": "0.600000000000000000" - }`, + { + "tx_types": { + "create_did": {"denom": "ncheq", "amount": "10000000000"}, + "update_did": {"denom": "ncheq", "amount": "4000000000"} + }, + "burn_factor": "0.600000000000000000" + }`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - { - "invalid value: case `create_did` amount 0", + ), + Entry("invalid value: case `create_did` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "0"}, "update_did": {"denom": "ncheq", "amount": "4000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - { - "invalid value: case `update_did` amount 0", + ), + Entry("invalid value: case `update_did` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "10000000000"}, "update_did": {"denom": "ncheq", "amount": "0"}, "deactivate_did": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `deactivate_did` amount 0", + }), + Entry("invalid value: case `deactivate_did` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "10000000000"}, "update_did": {"denom": "ncheq", "amount": "4000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "0"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - { - "invalid value: case `burn_factor` -1", + ), + Entry("invalid value: case `burn_factor` -1", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "10000000000"}, "update_did": {"denom": "ncheq", "amount": "4000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "-1"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - { - "invalid value: case `burn_factor` 1.1", + ), + Entry("invalid value: case `burn_factor` 1.1", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: didtypes.ModuleName, Key: string(didtypes.ParamStoreKeyFeeParams), Value: `{"tx_types": {"create_did": {"denom": "ncheq", "amount": "10000000000"}, "update_did": {"denom": "ncheq", "amount": "4000000000"}, "deactivate_did": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "1.1"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", }, - } - - for _, tc := range testCases { - tc := tc - suite.Run(tc.name, func() { - err := suite.govHandler(suite.ctx, tc.proposal) - if tc.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - tc.onHandle() - } - }) - } -} + ), +) diff --git a/x/did/keeper/keeper_suite_test.go b/x/did/keeper/keeper_suite_test.go new file mode 100644 index 000000000..3a9fc7d85 --- /dev/null +++ b/x/did/keeper/keeper_suite_test.go @@ -0,0 +1,13 @@ +package keeper_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestKeeper(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Keeper Suite") +} diff --git a/x/resource/keeper/keeper_param_change_proposal_test.go b/x/resource/keeper/keeper_param_change_proposal_test.go index 707902af0..73ff29707 100644 --- a/x/resource/keeper/keeper_param_change_proposal_test.go +++ b/x/resource/keeper/keeper_param_change_proposal_test.go @@ -1,8 +1,6 @@ package keeper_test import ( - "testing" - "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -13,6 +11,9 @@ import ( govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ) type HandlerTestSuite struct { @@ -23,36 +24,53 @@ type HandlerTestSuite struct { govHandler govv1beta1.Handler } -func (suite *HandlerTestSuite) SetupTest() { - suite.app = cheqdsimapp.Setup(suite.T(), false) +func (suite *HandlerTestSuite) SetupTest() error { + var err error + suite.app, err = cheqdsimapp.Setup(false) + if err != nil { + return err + } suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) suite.govHandler = params.NewParamChangeProposalHandler(suite.app.ParamsKeeper) + return nil } -func TestHandlerTestSuite(t *testing.T) { - suite.Run(t, new(HandlerTestSuite)) -} +// func TestHandlerTestSuite(t *testing.T) { +// suite.Run(t, new(HandlerTestSuite)) +// } func testProposal(changes ...proposal.ParamChange) *proposal.ParameterChangeProposal { return proposal.NewParameterChangeProposal("title", "description", changes) } -func (suite *HandlerTestSuite) TestProposalHandler() { - testCases := []struct { - name string - proposal *proposal.ParameterChangeProposal - onHandle func() - expErr bool - errMsg string - }{ - { - "all fields", +type TestCaseKeeperProposal struct { + proposal *proposal.ParameterChangeProposal + onHandle func(*HandlerTestSuite) + expErr bool + errMsg string +} + +var _ = DescribeTable("Proposal Handler", func(testcase TestCaseKeeperProposal) { + handlerSuite := new(HandlerTestSuite) + err := handlerSuite.SetupTest() + Expect(err).To(BeNil()) + + err = handlerSuite.govHandler(handlerSuite.ctx, testcase.proposal) + if testcase.expErr { + Expect(err).NotTo(BeNil()) + } else { + Expect(err).To(BeNil()) + testcase.onHandle(handlerSuite) + } +}, + Entry("all fields", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "10000000000"}, "json": {"denom": "ncheq", "amount": "4000000000"}, "default": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() { + func(handlerSuite *HandlerTestSuite) { expectedFeeParams := resourcetypes.FeeParams{ MediaTypes: map[string]sdk.Coin{ resourcetypes.DefaultKeyCreateResourceImage: {Denom: resourcetypes.BaseMinimalDenom, Amount: sdk.NewInt(10000000000)}, @@ -62,21 +80,21 @@ func (suite *HandlerTestSuite) TestProposalHandler() { BurnFactor: sdk.MustNewDecFromStr("0.600000000000000000"), } - feeParams := suite.app.ResourceKeeper.GetParams(suite.ctx) + feeParams := handlerSuite.app.ResourceKeeper.GetParams(handlerSuite.ctx) - suite.Require().Equal(expectedFeeParams, feeParams) + Expect(expectedFeeParams).To(Equal(feeParams)) }, false, "", - }, - { - "new media type added", + }), + Entry("new media type added", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "5000000000"}, "json": {"denom": "ncheq", "amount": "2000000000"}, "default": {"denom": "ncheq", "amount": "1000000000"}, "text/html": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.500000000000000000"}`, }), - func() { + func(handlerSuite *HandlerTestSuite) { expectedFeeParams := resourcetypes.FeeParams{ MediaTypes: map[string]sdk.Coin{ resourcetypes.DefaultKeyCreateResourceImage: {Denom: resourcetypes.BaseMinimalDenom, Amount: sdk.NewInt(resourcetypes.DefaultCreateResourceImageFee)}, @@ -87,26 +105,26 @@ func (suite *HandlerTestSuite) TestProposalHandler() { BurnFactor: sdk.MustNewDecFromStr(resourcetypes.DefaultBurnFactor), } - feeParams := suite.app.ResourceKeeper.GetParams(suite.ctx) + feeParams := handlerSuite.app.ResourceKeeper.GetParams(handlerSuite.ctx) - suite.Require().Equal(expectedFeeParams, feeParams) + Expect(expectedFeeParams).To(Equal(feeParams)) }, false, "", - }, - { - "empty value", + }), + Entry("empty value", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "omit fields", + }), + Entry("omit fields", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), @@ -119,77 +137,63 @@ func (suite *HandlerTestSuite) TestProposalHandler() { "burn_factor": "0.600000000000000000" }`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `image` amount 0", + }), + Entry("invalid value: case `image` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "0"}, "json": {"denom": "ncheq", "amount": "4000000000"}, "default": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `json` amount 0", + }), + Entry("invalid value: case `json` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "10000000000"}, "json": {"denom": "ncheq", "amount": "0"}, "default": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `default` amount 0", + }), + Entry("invalid value: case `default` amount 0", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "10000000000"}, "json": {"denom": "ncheq", "amount": "4000000000"}, "default": {"denom": "ncheq", "amount": "0"}}, "burn_factor": "0.600000000000000000"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `burn_factor` -1", + }), + Entry("invalid value: case `burn_factor` -1", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "10000000000"}, "json": {"denom": "ncheq", "amount": "4000000000"}, "default": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "-1"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - { - "invalid value: case `burn_factor` 1.1", + }), + Entry("invalid value: case `burn_factor` 1.1", + TestCaseKeeperProposal{ testProposal(proposal.ParamChange{ Subspace: resourcetypes.ModuleName, Key: string(resourcetypes.ParamStoreKeyFeeParams), Value: `{"media_types": {"image": {"denom": "ncheq", "amount": "10000000000"}, "json": {"denom": "ncheq", "amount": "4000000000"}, "default": {"denom": "ncheq", "amount": "2000000000"}}, "burn_factor": "1.1"}`, }), - func() {}, + func(*HandlerTestSuite) {}, true, "", - }, - } - - for _, tc := range testCases { - tc := tc - suite.Run(tc.name, func() { - err := suite.govHandler(suite.ctx, tc.proposal) - if tc.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - tc.onHandle() - } - }) - } -} + }), +) diff --git a/x/resource/keeper/keeper_suite_test.go b/x/resource/keeper/keeper_suite_test.go new file mode 100644 index 000000000..3a9fc7d85 --- /dev/null +++ b/x/resource/keeper/keeper_suite_test.go @@ -0,0 +1,13 @@ +package keeper_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestKeeper(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Keeper Suite") +}