chore: Embed unit test data (#1812)

* Embed unit test data

* Add testdata

Co-authored-by: anqiansong <anqiansong@bytedance.com>
master
anqiansong 3 years ago committed by GitHub
parent 14bf2f33f7
commit 16c61c6657
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1
.gitignore vendored

@ -17,7 +17,6 @@
# for test purpose # for test purpose
**/adhoc **/adhoc
**/testdata
# gitlab ci # gitlab ci
.cache .cache

@ -1,6 +1,7 @@
package gogen package gogen
import ( import (
_ "embed"
goformat "go/format" goformat "go/format"
"io/ioutil" "io/ioutil"
"os" "os"
@ -10,314 +11,45 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/tools/goctl/api/parser" "github.com/zeromicro/go-zero/tools/goctl/api/parser"
"github.com/zeromicro/go-zero/tools/goctl/rpc/execx"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
) )
const testApiTemplate = ` var (
info( //go:embed testdata/test_api_template.api
title: doc title testApiTemplate string
desc: "> //go:embed testdata/test_multi_service_template.api
doc description first part, testMultiServiceTemplate string
doc description second part<" //go:embed testdata/ap_ino_info.api
version: 1.0 apiNoInfo string
//go:embed testdata/invalid_api_file.api
invalidApiFile string
//go:embed testdata/anonymous_annotation.api
anonymousAnnotation string
//go:embed testdata/api_has_middleware.api
apiHasMiddleware string
//go:embed testdata/api_jwt.api
apiJwt string
//go:embed testdata/api_jwt_with_middleware.api
apiJwtWithMiddleware string
//go:embed testdata/api_has_no_request.api
apiHasNoRequest string
//go:embed testdata/api_route_test.api
apiRouteTest string
//go:embed testdata/has_comment_api_test.api
hasCommentApiTest string
//go:embed testdata/has_inline_no_exist_test.api
hasInlineNoExistTest string
//go:embed testdata/import_api.api
importApi string
//go:embed testdata/has_import_api.api
hasImportApi string
//go:embed testdata/no_struct_tag_api.api
noStructTagApi string
//go:embed testdata/nest_type_api.api
nestTypeApi string
) )
// TODO: test
// {
type Request struct { // TODO: test
// TODO
Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` // }
} // TODO: test
// TODO: test
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
@server(
// C0
group: greet/s1
)
// C1
service A-api {
// C2
@server( // C3
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response) // hello
// C4
@handler NoResponseHandler // C5
get /greet/get(Request)
}
`
const testMultiServiceTemplate = `
info(
title: doc title
desc: doc description first part
version: 1.0
)
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
service A-api {
@server(
handler: NoResponseHandler
)
get /greet/get(Request)
}
`
const apiNoInfo = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
`
const invalidApiFile = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
service A-api
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
`
const anonymousAnnotation = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
`
const apiHasMiddleware = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
@server(
middleware: TokenValidate
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
`
const apiJwt = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
@server(
jwt: Auth
signature: true
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
`
const apiJwtWithMiddleware = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
@server(
jwt: Auth
jwtTransition: Trans
middleware: TokenValidate
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
`
const apiHasNoRequest = `
service A-api {
@handler GreetHandler
post /greet/ping ()
}
`
const apiRouteTest = `
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + `
}
service A-api {
@handler NormalHandler
get /greet/from/:name(Request) returns (Response)
@handler NoResponseHandler
get /greet/from/:sex(Request)
@handler NoRequestHandler
get /greet/from/request returns (Response)
@handler NoRequestNoResponseHandler
get /greet/from
}
`
const hasCommentApiTest = `
type Inline struct {
}
type Request struct {
Inline
Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` // name in path
}
type Response struct {
Message string ` + "`" + `json:"msg"` + "`" + ` // message
}
service A-api {
@doc ("helloworld")
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
`
const hasInlineNoExistTest = `
type Request struct {
Inline
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + ` // message
}
service A-api {
@doc ("helloworld")
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
`
const importApi = `
type ImportData struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
`
const hasImportApi = `
import "importApi.api"
type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type Response struct {
Message string ` + "`" + `json:"message"` + "`" + ` // message
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
`
const noStructTagApi = `
type Request {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
}
type XXX {}
type (
Response {
Message string ` + "`" + `json:"message"` + "`" + `
}
A {}
B struct {}
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
`
const nestTypeApi = `
type Request {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
XXX struct {
}
}
service A-api {
@handler GreetHandler
get /greet/from/:name(Request)
}
`
func TestParser(t *testing.T) { func TestParser(t *testing.T) {
filename := "greet.api" filename := "greet.api"
err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm) err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm)
@ -537,8 +269,15 @@ func validate(t *testing.T, api string) {
} }
func validateWithCamel(t *testing.T, api, camel string) { func validateWithCamel(t *testing.T, api, camel string) {
dir := t.TempDir() dir := "workspace"
err := DoGenProject(api, dir, camel) defer func() {
os.RemoveAll(dir)
}()
err := pathx.MkdirIfNotExist(dir)
assert.Nil(t, err)
err = initMod(dir)
assert.Nil(t, err)
err = DoGenProject(api, dir, camel)
assert.Nil(t, err) assert.Nil(t, err)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if strings.HasSuffix(path, ".go") { if strings.HasSuffix(path, ".go") {
@ -550,6 +289,11 @@ func validateWithCamel(t *testing.T, api, camel string) {
}) })
} }
func initMod(mod string) error {
_, err := execx.Run("go mod init "+mod, mod)
return err
}
func validateCode(code string) error { func validateCode(code string) error {
_, err := goformat.Source([]byte(code)) _, err := goformat.Source([]byte(code))
return err return err

@ -0,0 +1,12 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,14 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,15 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
@server(
middleware: TokenValidate
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,4 @@
service A-api {
@handler GreetHandler
post /greet/ping ()
}

@ -0,0 +1,16 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
@server(
jwt: Auth
signature: true
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,17 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
@server(
jwt: Auth
jwtTransition: Trans
middleware: TokenValidate
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,16 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
service A-api {
@handler NormalHandler
get /greet/from/:name(Request) returns (Response)
@handler NoResponseHandler
get /greet/from/:sex(Request)
@handler NoRequestHandler
get /greet/from/request returns (Response)
@handler NoRequestNoResponseHandler
get /greet/from
}

@ -0,0 +1,20 @@
type Inline struct {
}
type Request struct {
Inline
Name string `path:"name,options=you|me"` // name in path
}
type Response struct {
Message string `json:"msg"` // message
}
service A-api {
@doc ("helloworld")
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,16 @@
import "importApi.api"
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"` // message
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,16 @@
type Request struct {
Inline
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"` // message
}
service A-api {
@doc ("helloworld")
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,3 @@
type ImportData struct {
Name string `path:"name,options=you|me"`
}

@ -0,0 +1,14 @@
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
service A-api
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,10 @@
type Request {
Name string `path:"name,options=you|me"`
XXX struct {
}
}
service A-api {
@handler GreetHandler
get /greet/from/:name(Request)
}

@ -0,0 +1,20 @@
type Request {
Name string `path:"name,options=you|me"`
}
type XXX {}
type (
Response {
Message string `json:"message"`
}
A {}
B struct {}
)
service A-api {
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}

@ -0,0 +1,36 @@
info(
title: doc title
desc: ">
doc description first part,
doc description second part<"
version: 1.0
)
// TODO: test
// {
type Request struct { // TODO: test
// TODO
Name string `path:"name,options=you|me"` // }
} // TODO: test
// TODO: test
type Response struct {
Message string `json:"message"`
}
@server(
// C0
group: greet/s1
)
// C1
service A-api {
// C2
@server( // C3
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response) // hello
// C4
@handler NoResponseHandler // C5
get /greet/get(Request)
}

@ -0,0 +1,27 @@
info(
title: doc title
desc: doc description first part
version: 1.0
)
type Request struct {
Name string `path:"name,options=you|me"`
}
type Response struct {
Message string `json:"message"`
}
service A-api {
@server(
handler: GreetHandler
)
get /greet/from/:name(Request) returns (Response)
}
service A-api {
@server(
handler: NoResponseHandler
)
get /greet/get(Request)
}

@ -1,7 +1,7 @@
package test package test
import ( import (
"io/ioutil" _ "embed"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -9,16 +9,17 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api" "github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
) )
//go:embed apis/test.api
var testApi string
var parser = ast.NewParser(ast.WithParserPrefix("test.api"), ast.WithParserDebug()) var parser = ast.NewParser(ast.WithParserPrefix("test.api"), ast.WithParserDebug())
func TestApi(t *testing.T) { func TestApi(t *testing.T) {
fn := func(p *api.ApiParserParser, visitor *ast.ApiVisitor) interface{} { fn := func(p *api.ApiParserParser, visitor *ast.ApiVisitor) interface{} {
return p.Api().Accept(visitor) return p.Api().Accept(visitor)
} }
content, err := ioutil.ReadFile("./apis/test.api")
assert.Nil(t, err)
v, err := parser.Accept(fn, string(content)) v, err := parser.Accept(fn, testApi)
assert.Nil(t, err) assert.Nil(t, err)
api := v.(*ast.Api) api := v.(*ast.Api)
body := &ast.Body{ body := &ast.Body{

@ -1,13 +1,15 @@
package parser package parser
import ( import (
_ "embed"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/tools/goctl/api/spec" "github.com/zeromicro/go-zero/tools/goctl/api/spec"
) )
var testApi = "// syntax doc\nsyntax = \"v1\" // syntax comment\n\n// type doc\ntype Request {\n\tName string `path:\"name,options=you|me\"`\n}\n\ntype Response {\n\tMessage string `json:\"message\"`\n}\n\n// service doc\nservice greet-api {\n\t// handler doc\n\t@handler GreetHandler // handler comment\n\tget /from/:name(Request) returns (Response);\n}" //go:embed testdata/test.api
var testApi string
func TestParseContent(t *testing.T) { func TestParseContent(t *testing.T) {
sp, err := ParseContent(testApi) sp, err := ParseContent(testApi)

@ -0,0 +1,18 @@
// syntax doc
syntax = "v1" // syntax comment
// type doc
type Request {
Name string `path:"name,options=you|me"`
}
type Response {
Message string `json:"message"`
}
// service doc
service greet-api {
// handler doc
@handler GreetHandler // handler comment
get /from/:name(Request) returns (Response);
}

@ -1,6 +1,7 @@
package command package command
import ( import (
_ "embed"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -13,7 +14,8 @@ import (
) )
var ( var (
sql = "-- 用户表 --\nCREATE TABLE `user` (\n `id` bigint(10) NOT NULL AUTO_INCREMENT,\n `name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户名称',\n `password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户密码',\n `mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',\n `gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公开',\n `nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `name_index` (`name`),\n UNIQUE KEY `mobile_index` (`mobile`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;\n\n" //go:embed testdata/user.sql
sql string
cfg = &config.Config{ cfg = &config.Config{
NamingFormat: "gozero", NamingFormat: "gozero",
} }

@ -0,0 +1,16 @@
-- 用户表 --
CREATE TABLE `user`
(
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户名称',
`password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户密码',
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
`gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公开',
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `name_index` (`name`),
UNIQUE KEY `mobile_index` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

@ -2,6 +2,7 @@ package gen
import ( import (
"database/sql" "database/sql"
_ "embed"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
@ -20,7 +21,8 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/util/pathx" "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
) )
var source = "CREATE TABLE `test_user` (\n `id` bigint NOT NULL AUTO_INCREMENT,\n `mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL,\n `class` bigint NOT NULL,\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `mobile_unique` (`mobile`),\n UNIQUE KEY `class_name_unique` (`class`,`name`),\n KEY `create_index` (`create_time`),\n KEY `name_index` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;" //go:embed testdata/user.sql
var source string
func TestCacheModel(t *testing.T) { func TestCacheModel(t *testing.T) {
logx.Disable() logx.Disable()

@ -0,0 +1,14 @@
CREATE TABLE `test_user`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL,
`class` bigint NOT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `mobile_unique` (`mobile`),
UNIQUE KEY `class_name_unique` (`class`,`name`),
KEY `create_index` (`create_time`),
KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

@ -1,6 +1,7 @@
package parser package parser
import ( import (
_ "embed"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"testing" "testing"
@ -30,9 +31,12 @@ func TestParseSelect(t *testing.T) {
assert.Equal(t, 0, len(tables)) assert.Equal(t, 0, len(tables))
} }
//go:embed testdata/user.sql
var user string
func TestParseCreateTable(t *testing.T) { func TestParseCreateTable(t *testing.T) {
sqlFile := filepath.Join(pathx.MustTempDir(), "tmp.sql") sqlFile := filepath.Join(pathx.MustTempDir(), "tmp.sql")
err := ioutil.WriteFile(sqlFile, []byte("CREATE TABLE `test_user` (\n `id` bigint NOT NULL AUTO_INCREMENT,\n `mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL comment '手\\t机 号',\n `class` bigint NOT NULL comment '班级',\n `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL comment '姓\n 名',\n `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP comment '创建\\r时间',\n `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (`id`),\n UNIQUE KEY `mobile_unique` (`mobile`),\n UNIQUE KEY `class_name_unique` (`class`,`name`),\n KEY `create_index` (`create_time`),\n KEY `name_index` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"), 0o777) err := ioutil.WriteFile(sqlFile, []byte(user), 0o777)
assert.Nil(t, err) assert.Nil(t, err)
tables, err := Parse(sqlFile, "go_zero") tables, err := Parse(sqlFile, "go_zero")

@ -0,0 +1,15 @@
CREATE TABLE `test_user`
(
`id` bigint NOT NULL AUTO_INCREMENT,
`mobile` varchar(255) COLLATE utf8mb4_bin NOT NULL comment '手\t机 号',
`class` bigint NOT NULL comment '班级',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL comment '
',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP comment '创建\r时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `mobile_unique` (`mobile`),
UNIQUE KEY `class_name_unique` (`class`,`name`),
KEY `create_index` (`create_time`),
KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
Loading…
Cancel
Save