From f68b74375a70a625dcde927562b705e64132e538 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 30 Jan 2024 18:26:23 +0800 Subject: [PATCH 1/2] yaptest: RunMock/RunTestServer; demo/basic --- classfile.go | 8 +-- go.mod | 2 +- go.sum | 4 +- yap.go | 14 +++-- ytest/case.go | 2 +- ytest/classfile.go | 16 ++++++ ytest/demo/_example/gop_autogen_test.go | 70 ++++++++++++------------- ytest/demo/basic/foo.gox | 13 +++++ ytest/demo/basic/foo_ytest.gox | 12 +++++ ytest/demo/basic/gop_autogen.go | 21 ++++++++ ytest/demo/basic/gop_autogen_test.go | 33 ++++++++++++ ytest/demo/mixyap/_main.yunit.gox | 5 -- 12 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 ytest/demo/basic/foo.gox create mode 100644 ytest/demo/basic/foo_ytest.gox create mode 100644 ytest/demo/basic/gop_autogen.go create mode 100644 ytest/demo/basic/gop_autogen_test.go delete mode 100644 ytest/demo/mixyap/_main.yunit.gox diff --git a/classfile.go b/classfile.go index a2bc5cd..4e21af6 100644 --- a/classfile.go +++ b/classfile.go @@ -36,8 +36,8 @@ func (p *App) initApp() { p.Engine = New() } -// InitYapApp initialize a YAP application. -func (p *App) InitYapApp(fs ...fs.FS) { +// Init initialize a YAP application. +func (p *App) Init(fs ...fs.FS) { if p.Engine == nil { p.initApp() } @@ -99,7 +99,9 @@ func (p App) Static__2(pattern string, fs http.FileSystem, allowRedirect ...bool // Gopt_App_Main is required by Go+ compiler as the entry of a YAP project. func Gopt_App_Main(app interface{ initApp() }) { app.initApp() - app.(interface{ MainEntry() }).MainEntry() + if me, ok := app.(interface{ MainEntry() }); ok { + me.MainEntry() + } } const ( diff --git a/go.mod b/go.mod index 104a35c..4461382 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/goplus/yap go 1.18 -require github.com/qiniu/x v1.13.2 +require github.com/qiniu/x v1.13.3-0.20240129201727-4013f184c5c7 diff --git a/go.sum b/go.sum index c49d87a..f2f7a1a 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/qiniu/x v1.13.2 h1:mgWOfB9Rpk6AEtlBoObZVxH+b2FHSntYrxc4KX5Ta98= -github.com/qiniu/x v1.13.2/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E= +github.com/qiniu/x v1.13.3-0.20240129201727-4013f184c5c7 h1:rzpGloMVgWexXti9yRXMH8aAdjNy8rZrlAQdKvzZeMg= +github.com/qiniu/x v1.13.3-0.20240129201727-4013f184c5c7/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E= diff --git a/yap.go b/yap.go index 5453291..ce8f4f3 100644 --- a/yap.go +++ b/yap.go @@ -118,14 +118,20 @@ func (p *Engine) Handle(pattern string, f func(ctx *Context)) { }) } -// Run listens on the TCP network address addr and then calls -// Serve with handler to handle requests on incoming connections. -// Accepted connections are configured to enable TCP keep-alives. -func (p *Engine) Run(addr string, mws ...func(h http.Handler) http.Handler) error { +// Handler returns the main entry that responds to HTTP requests. +func (p *Engine) Handler(mws ...func(h http.Handler) http.Handler) http.Handler { h := http.Handler(p) for _, mw := range mws { h = mw(h) } + return h +} + +// Run listens on the TCP network address addr and then calls +// Serve with handler to handle requests on incoming connections. +// Accepted connections are configured to enable TCP keep-alives. +func (p *Engine) Run(addr string, mws ...func(h http.Handler) http.Handler) error { + h := p.Handler(mws...) return http.ListenAndServe(addr, h) } diff --git a/ytest/case.go b/ytest/case.go index 1a84dc7..12101ab 100644 --- a/ytest/case.go +++ b/ytest/case.go @@ -149,7 +149,7 @@ type Case struct { DefaultHeader http.Header } -func New() *Case { +func NewCase() *Case { return &Case{} } diff --git a/ytest/classfile.go b/ytest/classfile.go index c6eda97..a952226 100644 --- a/ytest/classfile.go +++ b/ytest/classfile.go @@ -20,9 +20,12 @@ import ( "io" "log" "net/http" + "net/http/httptest" "os" "strings" "testing" + + "github.com/qiniu/x/mockhttp" ) const ( @@ -42,6 +45,19 @@ func (p *App) initApp() *App { return p } +// RunMock runs a HTTP server by mockhttp. +func (p *App) RunMock(host string, h http.Handler) { + tr := mockhttp.NewTransport() + p.transport = tr + tr.ListenAndServe(host, h) +} + +// RunTestServer runs a HTTP server by httptest.Server. +func (p *App) RunTestServer(host string, h http.Handler) { + svr := httptest.NewServer(h) + p.Host(host, svr.URL) +} + // Gopt_App_TestMain is required by Go+ compiler as the TestMain entry of a YAP testing project. func Gopt_App_TestMain(app interface{ initApp() *App }, m *testing.M) { app.initApp() diff --git a/ytest/demo/_example/gop_autogen_test.go b/ytest/demo/_example/gop_autogen_test.go index d85123d..b386b07 100644 --- a/ytest/demo/_example/gop_autogen_test.go +++ b/ytest/demo/_example/gop_autogen_test.go @@ -9,78 +9,78 @@ import ( type case_example struct { ytest.Case } -//line ytest/demo/example/example_ytest.gox:1 +//line ytest/demo/_example/example_ytest.gox:1 func (this *case_example) Main() { -//line ytest/demo/example/example_ytest.gox:1:1 +//line ytest/demo/_example/example_ytest.gox:1:1 this.Host("https://example.com", "http://localhost:8080") -//line ytest/demo/example/example_ytest.gox:2:1 +//line ytest/demo/_example/example_ytest.gox:2:1 testauth := ytest.Oauth2("...") -//line ytest/demo/example/example_ytest.gox:4:1 +//line ytest/demo/_example/example_ytest.gox:4:1 this.DefaultHeader.Set("User-Agent", "yaptest/0.7") -//line ytest/demo/example/example_ytest.gox:6:1 +//line ytest/demo/_example/example_ytest.gox:6:1 this.Run("urlWithVar", func() { -//line ytest/demo/example/example_ytest.gox:7:1 +//line ytest/demo/_example/example_ytest.gox:7:1 id := "123" -//line ytest/demo/example/example_ytest.gox:8:1 +//line ytest/demo/_example/example_ytest.gox:8:1 this.Get("https://example.com/p/" + id) -//line ytest/demo/example/example_ytest.gox:9:1 +//line ytest/demo/_example/example_ytest.gox:9:1 this.Send() -//line ytest/demo/example/example_ytest.gox:10:1 +//line ytest/demo/_example/example_ytest.gox:10:1 fmt.Println("code:", this.Resp().Code()) -//line ytest/demo/example/example_ytest.gox:11:1 +//line ytest/demo/_example/example_ytest.gox:11:1 fmt.Println("body:", this.Resp().Body()) }) -//line ytest/demo/example/example_ytest.gox:14:1 +//line ytest/demo/_example/example_ytest.gox:14:1 this.Run("matchWithVar", func() { -//line ytest/demo/example/example_ytest.gox:15:1 +//line ytest/demo/_example/example_ytest.gox:15:1 code := ytest.Gopx_Var_Cast__0[int]() -//line ytest/demo/example/example_ytest.gox:16:1 +//line ytest/demo/_example/example_ytest.gox:16:1 id := "123" -//line ytest/demo/example/example_ytest.gox:17:1 +//line ytest/demo/_example/example_ytest.gox:17:1 this.Get("https://example.com/p/" + id) -//line ytest/demo/example/example_ytest.gox:18:1 +//line ytest/demo/_example/example_ytest.gox:18:1 this.RetWith(code) -//line ytest/demo/example/example_ytest.gox:19:1 +//line ytest/demo/_example/example_ytest.gox:19:1 fmt.Println("code:", code) -//line ytest/demo/example/example_ytest.gox:20:1 +//line ytest/demo/_example/example_ytest.gox:20:1 ytest.Match__4(code, 200) }) -//line ytest/demo/example/example_ytest.gox:23:1 +//line ytest/demo/_example/example_ytest.gox:23:1 this.Run("postWithAuth", func() { -//line ytest/demo/example/example_ytest.gox:24:1 +//line ytest/demo/_example/example_ytest.gox:24:1 id := "123" -//line ytest/demo/example/example_ytest.gox:25:1 +//line ytest/demo/_example/example_ytest.gox:25:1 title := "title" -//line ytest/demo/example/example_ytest.gox:26:1 +//line ytest/demo/_example/example_ytest.gox:26:1 author := "author" -//line ytest/demo/example/example_ytest.gox:27:1 +//line ytest/demo/_example/example_ytest.gox:27:1 this.Post("https://example.com/p/" + id) -//line ytest/demo/example/example_ytest.gox:28:1 +//line ytest/demo/_example/example_ytest.gox:28:1 this.Auth(testauth) -//line ytest/demo/example/example_ytest.gox:29:1 +//line ytest/demo/_example/example_ytest.gox:29:1 this.Json(map[string]string{"title": title, "author": author}) -//line ytest/demo/example/example_ytest.gox:33:1 +//line ytest/demo/_example/example_ytest.gox:33:1 this.RetWith(200) -//line ytest/demo/example/example_ytest.gox:34:1 +//line ytest/demo/_example/example_ytest.gox:34:1 fmt.Println("body:", this.Resp().Body()) }) -//line ytest/demo/example/example_ytest.gox:37:1 +//line ytest/demo/_example/example_ytest.gox:37:1 this.Run("matchJsonObject", func() { -//line ytest/demo/example/example_ytest.gox:38:1 +//line ytest/demo/_example/example_ytest.gox:38:1 title := ytest.Gopx_Var_Cast__0[string]() -//line ytest/demo/example/example_ytest.gox:39:1 +//line ytest/demo/_example/example_ytest.gox:39:1 author := ytest.Gopx_Var_Cast__0[string]() -//line ytest/demo/example/example_ytest.gox:40:1 +//line ytest/demo/_example/example_ytest.gox:40:1 id := "123" -//line ytest/demo/example/example_ytest.gox:41:1 +//line ytest/demo/_example/example_ytest.gox:41:1 this.Get("https://example.com/p/" + id) -//line ytest/demo/example/example_ytest.gox:42:1 +//line ytest/demo/_example/example_ytest.gox:42:1 this.RetWith(200) -//line ytest/demo/example/example_ytest.gox:43:1 +//line ytest/demo/_example/example_ytest.gox:43:1 this.Json(map[string]*ytest.Var__0[string]{"title": title, "author": author}) -//line ytest/demo/example/example_ytest.gox:47:1 +//line ytest/demo/_example/example_ytest.gox:47:1 fmt.Println("title:", title) -//line ytest/demo/example/example_ytest.gox:48:1 +//line ytest/demo/_example/example_ytest.gox:48:1 fmt.Println("author:", author) }) } diff --git a/ytest/demo/basic/foo.gox b/ytest/demo/basic/foo.gox new file mode 100644 index 0000000..6004e6c --- /dev/null +++ b/ytest/demo/basic/foo.gox @@ -0,0 +1,13 @@ +import "github.com/goplus/yap" + +var ( + yap.App +) + +App.init + +get "/p/:id", ctx => { + ctx.json { + "id": ctx.param("id"), + } +} diff --git a/ytest/demo/basic/foo_ytest.gox b/ytest/demo/basic/foo_ytest.gox new file mode 100644 index 0000000..a71bc8c --- /dev/null +++ b/ytest/demo/basic/foo_ytest.gox @@ -0,0 +1,12 @@ +server := new(foo) +server.main +runMock "foo.com", server + +run "get /p/$id", => { + id := "123" + get "http://foo.com/p/${id}" + ret 200 + json { + "id": "12", + } +} diff --git a/ytest/demo/basic/gop_autogen.go b/ytest/demo/basic/gop_autogen.go new file mode 100644 index 0000000..04ed787 --- /dev/null +++ b/ytest/demo/basic/gop_autogen.go @@ -0,0 +1,21 @@ +package main + +import "github.com/goplus/yap" + +const _ = true + +type foo struct { + yap.App +} +//line ytest/demo/basic/foo.gox:7 +func (this *foo) Main() { +//line ytest/demo/basic/foo.gox:7:1 + this.App.Init() +//line ytest/demo/basic/foo.gox:9:1 + this.Get("/p/:id", func(ctx *yap.Context) { +//line ytest/demo/basic/foo.gox:10:1 + ctx.Json__1(map[string]string{"id": ctx.Param("id")}) + }) +} +func main() { +} diff --git a/ytest/demo/basic/gop_autogen_test.go b/ytest/demo/basic/gop_autogen_test.go new file mode 100644 index 0000000..32093d7 --- /dev/null +++ b/ytest/demo/basic/gop_autogen_test.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/goplus/yap/ytest" + "testing" +) + +type case_foo struct { + ytest.Case +} +//line ytest/demo/basic/foo_ytest.gox:1 +func (this *case_foo) Main() { +//line ytest/demo/basic/foo_ytest.gox:1:1 + server := new(foo) +//line ytest/demo/basic/foo_ytest.gox:2:1 + server.Main() +//line ytest/demo/basic/foo_ytest.gox:3:1 + this.RunMock("foo.com", server) +//line ytest/demo/basic/foo_ytest.gox:5:1 + this.Run("get /p/$id", func() { +//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) +//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": "12"}) + }) +} +func Test_foo(t *testing.T) { + ytest.Gopt_Case_TestMain(new(case_foo), t) +} diff --git a/ytest/demo/mixyap/_main.yunit.gox b/ytest/demo/mixyap/_main.yunit.gox deleted file mode 100644 index 1032b1a..0000000 --- a/ytest/demo/mixyap/_main.yunit.gox +++ /dev/null @@ -1,5 +0,0 @@ -import "github.com/goplus/yap" - -var ( - yap.App -) From 15a649b39e21409675402de565da6b2b20de94ff Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 30 Jan 2024 18:36:01 +0800 Subject: [PATCH 2/2] yap.App: init => initYap --- classfile.go | 4 ++-- ytest/demo/basic/foo.gox | 2 +- ytest/demo/basic/gop_autogen.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/classfile.go b/classfile.go index 4e21af6..f21460e 100644 --- a/classfile.go +++ b/classfile.go @@ -36,8 +36,8 @@ func (p *App) initApp() { p.Engine = New() } -// Init initialize a YAP application. -func (p *App) Init(fs ...fs.FS) { +// InitYap initialize a YAP application. +func (p *App) InitYap(fs ...fs.FS) { if p.Engine == nil { p.initApp() } diff --git a/ytest/demo/basic/foo.gox b/ytest/demo/basic/foo.gox index 6004e6c..405d2a4 100644 --- a/ytest/demo/basic/foo.gox +++ b/ytest/demo/basic/foo.gox @@ -4,7 +4,7 @@ var ( yap.App ) -App.init +initYap get "/p/:id", ctx => { ctx.json { diff --git a/ytest/demo/basic/gop_autogen.go b/ytest/demo/basic/gop_autogen.go index 04ed787..678c43d 100644 --- a/ytest/demo/basic/gop_autogen.go +++ b/ytest/demo/basic/gop_autogen.go @@ -10,7 +10,7 @@ type foo struct { //line ytest/demo/basic/foo.gox:7 func (this *foo) Main() { //line ytest/demo/basic/foo.gox:7:1 - this.App.Init() + this.InitYap() //line ytest/demo/basic/foo.gox:9:1 this.Get("/p/:id", func(ctx *yap.Context) { //line ytest/demo/basic/foo.gox:10:1