Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(template): scaffold genesis validation tests #1489

Merged
merged 24 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 0 additions & 37 deletions starport/services/scaffolder/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import (
"os"
"path/filepath"

"github.com/gobuffalo/genny"
"github.com/tendermint/starport/starport/pkg/multiformatname"
"github.com/tendermint/starport/starport/pkg/placeholder"
modulecreate "github.com/tendermint/starport/starport/templates/module/create"
)

const (
Expand All @@ -21,40 +18,6 @@ const (
componentPacket = "packet"
)

// supportMsgServer checks if the module supports the MsgServer convention
// if not, the module codebase is modified to support it
// https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-031-msg-service.md
func supportMsgServer(
replacer placeholder.Replacer,
appPath string,
opts *modulecreate.MsgServerOptions,
) (*genny.Generator, error) {
// Check if convention used
msgServerDefined, err := isMsgServerDefined(appPath, opts.ModuleName)
if err != nil {
return nil, err
}
if !msgServerDefined {
// Patch the module to support the convention
return modulecreate.AddMsgServerConventionToLegacyModule(replacer, opts)
}
return nil, nil
}

// isMsgServerDefined checks if the module uses the MsgServer convention for transactions
// this is checked by verifying the existence of the tx.proto file
func isMsgServerDefined(appPath, moduleName string) (bool, error) {
txProto, err := filepath.Abs(filepath.Join(appPath, "proto", moduleName, "tx.proto"))
if err != nil {
return false, err
}

if _, err := os.Stat(txProto); os.IsNotExist(err) {
return false, nil
}
return true, err
}

// checkComponentValidity performs various checks common to all components to verify if it can be scaffolded
func checkComponentValidity(appPath, moduleName string, compName multiformatname.Name, noMessage bool) error {
ok, err := moduleExists(appPath, moduleName)
Expand Down
6 changes: 2 additions & 4 deletions starport/services/scaffolder/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ func (s *Scaffolder) AddMessage(

// Check and support MsgServer convention
var gens []*genny.Generator
g, err = supportMsgServer(
gens, err = supportMsgServer(
gens,
tracer,
s.path,
&modulecreate.MsgServerOptions{
Expand All @@ -129,9 +130,6 @@ func (s *Scaffolder) AddMessage(
if err != nil {
return sm, err
}
if g != nil {
gens = append(gens, g)
}

// Scaffold
g, err = message.NewStargate(tracer, opts)
Expand Down
72 changes: 72 additions & 0 deletions starport/services/scaffolder/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package scaffolder

import (
"os"
"path/filepath"

"github.com/gobuffalo/genny"
"github.com/tendermint/starport/starport/pkg/placeholder"
modulecreate "github.com/tendermint/starport/starport/templates/module/create"
)

// supportGenesisTests checks if types/genesis_test.go exists
// appends the generator to create the file if it doesn't
func supportGenesisTests(
gens []*genny.Generator,
appPath,
appName,
modulePath,
moduleName string,
) ([]*genny.Generator, error) {
filepath, err := filepath.Abs(filepath.Join(appPath, "x", moduleName, "types", "genesis_test.go"))
if err != nil {
return nil, err
}
if _, err := os.Stat(filepath); os.IsNotExist(err) {
g, err := modulecreate.AddGenesisTest(appName, modulePath, moduleName)
if err != nil {
return nil, err
}
gens = append(gens, g)
}
return gens, err
}

// supportMsgServer checks if the module supports the MsgServer convention
// appends the generator to support it if it doesn't
// https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-031-msg-service.md
func supportMsgServer(
gens []*genny.Generator,
replacer placeholder.Replacer,
appPath string,
opts *modulecreate.MsgServerOptions,
) ([]*genny.Generator, error) {
// Check if convention used
msgServerDefined, err := isMsgServerDefined(appPath, opts.ModuleName)
if err != nil {
return nil, err
}
if !msgServerDefined {
// Patch the module to support the convention
g, err := modulecreate.AddMsgServerConventionToLegacyModule(replacer, opts)
if err != nil {
return nil, err
}
gens = append(gens, g)
}
return gens, nil
}

// isMsgServerDefined checks if the module uses the MsgServer convention for transactions
// this is checked by verifying the existence of the tx.proto file
func isMsgServerDefined(appPath, moduleName string) (bool, error) {
txProto, err := filepath.Abs(filepath.Join(appPath, "proto", moduleName, "tx.proto"))
if err != nil {
return false, err
}

if _, err := os.Stat(txProto); os.IsNotExist(err) {
return false, nil
}
return true, err
}
15 changes: 12 additions & 3 deletions starport/services/scaffolder/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ func (s *Scaffolder) AddType(
gens []*genny.Generator
)
// Check and support MsgServer convention
g, err = supportMsgServer(
gens, err = supportMsgServer(
gens,
tracer,
s.path,
&modulecreate.MsgServerOptions{
Expand All @@ -157,8 +158,16 @@ func (s *Scaffolder) AddType(
if err != nil {
return sm, err
}
if g != nil {
gens = append(gens, g)

gens, err = supportGenesisTests(
gens,
opts.AppPath,
opts.AppName,
opts.ModulePath,
opts.ModuleName,
)
if err != nil {
return sm, err
}

// create the type generator depending on the model
Expand Down
23 changes: 23 additions & 0 deletions starport/templates/module/create/genesistest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package modulecreate

import (
"github.com/gobuffalo/genny"
"github.com/gobuffalo/plush"
"github.com/gobuffalo/plushgen"
)

// AddGenesisTest returns the generator to generate genesis_test.go
func AddGenesisTest(appName, modulePath, moduleName string) (*genny.Generator, error) {
g := genny.New()
if err := g.Box(genesisTestTemplate); err != nil {
return g, err
}
ctx := plush.NewContext()
ctx.Set("moduleName", moduleName)
ctx.Set("modulePath", modulePath)
ctx.Set("appName", appName)

g.Transformer(plushgen.Transformer(ctx))
g.Transformer(genny.Replace("{{moduleName}}", moduleName))
return g, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package types_test

import (
"testing"
"github.com/stretchr/testify/require"
"<%= modulePath %>/x/<%= moduleName %>/types"
)

func TestGenesisState_Validate(t *testing.T) {
for _, tc := range []struct {
desc string
genState *types.GenesisState
valid bool
} {
{
desc: "default is valid",
genState: types.DefaultGenesis(),
valid: true,
},
{
desc: "valid genesis state",
genState: &types.GenesisState{
// this line is used by starport scaffolding # types/genesis/validField
},
valid: true,
},
// this line is used by starport scaffolding # types/genesis/testcase
} {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
err := tc.genState.Validate()
if tc.valid {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
}
3 changes: 3 additions & 0 deletions starport/templates/module/create/stargate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ func NewStargate(opts *CreateOptions) (*genny.Generator, error) {
if err := g.Box(msgServerTemplate); err != nil {
return g, err
}
if err := g.Box(genesisTestTemplate); err != nil {
return g, err
}
if err := g.Box(stargateTemplate); err != nil {
return g, err
}
Expand Down
10 changes: 7 additions & 3 deletions starport/templates/module/create/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ var (
//go:embed msgserver/* msgserver/**/*
fsMsgServer embed.FS

stargateTemplate = xgenny.NewEmbedWalker(fsStargate, "stargate/")
ibcTemplate = xgenny.NewEmbedWalker(fsIBC, "ibc/")
msgServerTemplate = xgenny.NewEmbedWalker(fsMsgServer, "msgserver/")
//go:embed genesistest/* genesistest/**/*
fsGenesisTest embed.FS

stargateTemplate = xgenny.NewEmbedWalker(fsStargate, "stargate/")
ibcTemplate = xgenny.NewEmbedWalker(fsIBC, "ibc/")
msgServerTemplate = xgenny.NewEmbedWalker(fsMsgServer, "msgserver/")
genesisTestTemplate = xgenny.NewEmbedWalker(fsGenesisTest, "genesistest/")
)
4 changes: 4 additions & 0 deletions starport/templates/module/placeholders.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ const (
PlaceholderIBCAppScopedKeeperDefinition = "// this line is used by starport scaffolding # ibc/app/scopedKeeper/definition"
PlaceholderIBCAppKeeperArgument = "// this line is used by starport scaffolding # ibc/app/keeper/argument"
PlaceholderIBCAppRouter = "// this line is used by starport scaffolding # ibc/app/router"

// Genesis test
PlaceholderTypesGenesisTestcase = "// this line is used by starport scaffolding # types/genesis/testcase"
PlaceholderTypesGenesisValidField = "// this line is used by starport scaffolding # types/genesis/validField"
)
67 changes: 67 additions & 0 deletions starport/templates/typed/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (

"github.com/gobuffalo/genny"
"github.com/tendermint/starport/starport/pkg/placeholder"
"github.com/tendermint/starport/starport/templates/module"
)

func (t *typedStargate) genesisModify(replacer placeholder.Replacer, opts *Options, g *genny.Generator) {
g.RunFn(t.genesisProtoModify(replacer, opts))
g.RunFn(t.genesisTypesModify(replacer, opts))
g.RunFn(t.genesisModuleModify(replacer, opts))
g.RunFn(t.genesisTestsModify(replacer, opts))
}

func (t *typedStargate) genesisProtoModify(replacer placeholder.Replacer, opts *Options) genny.RunFn {
Expand Down Expand Up @@ -146,6 +148,71 @@ genesis.%[2]vCount = k.Get%[2]vCount(ctx)
}
}

func (t *typedStargate) genesisTestsModify(replacer placeholder.Replacer, opts *Options) genny.RunFn {
return func(r *genny.Runner) error {
path := fmt.Sprintf("x/%s/types/genesis_test.go", opts.ModuleName)
f, err := r.Disk.Find(path)
if err != nil {
return err
}

templateValid := `%[1]v
%[2]vList: []types.%[2]v{
{
Id: 0,
},
{
Id: 1,
},
},
%[2]vCount: 2,`
replacementValid := fmt.Sprintf(
templateValid,
module.PlaceholderTypesGenesisValidField,
opts.TypeName.UpperCamel,
)
content := replacer.Replace(f.String(), module.PlaceholderTypesGenesisValidField, replacementValid)

templateTests := `%[1]v
{
desc: "duplicated %[2]v",
genState: &types.GenesisState{
%[3]vList: []types.%[3]v{
{
Id: 0,
},
{
Id: 0,
},
},
},
valid: false,
},
{
desc: "invalid %[2]v count",
genState: &types.GenesisState{
%[3]vList: []types.%[3]v{
{
Id: 1,
},
},
%[3]vCount: 0,
},
valid: false,
},`
lumtis marked this conversation as resolved.
Show resolved Hide resolved
replacementTests := fmt.Sprintf(
templateTests,
module.PlaceholderTypesGenesisTestcase,
opts.TypeName.LowerCamel,
opts.TypeName.UpperCamel,
)
content = replacer.Replace(content, module.PlaceholderTypesGenesisTestcase, replacementTests)

newFile := genny.NewFileS(path, content)
return r.File(newFile)
}
}

// PatchGenesisTypeImport patches types/genesis.go content from the issue:
// https://github.com/tendermint/starport/issues/992
func PatchGenesisTypeImport(replacer placeholder.Replacer, content string) string {
Expand Down
Loading