Skip to content

Commit

Permalink
TestParser & TestProtoGoPackageReduction
Browse files Browse the repository at this point in the history
  • Loading branch information
Reecepbcups committed Mar 1, 2024
1 parent b9c6cbe commit 8914ef1
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 19 deletions.
39 changes: 35 additions & 4 deletions spawn/proto_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ func ProtoServiceParser(logger *slog.Logger, content []byte, pkgDir string, ft F
pRPCs := make([]*ProtoRPC, 0)
c := strings.Split(string(content), "\n")

moduleName := GetProtoPackageName(content)

for idx, line := range c {
if strings.Contains(line, "rpc ") {
line = strings.TrimLeft(line, " ")
line = strings.TrimLeft(line, "\t")

if strings.HasPrefix(line, "rpc ") {
// if strings.Contains(line, "rpc ") {
line = strings.Trim(line, " ")
logger.Debug("proto file", "rpc line", line)

Expand All @@ -58,13 +64,39 @@ func ProtoServiceParser(logger *slog.Logger, content []byte, pkgDir string, ft F
Res: words[2],
Location: pkgDir,
FType: ft,
Module: moduleName,
})
}
}

return pRPCs
}

// given a proto file content, parse out the package name
// package cnd.v1; returns cnd as the name.
func GetProtoPackageName(content []byte) string {
for _, line := range strings.Split(string(content), "\n") {
line = strings.Trim(line, " ")
line = strings.Trim(line, "\t")

if strings.HasPrefix(line, "package ") {
// package cnd.v1;
line = strings.Trim(line, " ")

// cnd.v1;
line = strings.Split(line, "package ")[1]

// split at the first .
line = strings.Split(line, ".")[0]

return strings.Trim(line, " ")
}
}

return ""

}

// GetGoPackageLocationOfFiles parses the proto content pulling out the relative path
// of the go package location.
// option go_package = "github.com/rollchains/mychain/x/cnd/types"; -> x/cnd/types
Expand All @@ -76,10 +108,9 @@ func GetGoPackageLocationOfFiles(bz []byte) string {
// option go_package = "github.com/rollchains/mychain/x/cnd/types";
line = strings.Trim(line, " ")

// line = strings.NewReplacer("option go_package", "", "=", "", ";", "", , "", "\"", "").Replace(line)

// x/cnd/types";
line = strings.Split(line, fmt.Sprintf("%s/", modName))[1]
line := strings.Split(line, fmt.Sprintf("%s/", modName))[1]

// x/cnd/types
line = strings.Split(line, "\";")[0]

Expand Down
184 changes: 169 additions & 15 deletions spawn/proto_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,184 @@ package spawn

import (
"fmt"
"log/slog"
"os"
"testing"

"github.com/stretchr/testify/require"
)

var logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: false,
Level: slog.LevelError,
}))

func TestParser(t *testing.T) {
type tcase struct {
name string
modPkg string
protoContent string
ft FileType
expected []*ProtoRPC
}

tests := []tcase{
{
name: "query, multi line rpc",
modPkg: "github.com/orgName/chainName",
ft: Query,
protoContent: `syntax = "proto3";
package cnd.v1;
import "google/api/annotations.proto";
import "cnd/v1/genesis.proto";
proto := `syntax = "proto3";
package cnd.v1;
option go_package = "github.com/orgName/chainName/x/cnd/types";
import "google/api/annotations.proto";
import "cnd/v1/genesis.proto";
service Query {
// rpc for Params, make sure this line does not get picked up
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cnd/v1/params";
}
option go_package = "github.com/rollchains/mychain/x/cnd/types";
// multi line return statement (from proto linting long names)
rpc FeeShare(QueryFeeShareRequest)
returns (QueryFeeShareResponse) {
option (google.api.http).get = "/cnd/v1/feeshare";
}
}`,
expected: []*ProtoRPC{
{
Name: "Params",
Req: "QueryParamsRequest",
Res: "QueryParamsResponse",
Module: "cnd",
Location: "x/cnd/types",
FType: Query,
FileLoc: "",
},
{
Name: "FeeShare",
Req: "QueryFeeShareRequest",
Res: "QueryFeeShareResponse",
Module: "cnd",
Location: "x/cnd/types",
FType: Query,
FileLoc: "",
},
},
},
{
name: "tx, multiple msgs",
modPkg: "github.com/aaa/bbb",
ft: Tx,
protoContent: `syntax = "proto3";
package amm.v1;
import "cosmos/msg/v1/msg.proto";
import "amm/v1/genesis.proto";
option go_package = "github.com/aaa/bbb/x/amm/nested/types";
// Query provides defines the gRPC querier service.
service Query {
// Params queries all parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/cnd/v1/params";
service Msg {
option (cosmos.msg.v1.service) = true;
//rpc does some things
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
rpc UpdateParams2(MsgUpdateParams2) returns (MsgUpdateParamsResponse2);
}`,
expected: []*ProtoRPC{
{
Name: "UpdateParams",
Req: "MsgUpdateParams",
Res: "MsgUpdateParamsResponse",
Module: "amm",
Location: "x/amm/nested/types",
FType: Tx,
FileLoc: "",
},
{
Name: "UpdateParams2",
Req: "MsgUpdateParams2",
Res: "MsgUpdateParamsResponse2",
Module: "amm",
Location: "x/amm/nested/types",
FType: Tx,
FileLoc: "",
},
},
},
}

rpc FeeShare(QueryFeeShareRequest)
returns (QueryFeeShareResponse) {
option (google.api.http).get = "/cnd/v1/feeshare";
defer os.Remove("go.mod")

for _, tc := range tests {
tc := tc

content := []byte(tc.protoContent)

buildMockGoMod(t, tc.modPkg)

goPkgDir := GetGoPackageLocationOfFiles(content)

r := ProtoServiceParser(logger, content, goPkgDir, tc.ft)

require.Equal(t, len(tc.expected), len(r), tc.name, *r[0])

require.Equal(t, tc.expected, r)

os.Remove("go.mod")
}
}`
fmt.Println(proto)
}

func TestProtoGoPackageReduction(t *testing.T) {
type tcase struct {
modPkg string
input string
expected string
}

tests := []tcase{
{
modPkg: "github.com/rollchains/mychain",
input: `option go_package = "github.com/rollchains/mychain/x/cnd/types";`,
expected: "x/cnd/types",
},
{
modPkg: "github.com/rollchains/other",
input: `option go_package = "github.com/rollchains/other/x/cnd/types";`,
expected: "x/cnd/types",
},
{
modPkg: "github.com/rollchains/other",
input: `option go_package = "github.com/rollchains/other/x/cosmosmod/types";`,
expected: "x/cosmosmod/types",
},
{
modPkg: "github.com/abcchain/misc",
input: `option go_package = "github.com/abcchain/misc/x/module/subfolder/types";`,
expected: "x/module/subfolder/types",
},
}

defer os.Remove("go.mod")

for _, tc := range tests {
tc := tc

buildMockGoMod(t, tc.modPkg)

actual := GetGoPackageLocationOfFiles([]byte(tc.input))
require.Equal(t, tc.expected, actual)

os.Remove("go.mod")
}
}

// make sure to `defer os.Remove("go.mod")` after calling
func buildMockGoMod(t *testing.T, moduleName string) {
// create a go.mod file for this test
f, err := os.Create("go.mod")
require.NoError(t, err)
defer f.Close()
_, err = f.WriteString(fmt.Sprintf("module %s", moduleName))
require.NoError(t, err)
}

0 comments on commit 8914ef1

Please sign in to comment.