_future | macro func test passed

Former-commit-id: e5ec3ce865069c0236e8398dbf5ed2805437fce1
This commit is contained in:
Gerasimos (Makis) Maropoulos 2017-03-21 01:26:54 +02:00
parent db22de4b92
commit 251cc93c7d

View File

@ -4,11 +4,12 @@
// The whole "router" package is a temp place to test my ideas and implementations for future iris' features. // The whole "router" package is a temp place to test my ideas and implementations for future iris' features.
// Young developers can understand and see how ideas can be transform to real implementations on a software like Iris, // Young developers can understand and see how ideas can be transform to real implementations on a software like Iris,
// watching the history of a "dirty" code can be useful for some of you. // watching the history of a "dirty" code can be useful for some of you.
//
package router package router
import ( import (
"regexp" "regexp"
"strconv"
"testing" "testing"
"gopkg.in/kataras/iris.v6" "gopkg.in/kataras/iris.v6"
@ -16,9 +17,6 @@ import (
"gopkg.in/kataras/iris.v6/httptest" "gopkg.in/kataras/iris.v6/httptest"
) )
// macros should be registered before .Listen
type _macros map[string]func(string) bool
// a helper to return a macro from a simple regexp // a helper to return a macro from a simple regexp
// it compiles the regexp and after returns the macro, for obviously performance reasons. // it compiles the regexp and after returns the macro, for obviously performance reasons.
func fromRegexp(expr string) func(paramValue string) bool { func fromRegexp(expr string) func(paramValue string) bool {
@ -35,7 +33,6 @@ func fromRegexp(expr string) func(paramValue string) bool {
if err != nil { if err != nil {
panic(err) panic(err)
} }
return r.MatchString return r.MatchString
} }
@ -58,16 +55,17 @@ func link(path string, mac _macros) iris.HandlerFunc {
if prevH != nil { if prevH != nil {
prevH(ctx) prevH(ctx)
} }
paramValue := ctx.Param(paramName) paramValue := ctx.Param(paramName)
if paramValue != "" { if paramValue != "" {
valid := validator(paramValue) valid := validator(paramValue)
if !valid { if !valid {
print("not valid for validator on paramValue= '" + paramValue + "' ctx.Pos = ")
println(ctx.Pos) // it should be always 0.
ctx.EmitError(failStatus) ctx.EmitError(failStatus)
return return
} }
} }
// println(ctx.Pos) println(ctx.Pos)
// remember: router already matches the path, so here if a path param is missing then it was allowed by the router. // remember: router already matches the path, so here if a path param is missing then it was allowed by the router.
ctx.Next() ctx.Next()
} }
@ -75,9 +73,36 @@ func link(path string, mac _macros) iris.HandlerFunc {
for i := range tmpl.Params { for i := range tmpl.Params {
p := tmpl.Params[i] p := tmpl.Params[i]
if m := mac[p.Param.Macro.Name]; m != nil { if m, found := mac[p.Param.Macro.Name]; found && m.eval != nil {
prevH := h prevH := h
h = createH(p.Param.Name, m, p.Param.FailStatusCode, prevH) eval := m.eval
for _, fi := range m.funcs {
println("details for: " + fi.name)
println("m.funcs len = ")
print(len(m.funcs))
println("vs tmpl macro's funcs len = ")
print(len(p.Param.Macro.Funcs))
println()
for _, mi := range p.Param.Macro.Funcs {
if fi.name == mi.Name {
println(fi.name + " matches with pathtmpl macro func: " + mi.Name)
prevEval := eval
macroFuncEval := fi.eval(mi.Params)
eval = func(pvalue string) bool {
if prevEval(pvalue) {
return macroFuncEval(pvalue)
}
return false
}
continue
}
println("fi.name = " + fi.name + " | mi.Name = " + mi.Name)
}
}
h = createH(p.Param.Name, eval, p.Param.FailStatusCode, prevH)
} }
} }
@ -108,15 +133,75 @@ func testMacros(source string) error {
return nil return nil
} }
func TestMacros(t *testing.T) { type _macrofunc struct {
var m = _macros{ name string
"int": fromRegexp("[1-9]+$"), eval func([]string) func(string) bool
}
type _macro struct {
funcs []_macrofunc
eval func(string) bool
}
// macros should be registered before .Listen
type _macros map[string]*_macro
var all_macros = _macros{}
func addMacro(name string, v func(string) bool) {
all_macros[name] = &_macro{eval: v}
}
func addMacroFunc(macroName string, funcName string, v func([]string) func(string) bool) {
if m, found := all_macros[macroName]; found {
m.funcs = append(m.funcs, _macrofunc{name: funcName, eval: v})
} }
path := "/api/users/{id:int}/posts" }
func TestMacros(t *testing.T) {
addMacro("int", fromRegexp("[1-9]+$"))
// {id:int range(42,49)}
addMacroFunc("int", "range", func(params []string) func(string) bool {
// start: .Boot time, before .Listen
allowedParamsLen := 2
// params: 42,49 (including first and second)
if len(params) != allowedParamsLen {
panic("range accepts two parameters")
}
min, err := strconv.Atoi(params[0])
if err != nil {
panic("invalid first parameter: " + err.Error())
}
max, err := strconv.Atoi(params[1])
if err != nil {
panic("invalid second parameter: " + err.Error())
}
// end
return func(paramValue string) bool {
paramValueInt, err := strconv.Atoi(paramValue)
if err != nil {
return false
}
print("min: ")
println(min)
print("max: ")
println(max)
print("value: ")
println(paramValueInt)
if paramValueInt >= min && paramValueInt <= max {
return true
}
return false
}
})
path := "/api/users/{id:int range(42,49)}/posts"
app := iris.New() app := iris.New()
app.Adapt(httprouter.New()) app.Adapt(httprouter.New())
hv := link(path, m) hv := link(path, all_macros)
app.Get("/api/users/:id/posts", hv, func(ctx *iris.Context) { app.Get("/api/users/:id/posts", hv, func(ctx *iris.Context) {
ctx.ResponseWriter.WriteString(ctx.Path()) ctx.ResponseWriter.WriteString(ctx.Path())
@ -125,8 +210,12 @@ func TestMacros(t *testing.T) {
e := httptest.New(app, t) e := httptest.New(app, t)
e.GET("/api/users/42/posts").Expect().Status(iris.StatusOK).Body().Equal("/api/users/42/posts") e.GET("/api/users/42/posts").Expect().Status(iris.StatusOK).Body().Equal("/api/users/42/posts")
e.GET("/api/users/50/posts").Expect().Status(iris.StatusNotFound) // remember, it accepts 1-9 not matched if zero.
e.GET("/api/users/0/posts").Expect().Status(iris.StatusNotFound) e.GET("/api/users/0/posts").Expect().Status(iris.StatusNotFound)
e.GET("/api/users/_/posts").Expect().Status(iris.StatusNotFound) e.GET("/api/users/_/posts").Expect().Status(iris.StatusNotFound)
e.GET("/api/users/s/posts").Expect().Status(iris.StatusNotFound) e.GET("/api/users/s/posts").Expect().Status(iris.StatusNotFound)
e.GET("/api/users/posts").Expect().Status(iris.StatusNotFound) e.GET("/api/users/posts").Expect().Status(iris.StatusNotFound)
// macro func invalidate test with a non-zero value between 1-9 but bigger than the max(49)
e.GET("/api/users/51/posts").Expect().Status(iris.StatusNotFound)
} }