mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-10 00:20:00 +08:00
fix(goctl): allow duplicate_path_expression under different prefix (#4626)
This commit is contained in:
@@ -14,69 +14,97 @@ import (
|
||||
)
|
||||
|
||||
func Test_Parse(t *testing.T) {
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
apiSpec, err := Parse("./testdata/example.api", nil)
|
||||
assert.Nil(t, err)
|
||||
ast := assert.New(t)
|
||||
ast.Equal(spec.Info{
|
||||
Title: "type title here",
|
||||
Desc: "type desc here",
|
||||
Version: "type version here",
|
||||
Author: "type author here",
|
||||
Email: "type email here",
|
||||
Properties: map[string]string{
|
||||
"title": "type title here",
|
||||
"desc": "type desc here",
|
||||
"version": "type version here",
|
||||
"author": "type author here",
|
||||
"email": "type email here",
|
||||
},
|
||||
}, apiSpec.Info)
|
||||
ast.True(func() bool {
|
||||
for _, group := range apiSpec.Service.Groups {
|
||||
value, ok := group.Annotation.Properties["summary"]
|
||||
if ok {
|
||||
return value == "test"
|
||||
}
|
||||
}
|
||||
return false
|
||||
}())
|
||||
})
|
||||
t.Run(
|
||||
"valid", func(t *testing.T) {
|
||||
apiSpec, err := Parse("./testdata/example.api", nil)
|
||||
assert.Nil(t, err)
|
||||
ast := assert.New(t)
|
||||
ast.Equal(
|
||||
spec.Info{
|
||||
Title: "type title here",
|
||||
Desc: "type desc here",
|
||||
Version: "type version here",
|
||||
Author: "type author here",
|
||||
Email: "type email here",
|
||||
Properties: map[string]string{
|
||||
"title": "type title here",
|
||||
"desc": "type desc here",
|
||||
"version": "type version here",
|
||||
"author": "type author here",
|
||||
"email": "type email here",
|
||||
},
|
||||
}, apiSpec.Info,
|
||||
)
|
||||
ast.True(
|
||||
func() bool {
|
||||
for _, group := range apiSpec.Service.Groups {
|
||||
value, ok := group.Annotation.Properties["summary"]
|
||||
if ok {
|
||||
return value == "test"
|
||||
}
|
||||
}
|
||||
return false
|
||||
}(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
data, err := os.ReadFile("./testdata/invalid.api")
|
||||
assert.NoError(t, err)
|
||||
splits := bytes.Split(data, []byte("-----"))
|
||||
var testFile []string
|
||||
for idx, split := range splits {
|
||||
replacer := strings.NewReplacer(" ", "", "\t", "", "\n", "", "\r", "", "\f", "")
|
||||
r := replacer.Replace(string(split))
|
||||
if len(r) == 0 {
|
||||
continue
|
||||
}
|
||||
filename := filepath.Join(t.TempDir(), fmt.Sprintf("invalid%d.api", idx))
|
||||
err := os.WriteFile(filename, split, 0666)
|
||||
t.Run(
|
||||
"invalid", func(t *testing.T) {
|
||||
data, err := os.ReadFile("./testdata/invalid.api")
|
||||
assert.NoError(t, err)
|
||||
testFile = append(testFile, filename)
|
||||
}
|
||||
for _, v := range testFile {
|
||||
_, err := Parse(v, nil)
|
||||
splits := bytes.Split(data, []byte("-----"))
|
||||
var testFile []string
|
||||
for idx, split := range splits {
|
||||
replacer := strings.NewReplacer(" ", "", "\t", "", "\n", "", "\r", "", "\f", "")
|
||||
r := replacer.Replace(string(split))
|
||||
if len(r) == 0 {
|
||||
continue
|
||||
}
|
||||
filename := filepath.Join(t.TempDir(), fmt.Sprintf("invalid%d.api", idx))
|
||||
err := os.WriteFile(filename, split, 0666)
|
||||
assert.NoError(t, err)
|
||||
testFile = append(testFile, filename)
|
||||
}
|
||||
for _, v := range testFile {
|
||||
_, err := Parse(v, nil)
|
||||
assertx.Error(t, err)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"circleImport", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/base.api", nil)
|
||||
assertx.Error(t, err)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
t.Run("circleImport", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/base.api", nil)
|
||||
assertx.Error(t, err)
|
||||
})
|
||||
t.Run(
|
||||
"link_import", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/link_import.api", nil)
|
||||
assert.Nil(t, err)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run("link_import", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/link_import.api", nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(
|
||||
"duplicate_types", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/duplicate_type.api", nil)
|
||||
assertx.Error(t, err)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run("duplicate_types", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/duplicate_type.api", nil)
|
||||
assertx.Error(t, err)
|
||||
})
|
||||
t.Run(
|
||||
"duplicate_path_expression", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/duplicate_path_expression.api", nil)
|
||||
assertx.Error(t, err)
|
||||
},
|
||||
)
|
||||
t.Run(
|
||||
"duplicate_path_expression_different_prefix", func(t *testing.T) {
|
||||
_, err := Parse("./testdata/duplicate_path_expression_different_prefix.api", nil)
|
||||
|
||||
assert.Nil(t, err)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
atServerGroupKey = "group:"
|
||||
atServerPrefixKey = "prefix:"
|
||||
atServerGroupKey = "group"
|
||||
atServerPrefixKey = "prefix"
|
||||
)
|
||||
|
||||
// API is the parsed api file.
|
||||
@@ -38,18 +38,24 @@ func convert2API(a *ast.AST, importSet map[string]lang.PlaceholderType, is *impo
|
||||
syntax, ok := one.(*ast.SyntaxStmt)
|
||||
if !ok {
|
||||
syntax = &ast.SyntaxStmt{
|
||||
Syntax: ast.NewTokenNode(token.Token{
|
||||
Type: token.IDENT,
|
||||
Text: token.Syntax,
|
||||
}),
|
||||
Assign: ast.NewTokenNode(token.Token{
|
||||
Type: token.ASSIGN,
|
||||
Text: "=",
|
||||
}),
|
||||
Value: ast.NewTokenNode(token.Token{
|
||||
Type: token.STRING,
|
||||
Text: `"v1"`,
|
||||
}),
|
||||
Syntax: ast.NewTokenNode(
|
||||
token.Token{
|
||||
Type: token.IDENT,
|
||||
Text: token.Syntax,
|
||||
},
|
||||
),
|
||||
Assign: ast.NewTokenNode(
|
||||
token.Token{
|
||||
Type: token.ASSIGN,
|
||||
Text: "=",
|
||||
},
|
||||
),
|
||||
Value: ast.NewTokenNode(
|
||||
token.Token{
|
||||
Type: token.STRING,
|
||||
Text: `"v1"`,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,10 +139,14 @@ func (api *API) checkServiceStmt() error {
|
||||
for _, item := range v.Routes {
|
||||
handlerChecker.checkNodeWithPrefix(group, item.AtHandler.Name)
|
||||
path := fmt.Sprintf("[%s]:%s", prefix, item.Route.Format(""))
|
||||
pathChecker.check(ast.NewTokenNode(token.Token{
|
||||
Text: path,
|
||||
Position: item.Route.Pos(),
|
||||
}))
|
||||
pathChecker.check(
|
||||
ast.NewTokenNode(
|
||||
token.Token{
|
||||
Text: path,
|
||||
Position: item.Route.Pos(),
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
return f.error()
|
||||
@@ -237,7 +247,8 @@ func (api *API) getAtServerValue(atServer *ast.AtServerStmt, key string) string
|
||||
|
||||
func (api *API) mergeAPI(in *API) error {
|
||||
if api.Syntax.Value.Format() != in.Syntax.Value.Format() {
|
||||
return ast.SyntaxError(in.Syntax.Value.Pos(),
|
||||
return ast.SyntaxError(
|
||||
in.Syntax.Value.Pos(),
|
||||
"multiple syntax value expression, expected <%s>, got <%s>",
|
||||
api.Syntax.Value.Format(),
|
||||
in.Syntax.Value.Format(),
|
||||
|
||||
21
tools/goctl/pkg/parser/api/parser/testdata/duplicate_path_expression.api
vendored
Normal file
21
tools/goctl/pkg/parser/api/parser/testdata/duplicate_path_expression.api
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
syntax = "v1"
|
||||
|
||||
@server (
|
||||
group: path2
|
||||
middleware: Path
|
||||
prefix: /v1/v3
|
||||
timeout: 100ms
|
||||
)
|
||||
service example {
|
||||
@doc (
|
||||
desc: "path demo"
|
||||
)
|
||||
@handler getPath1
|
||||
get / (string) returns (string)
|
||||
|
||||
@doc (
|
||||
desc: "path demo"
|
||||
)
|
||||
@handler getPath2
|
||||
get / (string) returns (string)
|
||||
}
|
||||
2
tools/goctl/pkg/parser/api/parser/testdata/duplicate_path_expression_different_prefix.api
vendored
Normal file
2
tools/goctl/pkg/parser/api/parser/testdata/duplicate_path_expression_different_prefix.api
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import "duplicate_path_expression_different_prefix__prefix_1.api"
|
||||
import "duplicate_path_expression_different_prefix__prefix_2.api"
|
||||
@@ -0,0 +1,16 @@
|
||||
syntax = "v1"
|
||||
|
||||
|
||||
@server (
|
||||
group: group2
|
||||
middleware: Path
|
||||
prefix: /v1/group2
|
||||
timeout: 100ms
|
||||
)
|
||||
service example {
|
||||
@doc (
|
||||
desc: "path demo"
|
||||
)
|
||||
@handler getPath2
|
||||
get / (string) returns (string)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
syntax = "v1"
|
||||
|
||||
@server (
|
||||
group: group1
|
||||
middleware: Path
|
||||
prefix: /v1/group1
|
||||
timeout: 100ms
|
||||
)
|
||||
service example {
|
||||
@doc (
|
||||
desc: "path demo"
|
||||
)
|
||||
@handler getPath1
|
||||
get / (string) returns (string)
|
||||
}
|
||||
Reference in New Issue
Block a user