diff --git a/classfile.go b/classfile.go index 9863dc9..0102f25 100644 --- a/classfile.go +++ b/classfile.go @@ -28,6 +28,7 @@ const ( GopPackage = true ) +// App is project class of YAP classfile (old version). type App struct { Engine } @@ -86,6 +87,9 @@ func (p *App) Static__2(pattern string, fs http.FileSystem, allowRedirect ...boo type AppType interface { InitYap(fs ...fs.FS) SetLAS(listenAndServe func(addr string, handler http.Handler) error) + Route(method, path string, handle func(ctx *Context)) + Handle(pattern string, f func(ctx *Context)) + Run(addr string, mws ...func(h http.Handler) http.Handler) error } var ( diff --git a/classfile_v2.go b/classfile_v2.go new file mode 100644 index 0000000..3409896 --- /dev/null +++ b/classfile_v2.go @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package yap + +import ( + "strings" +) + +// Handler is worker class of YAP classfile (v2). +type Handler struct { + Context +} + +func (p *Handler) Main(ctx *Context) { + p.Context = *ctx +} + +var ( + repl = strings.NewReplacer("_", "/", "#", ":") +) + +func parseClassfname(name string) (method, path string) { + pos := strings.IndexByte(name, '_') + if pos < 0 { + return name, "/" + } + return name[:pos], repl.Replace(name[pos:]) +} + +// AppV2 is project class of YAP classfile (v2). +type AppV2 struct { + App +} + +type iHandler interface { + Main(ctx *Context) + Classfname() string +} + +// Gopt_AppV2_Main is required by Go+ compiler as the entry of a YAP project. +func Gopt_AppV2_Main(app AppType, handlers ...iHandler) { + app.InitYap() + for _, h := range handlers { + switch method, path := parseClassfname(h.Classfname()); method { + case "handle": + app.Handle(path, h.Main) + default: + app.Route(strings.ToUpper(method), path, h.Main) + } + } + if me, ok := app.(interface{ MainEntry() }); ok { + me.MainEntry() + } else { + app.Run(":8080") + } +} diff --git a/demo/classfile2_blog/get_p_#id.yap b/demo/classfile2_blog/get_p_#id.yap new file mode 100644 index 0000000..3a4aa21 --- /dev/null +++ b/demo/classfile2_blog/get_p_#id.yap @@ -0,0 +1,3 @@ +yap "article", { + "id": param("id"), +} diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go new file mode 100644 index 0000000..84a4161 --- /dev/null +++ b/demo/classfile2_blog/gop_autogen.go @@ -0,0 +1,24 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const _ = true + +type get_p_id struct { + yap.Handler +} + +func main() { + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id)) +} +//line demo/classfile2_blog/get_p_#id.yap:1 +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_blog/get_p_#id.yap:1:1 + this.Yap__1("article", map[string]string{"id": this.Param("id")}) +} +func (this *get_p_id) Classfname() string { + return "get_p_#id" +} diff --git a/demo/classfile2_blog/yap/article_yap.html b/demo/classfile2_blog/yap/article_yap.html new file mode 100644 index 0000000..7985956 --- /dev/null +++ b/demo/classfile2_blog/yap/article_yap.html @@ -0,0 +1,8 @@ + +
+ + + +Article {{.id}} + + diff --git a/demo/classfile2_hello/get.yap b/demo/classfile2_hello/get.yap new file mode 100644 index 0000000..79f1936 --- /dev/null +++ b/demo/classfile2_hello/get.yap @@ -0,0 +1 @@ +html `Hello, Yap!` diff --git a/demo/classfile2_hello/get_p_#id.yap b/demo/classfile2_hello/get_p_#id.yap new file mode 100644 index 0000000..fbc76b9 --- /dev/null +++ b/demo/classfile2_hello/get_p_#id.yap @@ -0,0 +1,3 @@ +json { + "id": param("id"), +} diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go new file mode 100644 index 0000000..a05e04f --- /dev/null +++ b/demo/classfile2_hello/gop_autogen.go @@ -0,0 +1,36 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const _ = true + +type get struct { + yap.Handler +} +type get_p_id struct { + yap.Handler +} + +func main() { + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_id)) +} +//line demo/classfile2_hello/get.yap:1 +func (this *get) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_hello/get.yap:1:1 + this.Html__1(`Hello, Yap!`) +} +func (this *get) Classfname() string { + return "get" +} +//line demo/classfile2_hello/get_p_#id.yap:1 +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_hello/get_p_#id.yap:1:1 + this.Json__1(map[string]string{"id": this.Param("id")}) +} +func (this *get_p_id) Classfname() string { + return "get_p_#id" +} diff --git a/demo/classfile2_static/gop_autogen.go b/demo/classfile2_static/gop_autogen.go new file mode 100644 index 0000000..7120a97 --- /dev/null +++ b/demo/classfile2_static/gop_autogen.go @@ -0,0 +1,23 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const _ = true + +type AppV2 struct { + yap.AppV2 +} +//line demo/classfile2_static/main.yap:1 +func (this *AppV2) MainEntry() { +//line demo/classfile2_static/main.yap:1:1 + this.Static__0("/foo", this.FS("public")) +//line demo/classfile2_static/main.yap:2:1 + this.Static__0("/") +//line demo/classfile2_static/main.yap:4:1 + this.Run(":8080") +} +func main() { + yap.Gopt_AppV2_Main(new(AppV2)) +} diff --git a/demo/classfile_static/staticfile_yap.gox b/demo/classfile2_static/main.yap similarity index 100% rename from demo/classfile_static/staticfile_yap.gox rename to demo/classfile2_static/main.yap diff --git a/demo/classfile_static/yap/public/a.html b/demo/classfile2_static/yap/public/a.html similarity index 100% rename from demo/classfile_static/yap/public/a.html rename to demo/classfile2_static/yap/public/a.html diff --git a/demo/classfile_static/yap/public/b.txt b/demo/classfile2_static/yap/public/b.txt similarity index 100% rename from demo/classfile_static/yap/public/b.txt rename to demo/classfile2_static/yap/public/b.txt diff --git a/demo/classfile_static/yap/static/hello.txt b/demo/classfile2_static/yap/static/hello.txt similarity index 100% rename from demo/classfile_static/yap/static/hello.txt rename to demo/classfile2_static/yap/static/hello.txt diff --git a/demo/classfile_static/yap/static/index.html b/demo/classfile2_static/yap/static/index.html similarity index 100% rename from demo/classfile_static/yap/static/index.html rename to demo/classfile2_static/yap/static/index.html diff --git a/demo/classfile2_statichttp/gop_autogen.go b/demo/classfile2_statichttp/gop_autogen.go new file mode 100644 index 0000000..3a1517c --- /dev/null +++ b/demo/classfile2_statichttp/gop_autogen.go @@ -0,0 +1,24 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import ( + "github.com/goplus/yap" + "github.com/qiniu/x/http/fs" +) + +const _ = true + +type AppV2 struct { + yap.AppV2 +} +//line demo/classfile2_statichttp/main.yap:3 +func (this *AppV2) MainEntry() { +//line demo/classfile2_statichttp/main.yap:3:1 + this.Static__2("/", fs.Http("https://goplus.org"), false) +//line demo/classfile2_statichttp/main.yap:4:1 + this.Run(":8080") +} +func main() { + yap.Gopt_AppV2_Main(new(AppV2)) +} diff --git a/demo/classfile_statichttp/statichttp_yap.gox b/demo/classfile2_statichttp/main.yap similarity index 87% rename from demo/classfile_statichttp/statichttp_yap.gox rename to demo/classfile2_statichttp/main.yap index deeb80d..df0ba1c 100644 --- a/demo/classfile_statichttp/statichttp_yap.gox +++ b/demo/classfile2_statichttp/main.yap @@ -1,4 +1,4 @@ import "github.com/qiniu/x/http/fs" static "/", fs.http("https://goplus.org"), false -run ":8888" +run ":8080" diff --git a/demo/classfile_hello/gop_autogen.go b/demo/classfile_hello/gop_autogen.go index 5137d51..aa7f026 100644 --- a/demo/classfile_hello/gop_autogen.go +++ b/demo/classfile_hello/gop_autogen.go @@ -6,24 +6,24 @@ import "github.com/goplus/yap" const _ = true -type hello struct { - yap.App +type AppV2 struct { + yap.AppV2 } -//line demo/classfile_hello/hello_yap.gox:1 -func (this *hello) MainEntry() { -//line demo/classfile_hello/hello_yap.gox:1:1 +//line demo/classfile_hello/main.yap:1 +func (this *AppV2) MainEntry() { +//line demo/classfile_hello/main.yap:1:1 this.Get("/p/:id", func(ctx *yap.Context) { -//line demo/classfile_hello/hello_yap.gox:2:1 +//line demo/classfile_hello/main.yap:2:1 ctx.Json__1(map[string]string{"id": ctx.Param("id")}) }) -//line demo/classfile_hello/hello_yap.gox:6:1 +//line demo/classfile_hello/main.yap:6:1 this.Handle("/", func(ctx *yap.Context) { -//line demo/classfile_hello/hello_yap.gox:7:1 +//line demo/classfile_hello/main.yap:7:1 ctx.Html__1(`Hello, Yap!`) }) -//line demo/classfile_hello/hello_yap.gox:10:1 +//line demo/classfile_hello/main.yap:10:1 this.Run(":8080") } func main() { - yap.Gopt_App_Main(new(hello)) + yap.Gopt_AppV2_Main(new(AppV2)) } diff --git a/demo/classfile_hello/hello_yap.gox b/demo/classfile_hello/main.yap similarity index 100% rename from demo/classfile_hello/hello_yap.gox rename to demo/classfile_hello/main.yap diff --git a/demo/classfile_static/gop_autogen.go b/demo/classfile_static/gop_autogen.go deleted file mode 100644 index f85061f..0000000 --- a/demo/classfile_static/gop_autogen.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by gop (Go+); DO NOT EDIT. - -package main - -import "github.com/goplus/yap" - -const _ = true - -type staticfile struct { - yap.App -} -//line demo/classfile_static/staticfile_yap.gox:1 -func (this *staticfile) MainEntry() { -//line demo/classfile_static/staticfile_yap.gox:1:1 - this.Static__0("/foo", this.FS("public")) -//line demo/classfile_static/staticfile_yap.gox:2:1 - this.Static__0("/") -//line demo/classfile_static/staticfile_yap.gox:4:1 - this.Run(":8080") -} -func main() { - yap.Gopt_App_Main(new(staticfile)) -} diff --git a/demo/classfile_statichttp/gop_autogen.go b/demo/classfile_statichttp/gop_autogen.go deleted file mode 100644 index 8525207..0000000 --- a/demo/classfile_statichttp/gop_autogen.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by gop (Go+); DO NOT EDIT. - -package main - -import ( - "github.com/goplus/yap" - "github.com/qiniu/x/http/fs" -) - -const _ = true - -type statichttp struct { - yap.App -} -//line demo/classfile_statichttp/statichttp_yap.gox:3 -func (this *statichttp) MainEntry() { -//line demo/classfile_statichttp/statichttp_yap.gox:3:1 - this.Static__2("/", fs.Http("https://goplus.org"), false) -//line demo/classfile_statichttp/statichttp_yap.gox:4:1 - this.Run(":8888") -} -func main() { - yap.Gopt_App_Main(new(statichttp)) -} diff --git a/gop.mod b/gop.mod index ce75052..e656abd 100644 --- a/gop.mod +++ b/gop.mod @@ -1,5 +1,9 @@ gop 1.2 +project .yap AppV2 github.com/goplus/yap + +class .yap Handler + project _yap.gox App github.com/goplus/yap project _yapt.gox App github.com/goplus/yap/ytest github.com/goplus/yap/test diff --git a/router.go b/router.go index 89605d0..5345196 100644 --- a/router.go +++ b/router.go @@ -82,46 +82,46 @@ type router struct { HandleOPTIONS bool } -func (r *router) init() { - r.RedirectTrailingSlash = true - r.RedirectFixedPath = true - r.HandleMethodNotAllowed = true - r.HandleOPTIONS = true +func (p *router) init() { + p.RedirectTrailingSlash = true + p.RedirectFixedPath = true + p.HandleMethodNotAllowed = true + p.HandleOPTIONS = true } // GET is a shortcut for router.Route(http.MethodGet, path, handle) -func (r *router) GET(path string, handle func(ctx *Context)) { - r.Route(http.MethodGet, path, handle) +func (p *router) GET(path string, handle func(ctx *Context)) { + p.Route(http.MethodGet, path, handle) } // HEAD is a shortcut for router.Route(http.MethodHead, path, handle) -func (r *router) HEAD(path string, handle func(ctx *Context)) { - r.Route(http.MethodHead, path, handle) +func (p *router) HEAD(path string, handle func(ctx *Context)) { + p.Route(http.MethodHead, path, handle) } // OPTIONS is a shortcut for router.Route(http.MethodOptions, path, handle) -func (r *router) OPTIONS(path string, handle func(ctx *Context)) { - r.Route(http.MethodOptions, path, handle) +func (p *router) OPTIONS(path string, handle func(ctx *Context)) { + p.Route(http.MethodOptions, path, handle) } // POST is a shortcut for router.Route(http.MethodPost, path, handle) -func (r *router) POST(path string, handle func(ctx *Context)) { - r.Route(http.MethodPost, path, handle) +func (p *router) POST(path string, handle func(ctx *Context)) { + p.Route(http.MethodPost, path, handle) } // PUT is a shortcut for router.Route(http.MethodPut, path, handle) -func (r *router) PUT(path string, handle func(ctx *Context)) { - r.Route(http.MethodPut, path, handle) +func (p *router) PUT(path string, handle func(ctx *Context)) { + p.Route(http.MethodPut, path, handle) } // PATCH is a shortcut for router.Route(http.MethodPatch, path, handle) -func (r *router) PATCH(path string, handle func(ctx *Context)) { - r.Route(http.MethodPatch, path, handle) +func (p *router) PATCH(path string, handle func(ctx *Context)) { + p.Route(http.MethodPatch, path, handle) } // DELETE is a shortcut for router.Route(http.MethodDelete, path, handle) -func (r *router) DELETE(path string, handle func(ctx *Context)) { - r.Route(http.MethodDelete, path, handle) +func (p *router) DELETE(path string, handle func(ctx *Context)) { + p.Route(http.MethodDelete, path, handle) } // Route registers a new request handle with the given path and method. @@ -132,7 +132,7 @@ func (r *router) DELETE(path string, handle func(ctx *Context)) { // This function is intended for bulk loading and to allow the usage of less // frequently used, non-standardized or custom methods (e.g. for internal // communication with a proxy). -func (r *router) Route(method, path string, handle func(ctx *Context)) { +func (p *router) Route(method, path string, handle func(ctx *Context)) { if method == "" { panic("method must not be empty") } @@ -143,34 +143,34 @@ func (r *router) Route(method, path string, handle func(ctx *Context)) { panic("handle must not be nil") } - if r.trees == nil { - r.trees = make(map[string]*node) + if p.trees == nil { + p.trees = make(map[string]*node) } - root := r.trees[method] + root := p.trees[method] if root == nil { root = new(node) - r.trees[method] = root + p.trees[method] = root - r.globalAllowed = r.allowed("*", "") + p.globalAllowed = p.allowed("*", "") } root.addRoute(path, handle) } -func (r *router) recv(w http.ResponseWriter, req *http.Request) { +func (p *router) recv(w http.ResponseWriter, req *http.Request) { if rcv := recover(); rcv != nil { - r.PanicHandler(w, req, rcv) + p.PanicHandler(w, req, rcv) } } -func (r *router) allowed(path, reqMethod string) (allow string) { +func (p *router) allowed(path, reqMethod string) (allow string) { allowed := make([]string, 0, 9) if path == "*" { // server-wide // empty method is used for internal calls to refresh the cache if reqMethod == "" { - for method := range r.trees { + for method := range p.trees { if method == http.MethodOptions { continue } @@ -178,16 +178,16 @@ func (r *router) allowed(path, reqMethod string) (allow string) { allowed = append(allowed, method) } } else { - return r.globalAllowed + return p.globalAllowed } } else { // specific path - for method := range r.trees { + for method := range p.trees { // Skip the requested method - we already tried this one if method == reqMethod || method == http.MethodOptions { continue } - handle, _ := r.trees[method].getValue(path, nil) + handle, _ := p.trees[method].getValue(path, nil) if handle != nil { // Route request method to list of allowed methods allowed = append(allowed, method) @@ -215,13 +215,13 @@ func (r *router) allowed(path, reqMethod string) (allow string) { return allow } -func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) { - if r.PanicHandler != nil { - defer r.recv(w, req) +func (p *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) { + if p.PanicHandler != nil { + defer p.recv(w, req) } path := req.URL.Path - root := r.trees[req.Method] + root := p.trees[req.Method] if root != nil { ctx := e.NewContext(w, req) if handle, tsr := root.getValue(path, ctx); handle != nil { @@ -235,7 +235,7 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) code = http.StatusPermanentRedirect } - if tsr && r.RedirectTrailingSlash { + if tsr && p.RedirectTrailingSlash { if len(path) > 1 && path[len(path)-1] == '/' { req.URL.Path = path[:len(path)-1] } else { @@ -246,10 +246,10 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) } // Try to fix the request path - if r.RedirectFixedPath { + if p.RedirectFixedPath { fixedPath, found := root.findCaseInsensitivePath( url.CleanPath(path), - r.RedirectTrailingSlash, + p.RedirectTrailingSlash, ) if found { req.URL.Path = fixedPath @@ -260,20 +260,20 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) } } - if req.Method == http.MethodOptions && r.HandleOPTIONS { + if req.Method == http.MethodOptions && p.HandleOPTIONS { // Route OPTIONS requests - if allow := r.allowed(path, http.MethodOptions); allow != "" { + if allow := p.allowed(path, http.MethodOptions); allow != "" { w.Header().Set("Allow", allow) - if r.GlobalOPTIONS != nil { - r.GlobalOPTIONS.ServeHTTP(w, req) + if p.GlobalOPTIONS != nil { + p.GlobalOPTIONS.ServeHTTP(w, req) } return } - } else if r.HandleMethodNotAllowed { // Route 405 - if allow := r.allowed(path, req.Method); allow != "" { + } else if p.HandleMethodNotAllowed { // Route 405 + if allow := p.allowed(path, req.Method); allow != "" { w.Header().Set("Allow", allow) - if r.MethodNotAllowed != nil { - r.MethodNotAllowed.ServeHTTP(w, req) + if p.MethodNotAllowed != nil { + p.MethodNotAllowed.ServeHTTP(w, req) } else { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), diff --git a/ydb/demo/foo/gop_autogen.go b/ydb/demo/foo/gop_autogen.go index 62149a7..211436e 100644 --- a/ydb/demo/foo/gop_autogen.go +++ b/ydb/demo/foo/gop_autogen.go @@ -224,6 +224,9 @@ func (this *articles) Main() { //line ydb/demo/foo/articles_ydb.gox:135:1 this.Ret(test.Set__2(doc2.ArticleEntry, doc3.ArticleEntry)) } +func (this *articles) Classfname() string { + return "articles" +} var ErrNoEmailAndTel = errors.New("no email and telephone") var rnd = rand.New(rand.NewSource(time.Now().UnixMicro())) @@ -251,8 +254,7 @@ func Diff(new []string, old []string) (add []string, del []string) { //line ydb/demo/foo/foo.gop:38:1 // Info calls Output to print to the standard logger. // Arguments are handled in the manner of fmt.Println. -func Info(args ...interface { -}) { +func Info(args ...interface{}) { //line ydb/demo/foo/foo.gop:41:1 log.Println(args...) } @@ -321,3 +323,6 @@ func (this *users) Main() { //line ydb/demo/foo/users_ydb.gox:58:1 this.Ret(true) } +func (this *users) Classfname() string { + return "users" +} diff --git a/ytest/demo/basic/gop_autogen_test.go b/ytest/demo/basic/gop_autogen_test.go index ad1bb20..4dfb8b0 100644 --- a/ytest/demo/basic/gop_autogen_test.go +++ b/ytest/demo/basic/gop_autogen_test.go @@ -4,6 +4,7 @@ package main import ( "github.com/goplus/yap/ytest" + "github.com/qiniu/x/stringutil" "testing" ) @@ -23,13 +24,16 @@ func (this *case_foo) Main() { //line ytest/demo/basic/foo_ytest.gox:6:1 id := "123" //line ytest/demo/basic/foo_ytest.gox:7:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/basic/foo_ytest.gox:8:1 this.RetWith(200) //line ytest/demo/basic/foo_ytest.gox:9:1 this.Json(map[string]string{"id": id}) }) } +func (this *case_foo) Classfname() string { + return "foo" +} func Test_foo(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_foo), t) } diff --git a/ytest/demo/foo/gop_autogen_test.go b/ytest/demo/foo/gop_autogen_test.go index fd170c6..debbd6c 100644 --- a/ytest/demo/foo/gop_autogen_test.go +++ b/ytest/demo/foo/gop_autogen_test.go @@ -5,6 +5,7 @@ package main import ( "github.com/goplus/yap/test" "github.com/goplus/yap/ytest" + "github.com/qiniu/x/stringutil" "testing" ) @@ -23,7 +24,7 @@ func (this *case_bar) Main() { //line ytest/demo/foo/bar_ytest.gox:4:1 id := "123" //line ytest/demo/foo/bar_ytest.gox:5:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/foo/bar_ytest.gox:6:1 this.Send() //line ytest/demo/foo/bar_ytest.gox:7:1 @@ -32,6 +33,9 @@ func (this *case_bar) Main() { this.Json(map[string]string{"id": id}) }) } +func (this *case_bar) Classfname() string { + return "bar" +} //line ytest/demo/foo/foo_ytest.gox:1 func (this *case_foo) Main() { //line ytest/demo/foo/foo_ytest.gox:1:1 @@ -41,13 +45,16 @@ func (this *case_foo) Main() { //line ytest/demo/foo/foo_ytest.gox:4:1 id := "123" //line ytest/demo/foo/foo_ytest.gox:5:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/foo/foo_ytest.gox:6:1 this.RetWith(200) //line ytest/demo/foo/foo_ytest.gox:7:1 this.Json(map[string]string{"id": id}) }) } +func (this *case_foo) Classfname() string { + return "foo" +} func Test_bar(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_bar), t) } diff --git a/ytest/demo/jwtdemo/gop_autogen_test.go b/ytest/demo/jwtdemo/gop_autogen_test.go index 7f47fec..f2766ca 100644 --- a/ytest/demo/jwtdemo/gop_autogen_test.go +++ b/ytest/demo/jwtdemo/gop_autogen_test.go @@ -5,6 +5,7 @@ package main import ( "github.com/goplus/yap/ytest" "github.com/goplus/yap/ytest/auth/jwt" + "github.com/qiniu/x/stringutil" "testing" "time" ) @@ -23,7 +24,7 @@ func (this *case_jwtdemo) Main() { //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:12:1 id := "123" //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:13:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:14:1 this.Auth(testuser) //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:15:1 @@ -32,6 +33,9 @@ func (this *case_jwtdemo) Main() { this.Json(map[string]string{"id": id}) }) } +func (this *case_jwtdemo) Classfname() string { + return "jwtdemo" +} func Test_jwtdemo(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_jwtdemo), t) }