1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-09 13:05:56 +00:00

add the stale release

This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-08-12 23:41:20 +03:00
parent 535fb6dc0d
commit 2a4ce876b6
793 changed files with 188 additions and 52415 deletions

View File

@@ -1,8 +1,8 @@
package mvc
import (
"github.com/kataras/iris/v12/hero"
"github.com/kataras/iris/v12/versioning"
"github.com/kataras/iris/hero"
"github.com/kataras/iris/versioning"
)
type (

View File

@@ -5,10 +5,10 @@ import (
"reflect"
"strings"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/hero"
"github.com/kataras/iris/v12/macro"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/router"
"github.com/kataras/iris/hero"
"github.com/kataras/iris/macro"
)
// BaseController is the optional controller interface, if it's

View File

@@ -1,201 +0,0 @@
package mvc_test
import (
"testing"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/httptest"
. "github.com/kataras/iris/v12/mvc"
)
// service
type (
// these testService and testServiceImpl could be in lowercase, unexported
// but the `Say` method should be exported however we have those exported
// because of the controller handler test.
testService interface {
Say(string) string
}
testServiceImpl struct {
prefix string
}
)
func (s *testServiceImpl) Say(message string) string {
return s.prefix + " " + message
}
type testControllerHandle struct {
Ctx *context.Context
Service testService
reqField string
}
func (c *testControllerHandle) BeforeActivation(b BeforeActivation) {
b.Handle("GET", "/histatic", "HiStatic")
b.Handle("GET", "/hiservice", "HiService")
b.Handle("GET", "/hiservice/{ps:string}", "HiServiceBy")
b.Handle("GET", "/hiparam/{ps:string}", "HiParamBy")
b.Handle("GET", "/hiparamempyinput/{ps:string}", "HiParamEmptyInputBy")
b.HandleMany("GET", "/custom/{ps:string} /custom2/{ps:string}", "CustomWithParameter")
b.HandleMany("GET", "/custom3/{ps:string}/{pssecond:string}", "CustomWithParameters")
}
// test `GetRoute` for custom routes.
func (c *testControllerHandle) AfterActivation(a AfterActivation) {
// change automatic parser's route change name.
rget := a.GetRoute("Get")
if rget == nil {
panic("route from function name: 'Get' doesn't exist on `AfterActivation`")
}
rget.Name = "index_route"
// change a custom route's name.
r := a.GetRoute("HiStatic")
if r == nil {
panic("route from function name: HiStatic doesn't exist on `AfterActivation`")
}
// change the name here, and test if name changed in the handler.
r.Name = "hi_static_route"
}
func (c *testControllerHandle) BeginRequest(ctx iris.Context) {
c.reqField = ctx.URLParam("reqfield")
}
func (c *testControllerHandle) EndRequest(ctx iris.Context) {}
func (c *testControllerHandle) Get() string {
if c.Ctx.GetCurrentRoute().Name() != "index_route" {
return "Get's route's name didn't change on AfterActivation"
}
return "index"
}
func (c *testControllerHandle) HiStatic() string {
if c.Ctx.GetCurrentRoute().Name() != "hi_static_route" {
return "HiStatic's route's name didn't change on AfterActivation"
}
return c.reqField
}
func (c *testControllerHandle) HiService() string {
return c.Service.Say("hi")
}
func (c *testControllerHandle) HiServiceBy(v string) string {
return c.Service.Say("hi with param: " + v)
}
func (c *testControllerHandle) HiParamBy(v string) string {
return v
}
func (c *testControllerHandle) HiParamEmptyInputBy() string {
return "empty in but served with ctx.Params.Get('ps')=" + c.Ctx.Params().Get("ps")
}
func (c *testControllerHandle) CustomWithParameter(param1 string) string {
return param1
}
func (c *testControllerHandle) CustomWithParameters(param1, param2 string) string {
return param1 + param2
}
type testSmallController struct{}
// test ctx + id in the same time.
func (c *testSmallController) GetHiParamEmptyInputWithCtxBy(ctx *context.Context, id string) string {
return "empty in but served with ctx.Params.Get('param2')= " + ctx.Params().Get("param2") + " == id == " + id
}
func TestControllerHandle(t *testing.T) {
app := iris.New()
m := New(app)
m.Register(&testServiceImpl{prefix: "service:"})
m.Handle(new(testControllerHandle))
m.Handle(new(testSmallController))
e := httptest.New(t, app)
// test the index, is not part of the current package's implementation but do it.
e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal("index")
// the important things now.
// this test ensures that the BeginRequest of the controller will be
// called correctly and also the controller is binded to the first input argument
// (which is the function's receiver, if any, in this case the *testController in go).
expectedReqField := "this is a request field filled by this url param"
e.GET("/histatic").WithQuery("reqfield", expectedReqField).Expect().Status(httptest.StatusOK).
Body().Equal(expectedReqField)
// this test makes sure that the binded values of the controller is handled correctly
// and can be used in a user-defined, dynamic "mvc handler".
e.GET("/hiservice").Expect().Status(httptest.StatusOK).
Body().Equal("service: hi")
e.GET("/hiservice/value").Expect().Status(httptest.StatusOK).
Body().Equal("service: hi with param: value")
// this worked with a temporary variadic on the resolvemethodfunc which is not
// correct design, I should split the path and params with the rest of implementation
// in order a simple template.Src can be given.
e.GET("/hiparam/value").Expect().Status(httptest.StatusOK).
Body().Equal("value")
e.GET("/hiparamempyinput/value").Expect().Status(httptest.StatusOK).
Body().Equal("empty in but served with ctx.Params.Get('ps')=value")
e.GET("/custom/value1").Expect().Status(httptest.StatusOK).
Body().Equal("value1")
e.GET("/custom2/value2").Expect().Status(httptest.StatusOK).
Body().Equal("value2")
e.GET("/custom3/value1/value2").Expect().Status(httptest.StatusOK).
Body().Equal("value1value2")
e.GET("/custom3/value1").Expect().Status(httptest.StatusNotFound)
e.GET("/hi/param/empty/input/with/ctx/value").Expect().Status(httptest.StatusOK).
Body().Equal("empty in but served with ctx.Params.Get('param2')= value == id == value")
}
type testControllerHandleWithDynamicPathPrefix struct {
Ctx iris.Context
}
func (c *testControllerHandleWithDynamicPathPrefix) GetBy(id string) string {
params := c.Ctx.Params()
return params.Get("model") + params.Get("action") + id
}
func TestControllerHandleWithDynamicPathPrefix(t *testing.T) {
app := iris.New()
New(app.Party("/api/data/{model:string}/{action:string}")).Handle(new(testControllerHandleWithDynamicPathPrefix))
e := httptest.New(t, app)
e.GET("/api/data/mymodel/myaction/myid").Expect().Status(httptest.StatusOK).
Body().Equal("mymodelmyactionmyid")
}
type testControllerGetBy struct{}
func (c *testControllerGetBy) GetBy(age int64) *testCustomStruct {
return &testCustomStruct{
Age: int(age),
Name: "name",
}
}
func TestControllerGetByWithAllowMethods(t *testing.T) {
app := iris.New()
app.Configure(iris.WithFireMethodNotAllowed)
// ^ this 405 status will not be fired on POST: project/... because of
// .AllowMethods, but it will on PUT.
New(app.Party("/project").AllowMethods(iris.MethodGet, iris.MethodPost)).Handle(new(testControllerGetBy))
e := httptest.New(t, app)
e.GET("/project/42").Expect().Status(httptest.StatusOK).
JSON().Equal(&testCustomStruct{Age: 42, Name: "name"})
e.POST("/project/42").Expect().Status(httptest.StatusOK)
e.PUT("/project/42").Expect().Status(httptest.StatusMethodNotAllowed)
}

View File

@@ -8,8 +8,8 @@ import (
"strings"
"unicode"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/macro"
"github.com/kataras/iris/core/router"
"github.com/kataras/iris/macro"
)
const (

View File

@@ -1,271 +0,0 @@
package mvc_test
import (
"errors"
"testing"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/httptest"
. "github.com/kataras/iris/v12/mvc"
)
type testControllerMethodResult struct {
Ctx *context.Context
}
func (c *testControllerMethodResult) Get() Result {
return Response{
Text: "Hello World!",
}
}
func (c *testControllerMethodResult) GetWithStatus() Response { // or Result again, no problem.
return Response{
Text: "This page doesn't exist",
Code: iris.StatusNotFound,
}
}
type testCustomStruct struct {
Name string `json:"name" xml:"name"`
Age int `json:"age" xml:"age"`
}
func (c *testControllerMethodResult) GetJson() Result {
var err error
if c.Ctx.URLParamExists("err") {
err = errors.New("error here")
}
return Response{
Err: err, // if err != nil then it will fire the error's text with a BadRequest.
Object: testCustomStruct{Name: "Iris", Age: 2},
}
}
var things = []string{"thing 0", "thing 1", "thing 2"}
func (c *testControllerMethodResult) GetThingWithTryBy(index int) Result {
failure := Response{
Text: "thing does not exist",
Code: iris.StatusNotFound,
}
return Try(func() Result {
// if panic because of index exceed the slice
// then the "failure" response will be returned instead.
return Response{Text: things[index]}
}, failure)
}
func (c *testControllerMethodResult) GetThingWithTryDefaultBy(index int) Result {
return Try(func() Result {
// if panic because of index exceed the slice
// then the default failure response will be returned instead (400 bad request).
return Response{Text: things[index]}
})
}
func TestControllerMethodResult(t *testing.T) {
app := iris.New()
New(app).Handle(new(testControllerMethodResult))
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusOK).
Body().Equal("Hello World!")
e.GET("/with/status").Expect().Status(iris.StatusNotFound).
Body().Equal("This page doesn't exist")
e.GET("/json").Expect().Status(iris.StatusOK).
JSON().Equal(iris.Map{
"name": "Iris",
"age": 2,
})
e.GET("/json").WithQuery("err", true).Expect().
Status(iris.StatusBadRequest).
Body().Equal("error here")
e.GET("/thing/with/try/1").Expect().
Status(iris.StatusOK).
Body().Equal("thing 1")
// failure because of index exceed the slice
e.GET("/thing/with/try/3").Expect().
Status(iris.StatusNotFound).
Body().Equal("thing does not exist")
e.GET("/thing/with/try/default/3").Expect().
Status(iris.StatusBadRequest).
Body().Equal("Bad Request")
}
type testControllerMethodResultTypes struct {
Ctx *context.Context
}
func (c *testControllerMethodResultTypes) GetText() string {
return "text"
}
func (c *testControllerMethodResultTypes) GetStatus() int {
return iris.StatusBadGateway
}
func (c *testControllerMethodResultTypes) GetTextWithStatusOk() (string, int) {
return "OK", iris.StatusOK
}
// tests should have output arguments mixed
func (c *testControllerMethodResultTypes) GetStatusWithTextNotOkBy(first string, second string) (int, string) {
return iris.StatusForbidden, "NOT_OK_" + first + second
}
func (c *testControllerMethodResultTypes) GetTextAndContentType() (string, string) {
return "<b>text</b>", "text/html"
}
type testControllerMethodCustomResult struct {
HTML string
}
// The only one required function to make that a custom Response dispatcher.
func (r testControllerMethodCustomResult) Dispatch(ctx *context.Context) {
ctx.HTML(r.HTML)
}
func (c *testControllerMethodResultTypes) GetCustomResponse() testControllerMethodCustomResult {
return testControllerMethodCustomResult{"<b>text</b>"}
}
func (c *testControllerMethodResultTypes) GetCustomResponseWithStatusOk() (testControllerMethodCustomResult, int) {
return testControllerMethodCustomResult{"<b>OK</b>"}, iris.StatusOK
}
func (c *testControllerMethodResultTypes) GetCustomResponseWithStatusNotOk() (testControllerMethodCustomResult, int) {
return testControllerMethodCustomResult{"<b>internal server error</b>"}, iris.StatusInternalServerError
}
func (c *testControllerMethodResultTypes) GetCustomStruct() testCustomStruct {
return testCustomStruct{"Iris", 2}
}
func (c *testControllerMethodResultTypes) GetCustomStructWithStatusNotOk() (testCustomStruct, int) {
return testCustomStruct{"Iris", 2}, iris.StatusInternalServerError
}
func (c *testControllerMethodResultTypes) GetCustomStructWithContentType() (testCustomStruct, string) {
return testCustomStruct{"Iris", 2}, "text/xml"
}
func (c *testControllerMethodResultTypes) GetCustomStructWithError() (s testCustomStruct, err error) {
s = testCustomStruct{"Iris", 2}
if c.Ctx.URLParamExists("err") {
err = errors.New("omit return of testCustomStruct and fire error")
}
// it should send the testCustomStruct as JSON if error is nil
// otherwise it should fire the default error(BadRequest) with the error's text.
return
}
func TestControllerMethodResultTypes(t *testing.T) {
app := iris.New()
New(app).Handle(new(testControllerMethodResultTypes))
e := httptest.New(t, app)
e.GET("/text").Expect().Status(iris.StatusOK).
Body().Equal("text")
e.GET("/status").Expect().Status(iris.StatusBadGateway)
e.GET("/text/with/status/ok").Expect().Status(iris.StatusOK).
Body().Equal("OK")
e.GET("/status/with/text/not/ok/first/second").Expect().Status(iris.StatusForbidden).
Body().Equal("NOT_OK_firstsecond")
// Author's note: <-- if that fails means that the last binder called for both input args,
// see path_param_binder.go
e.GET("/text/and/content/type").Expect().Status(iris.StatusOK).
ContentType("text/html", "utf-8").
Body().Equal("<b>text</b>")
e.GET("/custom/response").Expect().Status(iris.StatusOK).
ContentType("text/html", "utf-8").
Body().Equal("<b>text</b>")
e.GET("/custom/response/with/status/ok").Expect().Status(iris.StatusOK).
ContentType("text/html", "utf-8").
Body().Equal("<b>OK</b>")
e.GET("/custom/response/with/status/not/ok").Expect().Status(iris.StatusInternalServerError).
ContentType("text/html", "utf-8").
Body().Equal("<b>internal server error</b>")
expectedResultFromCustomStruct := map[string]interface{}{
"name": "Iris",
"age": 2,
}
e.GET("/custom/struct").Expect().Status(iris.StatusOK).
JSON().Equal(expectedResultFromCustomStruct)
e.GET("/custom/struct/with/status/not/ok").Expect().Status(iris.StatusInternalServerError).
JSON().Equal(expectedResultFromCustomStruct)
e.GET("/custom/struct/with/content/type").Expect().Status(iris.StatusOK).
ContentType("text/xml", "utf-8")
e.GET("/custom/struct/with/error").Expect().Status(iris.StatusOK).
JSON().Equal(expectedResultFromCustomStruct)
e.GET("/custom/struct/with/error").WithQuery("err", true).Expect().
Status(iris.StatusBadRequest). // the default status code if error is not nil
// the content should be not JSON it should be the status code's text
// it will fire the error's text
Body().Equal("omit return of testCustomStruct and fire error")
}
type testControllerViewResultRespectCtxViewData struct {
T *testing.T
}
func (t *testControllerViewResultRespectCtxViewData) BeginRequest(ctx *context.Context) {
ctx.ViewData("name_begin", "iris_begin")
}
func (t *testControllerViewResultRespectCtxViewData) EndRequest(ctx *context.Context) {
// check if data is not overridden by return View {Data: context.Map...}
dataWritten := ctx.GetViewData()
if dataWritten == nil {
t.T.Fatalf("view data is nil, both BeginRequest and Get failed to write the data")
return
}
if dataWritten["name_begin"] == nil {
t.T.Fatalf(`view data[name_begin] is nil,
BeginRequest's ctx.ViewData call have been overridden by Get's return View {Data: }.
Total view data: %v`, dataWritten)
}
if dataWritten["name"] == nil {
t.T.Fatalf("view data[name] is nil, Get's return View {Data: } didn't work. Total view data: %v", dataWritten)
}
}
func (t *testControllerViewResultRespectCtxViewData) Get() Result {
return View{
Name: "doesnt_exists.html",
Data: context.Map{"name": "iris"}, // we care about this only.
Code: iris.StatusInternalServerError,
}
}
func TestControllerViewResultRespectCtxViewData(t *testing.T) {
app := iris.New()
m := New(app.Party("/"))
m.Register(t)
m.Handle(new(testControllerViewResultRespectCtxViewData))
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusInternalServerError)
}

View File

@@ -1,758 +0,0 @@
// black-box testing
package mvc_test
import (
"testing"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/hero"
"github.com/kataras/iris/v12/httptest"
. "github.com/kataras/iris/v12/mvc"
)
type testController struct {
Ctx *context.Context
}
var writeMethod = func(ctx *context.Context) {
ctx.Writef(ctx.Method())
}
func (c *testController) Get() {
writeMethod(c.Ctx)
}
func (c *testController) Post() {
writeMethod(c.Ctx)
}
func (c *testController) Put() {
writeMethod(c.Ctx)
}
func (c *testController) Delete() {
writeMethod(c.Ctx)
}
func (c *testController) Connect() {
writeMethod(c.Ctx)
}
func (c *testController) Head() {
writeMethod(c.Ctx)
}
func (c *testController) Patch() {
writeMethod(c.Ctx)
}
func (c *testController) Options() {
writeMethod(c.Ctx)
}
func (c *testController) Trace() {
writeMethod(c.Ctx)
}
type (
testControllerAll struct{ Ctx *context.Context }
testControllerAny struct{ Ctx *context.Context } // exactly the same as All.
)
func (c *testControllerAll) All() {
writeMethod(c.Ctx)
}
func (c *testControllerAny) Any() {
writeMethod(c.Ctx)
}
func TestControllerMethodFuncs(t *testing.T) {
app := iris.New()
New(app).Handle(new(testController))
New(app.Party("/all")).Handle(new(testControllerAll))
New(app.Party("/any")).Handle(new(testControllerAny))
e := httptest.New(t, app)
for _, method := range router.AllMethods {
e.Request(method, "/").Expect().Status(iris.StatusOK).
Body().Equal(method)
e.Request(method, "/all").Expect().Status(iris.StatusOK).
Body().Equal(method)
e.Request(method, "/any").Expect().Status(iris.StatusOK).
Body().Equal(method)
}
}
type testControllerBeginAndEndRequestFunc struct {
Ctx *context.Context
Username string
}
// called before of every method (Get() or Post()).
//
// useful when more than one methods using the
// same request values or context's function calls.
func (c *testControllerBeginAndEndRequestFunc) BeginRequest(ctx *context.Context) {
c.Username = ctx.Params().Get("username")
}
// called after every method (Get() or Post()).
func (c *testControllerBeginAndEndRequestFunc) EndRequest(ctx *context.Context) {
ctx.Writef("done") // append "done" to the response
}
func (c *testControllerBeginAndEndRequestFunc) Get() {
c.Ctx.Writef(c.Username)
}
func (c *testControllerBeginAndEndRequestFunc) Post() {
c.Ctx.Writef(c.Username)
}
func TestControllerBeginAndEndRequestFunc(t *testing.T) {
app := iris.New()
New(app.Party("/profile/{username}")).
Handle(new(testControllerBeginAndEndRequestFunc))
e := httptest.New(t, app)
usernames := []string{
"kataras",
"makis",
"efi",
"rg",
"bill",
"whoisyourdaddy",
}
doneResponse := "done"
for _, username := range usernames {
e.GET("/profile/" + username).Expect().Status(iris.StatusOK).
Body().Equal(username + doneResponse)
e.POST("/profile/" + username).Expect().Status(iris.StatusOK).
Body().Equal(username + doneResponse)
}
}
func TestControllerBeginAndEndRequestFuncBindMiddleware(t *testing.T) {
app := iris.New()
usernames := map[string]bool{
"kataras": true,
"makis": false,
"efi": true,
"rg": false,
"bill": true,
"whoisyourdaddy": false,
}
middlewareCheck := func(ctx *context.Context) {
for username, allow := range usernames {
if ctx.Params().Get("username") == username && allow {
ctx.Next()
return
}
}
ctx.StatusCode(iris.StatusForbidden)
ctx.Writef("forbidden")
}
app.PartyFunc("/profile/{username}", func(r iris.Party) {
r.Use(middlewareCheck)
New(r).Handle(new(testControllerBeginAndEndRequestFunc))
})
e := httptest.New(t, app)
doneResponse := "done"
for username, allow := range usernames {
getEx := e.GET("/profile/" + username).Expect()
if allow {
getEx.Status(iris.StatusOK).
Body().Equal(username + doneResponse)
} else {
getEx.Status(iris.StatusForbidden).Body().Equal("forbidden")
}
postEx := e.POST("/profile/" + username).Expect()
if allow {
postEx.Status(iris.StatusOK).
Body().Equal(username + doneResponse)
} else {
postEx.Status(iris.StatusForbidden).Body().Equal("forbidden")
}
}
}
type Model struct {
Username string
}
type testControllerEndRequestAwareness struct {
Ctx *context.Context
}
func (c *testControllerEndRequestAwareness) Get() {
username := c.Ctx.Params().Get("username")
c.Ctx.Values().Set(c.Ctx.Application().ConfigurationReadOnly().GetViewDataContextKey(),
map[string]interface{}{
"TestModel": Model{Username: username},
"myModel": Model{Username: username + "2"},
})
}
func writeModels(ctx *context.Context, names ...string) {
if expected, got := len(names), len(ctx.GetViewData()); expected != got {
ctx.Writef("expected view data length: %d but got: %d for names: %s", expected, got, names)
return
}
for _, name := range names {
m, ok := ctx.GetViewData()[name]
if !ok {
ctx.Writef("fail load and set the %s", name)
return
}
model, ok := m.(Model)
if !ok {
ctx.Writef("fail to override the %s' name by the tag", name)
return
}
ctx.Writef(model.Username)
}
}
func (c *testControllerEndRequestAwareness) BeginRequest(ctx *context.Context) {}
func (c *testControllerEndRequestAwareness) EndRequest(ctx *context.Context) {
writeModels(ctx, "TestModel", "myModel")
}
func TestControllerEndRequestAwareness(t *testing.T) {
app := iris.New()
New(app.Party("/era/{username}")).Handle(new(testControllerEndRequestAwareness))
e := httptest.New(t, app)
usernames := []string{
"kataras",
"makis",
}
for _, username := range usernames {
e.GET("/era/" + username).Expect().Status(iris.StatusOK).
Body().Equal(username + username + "2")
}
}
type testBindType struct {
title string
}
type testControllerBindStruct struct {
Ctx *context.Context
// should start with upper letter of course
TitlePointer *testBindType // should have the value of the "myTitlePtr" on test
TitleValue testBindType // should have the value of the "myTitleV" on test
Other string // just another type to check the field collection, should be empty
}
func (t *testControllerBindStruct) Get() {
t.Ctx.Writef(t.TitlePointer.title + t.TitleValue.title + t.Other)
}
// test if context can be binded to the controller's function
// without need to declare it to a struct if not needed.
func (t *testControllerBindStruct) GetCtx(ctx iris.Context) {
ctx.StatusCode(iris.StatusContinue)
}
type testControllerBindDeep struct {
testControllerBindStruct
}
func (t *testControllerBindDeep) BeforeActivation(b BeforeActivation) {
b.Dependencies().Register(func(ctx iris.Context) (v testCustomStruct, err error) {
err = ctx.ReadJSON(&v)
return
})
}
func (t *testControllerBindDeep) Get() {
// t.testControllerBindStruct.Get()
t.Ctx.Writef(t.TitlePointer.title + t.TitleValue.title + t.Other)
}
func (t *testControllerBindDeep) Post(v testCustomStruct) string {
return v.Name
}
func TestControllerDependencies(t *testing.T) {
app := iris.New()
// app.Logger().SetLevel("debug")
t1, t2 := "my pointer title", "val title"
// test bind pointer to pointer of the correct type
myTitlePtr := &testBindType{title: t1}
// test bind value to value of the correct type
myTitleV := testBindType{title: t2}
m := New(app)
m.Register(myTitlePtr, myTitleV)
m.Handle(new(testControllerBindStruct))
m.Clone(app.Party("/deep")).Handle(new(testControllerBindDeep))
e := httptest.New(t, app)
expected := t1 + t2
e.GET("/").Expect().Status(iris.StatusOK).
Body().Equal(expected)
e.GET("/ctx").Expect().Status(iris.StatusContinue)
e.GET("/deep").Expect().Status(iris.StatusOK).
Body().Equal(expected)
e.POST("/deep").WithJSON(iris.Map{"name": "kataras"}).Expect().Status(iris.StatusOK).
Body().Equal("kataras")
e.POST("/deep").Expect().Status(iris.StatusBadRequest).
Body().Equal("unexpected end of JSON input")
}
type testCtrl0 struct {
testCtrl00
}
func (c *testCtrl0) Get() string {
return c.Ctx.Params().Get("username")
}
func (c *testCtrl0) EndRequest(ctx *context.Context) {
if c.TitlePointer == nil {
ctx.Writef("\nTitlePointer is nil!\n")
} else {
ctx.Writef(c.TitlePointer.title)
}
// should be the same as `.testCtrl000.testCtrl0000.EndRequest(ctx)`
c.testCtrl00.EndRequest(ctx)
}
type testCtrl00 struct {
Ctx *context.Context
testCtrl000
}
type testCtrl000 struct {
testCtrl0000
TitlePointer *testBindType
}
type testCtrl0000 struct {
}
func (c *testCtrl0000) BeginRequest(ctx *context.Context) {}
func (c *testCtrl0000) EndRequest(ctx *context.Context) {
ctx.Writef("finish")
}
func TestControllerInsideControllerRecursively(t *testing.T) {
var (
username = "gerasimos"
title = "mytitle"
expected = username + title + "finish"
)
app := iris.New()
m := New(app.Party("/user/{username}"))
m.Register(&testBindType{title: title})
m.Handle(new(testCtrl0))
e := httptest.New(t, app)
e.GET("/user/" + username).Expect().
Status(iris.StatusOK).Body().Equal(expected)
}
type testControllerRelPathFromFunc struct{}
func (c *testControllerRelPathFromFunc) BeginRequest(ctx *context.Context) {}
func (c *testControllerRelPathFromFunc) EndRequest(ctx *context.Context) {
ctx.Writef("%s:%s", ctx.Method(), ctx.Path())
}
func (c *testControllerRelPathFromFunc) Get() {}
func (c *testControllerRelPathFromFunc) GetBy(uint64) {}
func (c *testControllerRelPathFromFunc) GetUint8RatioBy(uint8) {}
func (c *testControllerRelPathFromFunc) GetInt64RatioBy(int64) {}
func (c *testControllerRelPathFromFunc) GetAnythingByWildcard(string) {}
func (c *testControllerRelPathFromFunc) GetLogin() {}
func (c *testControllerRelPathFromFunc) PostLogin() {}
func (c *testControllerRelPathFromFunc) GetAdminLogin() {}
func (c *testControllerRelPathFromFunc) PutSomethingIntoThis() {}
func (c *testControllerRelPathFromFunc) GetSomethingBy(bool) {}
func (c *testControllerRelPathFromFunc) GetSomethingByBy(string, int) {}
func (c *testControllerRelPathFromFunc) GetSomethingNewBy(string, int) {} // two input arguments, one By which is the latest word.
func (c *testControllerRelPathFromFunc) GetSomethingByElseThisBy(bool, int) {} // two input arguments
func (c *testControllerRelPathFromFunc) GetLocationX() {}
func (c *testControllerRelPathFromFunc) GetLocationXY() {}
func (c *testControllerRelPathFromFunc) GetLocationZBy(int) {}
func TestControllerRelPathFromFunc(t *testing.T) {
app := iris.New()
New(app).Handle(new(testControllerRelPathFromFunc))
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusOK).
Body().Equal("GET:/")
e.GET("/18446744073709551615").Expect().Status(iris.StatusOK).
Body().Equal("GET:/18446744073709551615")
e.GET("/uint8/ratio/255").Expect().Status(iris.StatusOK).
Body().Equal("GET:/uint8/ratio/255")
e.GET("/uint8/ratio/256").Expect().Status(iris.StatusNotFound)
e.GET("/int64/ratio/-42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/int64/ratio/-42")
e.GET("/something/true").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/true")
e.GET("/something/false").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/false")
e.GET("/something/truee").Expect().Status(iris.StatusNotFound)
e.GET("/something/falsee").Expect().Status(iris.StatusNotFound)
e.GET("/something/kataras/42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/kataras/42")
e.GET("/something/new/kataras/42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/new/kataras/42")
e.GET("/something/true/else/this/42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/something/true/else/this/42")
e.GET("/login").Expect().Status(iris.StatusOK).
Body().Equal("GET:/login")
e.POST("/login").Expect().Status(iris.StatusOK).
Body().Equal("POST:/login")
e.GET("/admin/login").Expect().Status(iris.StatusOK).
Body().Equal("GET:/admin/login")
e.PUT("/something/into/this").Expect().Status(iris.StatusOK).
Body().Equal("PUT:/something/into/this")
e.GET("/42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/42")
e.GET("/anything/here").Expect().Status(iris.StatusOK).
Body().Equal("GET:/anything/here")
e.GET("/location/x").Expect().Status(iris.StatusOK).
Body().Equal("GET:/location/x")
e.GET("/location/x/y").Expect().Status(iris.StatusOK).
Body().Equal("GET:/location/x/y")
e.GET("/location/z/42").Expect().Status(iris.StatusOK).
Body().Equal("GET:/location/z/42")
}
type testControllerActivateListener struct {
TitlePointer *testBindType
}
func (c *testControllerActivateListener) BeforeActivation(b BeforeActivation) {
b.Dependencies().Register(&testBindType{title: "overrides the dependency but not the field"}) // overrides the `Register` previous calls.
// b.Handle("POST", "/me/tos-read", "MeTOSRead")
// b.Handle("GET", "/me/tos-read", "MeTOSRead")
// OR:
b.HandleMany("GET POST", "/me/tos-read", "MeTOSRead")
}
func (c *testControllerActivateListener) Get() string {
return c.TitlePointer.title
}
func (c *testControllerActivateListener) MeTOSRead() string {
return "MeTOSRead"
}
func TestControllerActivateListener(t *testing.T) {
app := iris.New()
New(app).Handle(new(testControllerActivateListener))
m := New(app)
m.Register(&testBindType{
title: "my title",
})
m.Party("/manual").Handle(new(testControllerActivateListener))
// or
m.Party("/manual2").Handle(&testControllerActivateListener{
TitlePointer: &testBindType{
title: "my manual title",
},
})
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusOK).
Body().Equal("overrides the dependency but not the field")
e.GET("/me/tos-read").Expect().Status(iris.StatusOK).
Body().Equal("MeTOSRead")
e.POST("/me/tos-read").Expect().Status(iris.StatusOK).
Body().Equal("MeTOSRead")
e.GET("/manual").Expect().Status(iris.StatusOK).
Body().Equal("overrides the dependency but not the field")
e.GET("/manual2").Expect().Status(iris.StatusOK).
Body().Equal("my manual title")
}
type testControllerNotCreateNewDueManuallySettingAllFields struct {
T *testing.T
TitlePointer *testBindType
}
func (c *testControllerNotCreateNewDueManuallySettingAllFields) AfterActivation(a AfterActivation) {
if n := len(a.DependenciesReadOnly()) - len(hero.BuiltinDependencies) - 1; /* Application */ n != 1 {
c.T.Fatalf(`expecting 1 dependency;
- the 'T' and the 'TitlePointer' are manually binded (nonzero fields on initilization)
- controller has no more than these two fields, it's a singleton
- however, the dependencies length here should be 1 because the injector's options handler dependencies contains the controller's value dependency itself
-- got dependencies length: %d`, n)
}
if !a.Singleton() {
c.T.Fatalf(`this controller should be tagged as Singleton. It shouldn't be tagged used as request scoped(create new instances on each request),
it doesn't contain any dynamic value or dependencies that should be binded via the iris mvc engine`)
}
}
func (c *testControllerNotCreateNewDueManuallySettingAllFields) Get() string {
return c.TitlePointer.title
}
func TestControllerNotCreateNewDueManuallySettingAllFields(t *testing.T) {
app := iris.New()
New(app).Handle(&testControllerNotCreateNewDueManuallySettingAllFields{
T: t,
TitlePointer: &testBindType{
title: "my title",
},
})
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusOK).
Body().Equal("my title")
}
type testControllerRequestScopedDependencies struct {
MyContext *testMyContext
CustomStruct *testCustomStruct
}
func (c *testControllerRequestScopedDependencies) Get() *testCustomStruct {
return c.CustomStruct
}
func (c *testControllerRequestScopedDependencies) GetCustomContext() string {
return c.MyContext.OtherField
}
func newRequestDep1(ctx *context.Context) *testCustomStruct {
return &testCustomStruct{
Name: ctx.URLParam("name"),
Age: ctx.URLParamIntDefault("age", 0),
}
}
type testMyContext struct {
Context *context.Context
OtherField string
}
func newRequestDep2(ctx *context.Context) *testMyContext {
return &testMyContext{
Context: ctx,
OtherField: "test",
}
}
func TestControllerRequestScopedDependencies(t *testing.T) {
app := iris.New()
m := New(app)
m.Register(newRequestDep1)
m.Register(newRequestDep2)
m.Handle(new(testControllerRequestScopedDependencies))
e := httptest.New(t, app)
e.GET("/").WithQuery("name", "kataras").WithQuery("age", 27).
Expect().Status(httptest.StatusOK).JSON().Equal(&testCustomStruct{
Name: "kataras",
Age: 27,
})
e.GET("/custom/context").Expect().Status(httptest.StatusOK).Body().Equal("test")
}
type (
testServiceDoSomething struct{}
TestControllerAsDeepDep struct {
Ctx iris.Context
Service *testServiceDoSomething
}
FooController struct {
TestControllerAsDeepDep
}
BarController struct {
FooController
}
FinalController struct {
BarController
}
)
func (s *testServiceDoSomething) DoSomething(ctx iris.Context) {
ctx.WriteString("foo bar")
}
func (c *FinalController) GetSomething() {
c.Service.DoSomething(c.Ctx)
}
func TestControllersInsideControllerDeep(t *testing.T) {
app := iris.New()
m := New(app)
m.Register(new(testServiceDoSomething))
m.Handle(new(FinalController))
e := httptest.New(t, app)
e.GET("/something").Expect().Status(httptest.StatusOK).Body().Equal("foo bar")
}
type testApplicationDependency struct {
App *Application
}
func (c *testApplicationDependency) Get() string {
return c.App.Name
}
func TestApplicationDependency(t *testing.T) {
app := iris.New()
m := New(app).SetName("app1")
m.Handle(new(testApplicationDependency))
m2 := m.Clone(app.Party("/other")).SetName("app2")
m2.Handle(new(testApplicationDependency))
e := httptest.New(t, app)
e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal("app1")
e.GET("/other").Expect().Status(httptest.StatusOK).Body().Equal("app2")
}
// Authenticated type.
type Authenticated int64
// BasePrivateController base controller for private controllers.
type BasePrivateController struct {
CurrentUserID Authenticated
Ctx iris.Context // not-used.
}
type publicController struct {
Ctx iris.Context // not-used.
}
func (c *publicController) Get() iris.Map {
return iris.Map{"data": "things"}
}
type privateController struct{ BasePrivateController }
func (c *privateController) Get() iris.Map {
return iris.Map{"id": c.CurrentUserID}
}
func TestControllerOverlapping(t *testing.T) {
app := iris.New()
m := New(app)
m.Router.SetRegisterRule(iris.RouteOverlap)
m.Register(func(ctx iris.Context) Authenticated {
if ctx.URLParam("name") == "kataras" {
return 1
}
ctx.StopWithStatus(iris.StatusForbidden)
return -1
})
// Order matters.
m.Handle(new(privateController))
m.Handle(new(publicController))
e := httptest.New(t, app)
e.GET("/").WithQuery("name", "kataras").Expect().Status(httptest.StatusOK).
JSON().Equal(iris.Map{"id": 1})
e.GET("/").Expect().Status(httptest.StatusOK).
JSON().Equal(iris.Map{"data": "things"})
}
type testControllerMethodHandlerBindStruct struct{}
type bindStructData struct {
Name string `json:"name" url:"name"`
}
func (*testControllerMethodHandlerBindStruct) Any(data bindStructData) bindStructData {
return data
}
func (*testControllerMethodHandlerBindStruct) PostBySlice(id uint64, manyData []bindStructData) []bindStructData {
return manyData
}
type dataSlice []bindStructData
func (*testControllerMethodHandlerBindStruct) PostBySlicetype(id uint64, manyData dataSlice) dataSlice {
return manyData
}
type dataSlicePtr []*bindStructData
func (*testControllerMethodHandlerBindStruct) PostBySlicetypeptr(id uint64, manyData dataSlicePtr) dataSlicePtr {
return manyData
}
func TestControllerMethodHandlerBindStruct(t *testing.T) {
app := iris.New()
m := New(app.Party("/data"))
m.HandleError(func(ctx iris.Context, err error) {
t.Fatalf("Path: %s, Error: %v", ctx.Path(), err)
})
m.Handle(new(testControllerMethodHandlerBindStruct))
data := bindStructData{Name: "kataras"}
manyData := []bindStructData{data, {"john doe"}}
e := httptest.New(t, app)
e.GET("/data").WithQueryObject(data).Expect().Status(httptest.StatusOK).JSON().Equal(data)
e.PATCH("/data").WithJSON(data).Expect().Status(httptest.StatusOK).JSON().Equal(data)
e.POST("/data/42/slice").WithJSON(manyData).Expect().Status(httptest.StatusOK).JSON().Equal(manyData)
e.POST("/data/42/slicetype").WithJSON(manyData).Expect().Status(httptest.StatusOK).JSON().Equal(manyData)
e.POST("/data/42/slicetypeptr").WithJSON(manyData).Expect().Status(httptest.StatusOK).JSON().Equal(manyData)
// more tests inside the hero package itself.
}

View File

@@ -4,7 +4,7 @@ import (
"net/http"
"path"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/context"
)
// GRPC registers a controller which serves gRPC clients.

View File

@@ -4,10 +4,10 @@ import (
"reflect"
"strings"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/hero"
"github.com/kataras/iris/v12/websocket"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/router"
"github.com/kataras/iris/hero"
"github.com/kataras/iris/websocket"
"github.com/kataras/golog"
)

View File

@@ -1,9 +1,9 @@
package mvc
import (
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router"
"github.com/kataras/iris/v12/versioning"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/router"
"github.com/kataras/iris/versioning"
)
// Version returns a valid `Option` that can be passed to the `Application.Handle` method.