mirror of
https://github.com/kataras/iris.git
synced 2025-02-09 18:46:19 +01:00
_future
Former-commit-id: c6f2c47cece55865b381df33950e6dfd8ccf882f
This commit is contained in:
parent
a95a02a16a
commit
251eeb6bd0
|
@ -41,7 +41,7 @@ app.Int.Set("min", minValidator)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
isVersionStrValidator := func() func(string) bool {
|
isVersionStrValidator := func() func(string) bool {
|
||||||
versions := []string("v1","v2")
|
versions := []string{"v1","v2"}
|
||||||
return func(paramValue string) bool {
|
return func(paramValue string) bool {
|
||||||
for _, s := range versions {
|
for _, s := range versions {
|
||||||
if s == paramValue {
|
if s == paramValue {
|
||||||
|
|
|
@ -11,14 +11,14 @@ const (
|
||||||
// /myparam
|
// /myparam
|
||||||
ParamTypeAlphabetical
|
ParamTypeAlphabetical
|
||||||
// /myparam1/myparam2
|
// /myparam1/myparam2
|
||||||
ParamPath
|
ParamTypePath
|
||||||
)
|
)
|
||||||
|
|
||||||
var paramTypes = map[string]ParamType{
|
var paramTypes = map[string]ParamType{
|
||||||
"int": ParamTypeInt,
|
"int": ParamTypeInt,
|
||||||
"string": ParamTypeString,
|
"string": ParamTypeString,
|
||||||
"alphabetical": ParamTypeAlphabetical,
|
"alphabetical": ParamTypeAlphabetical,
|
||||||
"path": ParamPath,
|
"path": ParamTypePath,
|
||||||
// could be named also:
|
// could be named also:
|
||||||
// "tail":
|
// "tail":
|
||||||
// "wild"
|
// "wild"
|
||||||
|
|
|
@ -2,6 +2,7 @@ package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/kataras/iris.v6/_future/ipel/ast"
|
"gopkg.in/kataras/iris.v6/_future/ipel/ast"
|
||||||
|
@ -26,8 +27,20 @@ func (p *Parser) appendErr(format string, a ...interface{}) {
|
||||||
p.errors = append(p.errors, fmt.Sprintf(format, a...))
|
p.errors = append(p.errors, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DefaultParamErrorCode = 404
|
||||||
|
|
||||||
|
func parseParamFuncArg(t token.Token) (a ast.ParamFuncArg, err error) {
|
||||||
|
if t.Type == token.INT {
|
||||||
|
return ast.ParamFuncArgToInt(t.Literal)
|
||||||
|
}
|
||||||
|
return t.Literal, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Parser) Parse() (*ast.ParamStatement, error) {
|
func (p *Parser) Parse() (*ast.ParamStatement, error) {
|
||||||
stmt := new(ast.ParamStatement)
|
stmt := new(ast.ParamStatement)
|
||||||
|
stmt.ErrorCode = DefaultParamErrorCode
|
||||||
|
// let's have them nilled stmt.Funcs = make([]ast.ParamFunc, 0)
|
||||||
|
lastParamFunc := ast.ParamFunc{}
|
||||||
for {
|
for {
|
||||||
t := p.l.NextToken()
|
t := p.l.NextToken()
|
||||||
if t.Type == token.EOF {
|
if t.Type == token.EOF {
|
||||||
|
@ -45,11 +58,52 @@ func (p *Parser) Parse() (*ast.ParamStatement, error) {
|
||||||
paramType := ast.LookupParamType(nextTok.Literal)
|
paramType := ast.LookupParamType(nextTok.Literal)
|
||||||
if paramType == ast.ParamTypeUnExpected {
|
if paramType == ast.ParamTypeUnExpected {
|
||||||
p.appendErr("[%d:%d] unexpected parameter type: %s", t.Start, t.End, nextTok.Literal)
|
p.appendErr("[%d:%d] unexpected parameter type: %s", t.Start, t.End, nextTok.Literal)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
stmt.Type = paramType
|
||||||
|
// param func
|
||||||
|
case token.IDENT:
|
||||||
|
lastParamFunc.Name = t.Literal
|
||||||
|
case token.LPAREN:
|
||||||
|
argValTok := p.l.NextToken()
|
||||||
|
argVal, err := parseParamFuncArg(argValTok)
|
||||||
|
if err != nil {
|
||||||
|
p.appendErr("[%d:%d] expected param func argument to be an integer but got %s", t.Start, t.End, argValTok.Literal)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
lastParamFunc.Args = append(lastParamFunc.Args, argVal)
|
||||||
|
case token.COMMA:
|
||||||
|
argValTok := p.l.NextToken()
|
||||||
|
argVal, err := parseParamFuncArg(argValTok)
|
||||||
|
if err != nil {
|
||||||
|
p.appendErr("[%d:%d] expected param func argument to be an integer but got %s", t.Start, t.End, argValTok.Literal)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
lastParamFunc.Args = append(lastParamFunc.Args, argVal)
|
||||||
|
case token.RPAREN:
|
||||||
|
stmt.Funcs = append(stmt.Funcs, lastParamFunc)
|
||||||
|
lastParamFunc = ast.ParamFunc{} // reset
|
||||||
|
case token.ELSE:
|
||||||
|
errCodeTok := p.l.NextToken()
|
||||||
|
if errCodeTok.Type != token.INT {
|
||||||
|
p.appendErr("[%d:%d] expected error code to be an integer but got %s", t.Start, t.End, errCodeTok.Literal)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
errCode, err := strconv.Atoi(errCodeTok.Literal)
|
||||||
|
if err != nil {
|
||||||
|
// this is a bug on lexer if throws because we already check for token.INT
|
||||||
|
p.appendErr("[%d:%d] unexpected lexer error while trying to convert error code to an integer, %s", t.Start, t.End, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stmt.ErrorCode = errCode
|
||||||
|
case token.RBRACE:
|
||||||
|
break
|
||||||
case token.ILLEGAL:
|
case token.ILLEGAL:
|
||||||
p.appendErr("[%d:%d] illegal token: %s", t.Start, t.End, t.Literal)
|
p.appendErr("[%d:%d] illegal token: %s", t.Start, t.End, t.Literal)
|
||||||
default:
|
default:
|
||||||
p.appendErr("[%d:%d] unexpected token type: %q", t.Start, t.End, t.Type)
|
p.appendErr("[%d:%d] unexpected token type: %q with value %s", t.Start, t.End, t.Type, t.Literal)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@ package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gopkg.in/kataras/iris.v6/_future/ipel/ast"
|
||||||
"gopkg.in/kataras/iris.v6/_future/ipel/lexer"
|
"gopkg.in/kataras/iris.v6/_future/ipel/lexer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test is failing because we are not finished with the Parser yet
|
|
||||||
// 27/03
|
|
||||||
func TestParseError(t *testing.T) {
|
func TestParseError(t *testing.T) {
|
||||||
// fail
|
// fail
|
||||||
illegalChar := '$'
|
illegalChar := '$'
|
||||||
|
@ -46,3 +46,79 @@ func TestParseError(t *testing.T) {
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
valid bool
|
||||||
|
expectedStatement ast.ParamStatement
|
||||||
|
}{
|
||||||
|
{"{id:int min(1) max(5) else 404}", true,
|
||||||
|
ast.ParamStatement{
|
||||||
|
Name: "id",
|
||||||
|
Type: ast.ParamTypeInt,
|
||||||
|
Funcs: []ast.ParamFunc{
|
||||||
|
ast.ParamFunc{
|
||||||
|
Name: "min",
|
||||||
|
Args: []ast.ParamFuncArg{1}},
|
||||||
|
ast.ParamFunc{
|
||||||
|
Name: "max",
|
||||||
|
Args: []ast.ParamFuncArg{5}},
|
||||||
|
},
|
||||||
|
ErrorCode: 404,
|
||||||
|
}}, // 0
|
||||||
|
{"{id:int range(1,5)}", true,
|
||||||
|
ast.ParamStatement{
|
||||||
|
Name: "id",
|
||||||
|
Type: ast.ParamTypeInt,
|
||||||
|
Funcs: []ast.ParamFunc{
|
||||||
|
ast.ParamFunc{
|
||||||
|
Name: "range",
|
||||||
|
Args: []ast.ParamFuncArg{1, 5}},
|
||||||
|
},
|
||||||
|
ErrorCode: 404,
|
||||||
|
}}, // 1
|
||||||
|
{"{file:path contains(.)}", true,
|
||||||
|
ast.ParamStatement{
|
||||||
|
Name: "file",
|
||||||
|
Type: ast.ParamTypePath,
|
||||||
|
Funcs: []ast.ParamFunc{
|
||||||
|
ast.ParamFunc{
|
||||||
|
Name: "contains",
|
||||||
|
Args: []ast.ParamFuncArg{"."}},
|
||||||
|
},
|
||||||
|
ErrorCode: 404,
|
||||||
|
}}, // 2
|
||||||
|
{"{username:alphabetical", true,
|
||||||
|
ast.ParamStatement{
|
||||||
|
Name: "username",
|
||||||
|
Type: ast.ParamTypeAlphabetical,
|
||||||
|
ErrorCode: 404,
|
||||||
|
}}, // 3
|
||||||
|
{"{username:thisianunexpected", false,
|
||||||
|
ast.ParamStatement{
|
||||||
|
Name: "username",
|
||||||
|
Type: ast.ParamTypeUnExpected,
|
||||||
|
ErrorCode: 404,
|
||||||
|
}}, // 4
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
l := lexer.New(tt.input)
|
||||||
|
p := New(l)
|
||||||
|
resultStmt, err := p.Parse()
|
||||||
|
|
||||||
|
if tt.valid && err != nil {
|
||||||
|
t.Fatalf("tests[%d] - error %s", i, err.Error())
|
||||||
|
} else if !tt.valid && err == nil {
|
||||||
|
t.Fatalf("tests[%d] - expected to be a failure", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resultStmt != nil { // is valid here
|
||||||
|
if !reflect.DeepEqual(tt.expectedStatement, *resultStmt) {
|
||||||
|
t.Fatalf("tests[%d] - wrong statement, expected and result differs. Details:\n%#v\n%#v", i, tt.expectedStatement, *resultStmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user