Extend grammar to support modules

This commit is contained in:
Peter 2021-05-02 12:31:31 +02:00
parent 8eb0bdbb54
commit 12da983bfc
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
2 changed files with 164 additions and 4 deletions

View file

@ -16,7 +16,8 @@ var (
func init() { func init() {
sqlLexer := lexer.Must(stateful.NewSimple([]stateful.Rule{ sqlLexer := lexer.Must(stateful.NewSimple([]stateful.Rule{
{Name: `Ident`, Pattern: `[a-zA-Z_][a-zA-Z0-9_]*`, Action: nil}, {Name: `Module`, Pattern: `[a-z]+`, Action: nil},
{Name: `Ident`, Pattern: `[A-Z][a-zA-Z0-9_]*`, Action: nil},
{Name: `Float`, Pattern: `\d+\.\d+`, Action: nil}, {Name: `Float`, Pattern: `\d+\.\d+`, Action: nil},
{Name: `Int`, Pattern: `[-]?\d+`, Action: nil}, {Name: `Int`, Pattern: `[-]?\d+`, Action: nil},
{Name: `String`, Pattern: `'[^']*'|"[^"]*"`, Action: nil}, {Name: `String`, Pattern: `'[^']*'|"[^"]*"`, Action: nil},
@ -50,8 +51,9 @@ type Filters struct {
} }
type Method struct { type Method struct {
Module string `parser:"(@Module'.')?"`
Name string `parser:"@Ident"` Name string `parser:"@Ident"`
Params []Param `parser:"'(' @@ ( ',' @@ )*')'"` Params []Param `parser:"'(' @@? ( ',' @@ )*')'"`
} }
type Param struct { type Param struct {

View file

@ -36,6 +36,57 @@ func TestParse(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "Terminator only - no argument",
args: args{
rule: `=> NoContent()`,
},
want: &Routing{
Terminator: &Method{
Name: "NoContent",
},
},
wantErr: false,
},
{
name: "Terminator with module - no argument",
args: args{
rule: `=> http.NoContent()`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "NoContent",
},
},
wantErr: false,
},
{
name: "Terminator only do not support method name not starting with capital letter",
args: args{
rule: `=> file("default.html")`,
},
want: nil,
wantErr: true,
},
{
name: "Terminator with module - string argument",
args: args{
rule: `=> http.File("default.html")`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "File",
Params: []Param{
{
String: stringRef("default.html"),
},
},
},
},
wantErr: false,
},
{ {
name: "Terminator only - int argument", name: "Terminator only - int argument",
args: args{ args: args{
@ -53,6 +104,24 @@ func TestParse(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "Terminator with module - int argument",
args: args{
rule: `=> http.ReturnInt(1)`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "ReturnInt",
Params: []Param{
{
Int: intRef(1),
},
},
},
},
wantErr: false,
},
{ {
name: "Terminator only - int argument, multiple digits", name: "Terminator only - int argument, multiple digits",
args: args{ args: args{
@ -70,6 +139,24 @@ func TestParse(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "Terminator with Module - int argument, multiple digits",
args: args{
rule: `=> http.ReturnInt(1337)`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "ReturnInt",
Params: []Param{
{
Int: intRef(1337),
},
},
},
},
wantErr: false,
},
{ {
name: "Terminator only - float argument", name: "Terminator only - float argument",
args: args{ args: args{
@ -116,10 +203,41 @@ func TestParse(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "path pattern and terminator with Modules",
args: args{
rule: `http.PathPattern(".*\\.(?i)png") => http.ReturnFile("default.html")`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "ReturnFile",
Params: []Param{
{
String: stringRef("default.html"),
},
},
},
Filters: &Filters{
Chain: []Method{
{
Module: "http",
Name: "PathPattern",
Params: []Param{
{
String: stringRef(`.*\.(?i)png`),
},
},
},
},
},
},
wantErr: false,
},
{ {
name: "HTTP method, path pattern and terminator", name: "HTTP method, path pattern and terminator",
args: args{ args: args{
rule: `HTTPMethod("GET") -> PathPattern("/index.html") => ReturnFile("default.html")`, rule: `Method("GET") -> PathPattern("/index.html") => ReturnFile("default.html")`,
}, },
want: &Routing{ want: &Routing{
Terminator: &Method{ Terminator: &Method{
@ -133,7 +251,7 @@ func TestParse(t *testing.T) {
Filters: &Filters{ Filters: &Filters{
Chain: []Method{ Chain: []Method{
{ {
Name: "HTTPMethod", Name: "Method",
Params: []Param{ Params: []Param{
{ {
String: stringRef(http.MethodGet), String: stringRef(http.MethodGet),
@ -153,6 +271,46 @@ func TestParse(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "HTTP method, path pattern and terminator with modules",
args: args{
rule: `http.Method("GET") -> http.PathPattern("/index.html") => http.ReturnFile("default.html")`,
},
want: &Routing{
Terminator: &Method{
Module: "http",
Name: "ReturnFile",
Params: []Param{
{
String: stringRef("default.html"),
},
},
},
Filters: &Filters{
Chain: []Method{
{
Module: "http",
Name: "Method",
Params: []Param{
{
String: stringRef(http.MethodGet),
},
},
},
{
Module: "http",
Name: "PathPattern",
Params: []Param{
{
String: stringRef("/index.html"),
},
},
},
},
},
},
wantErr: false,
},
} }
for _, tc := range tests { for _, tc := range tests {
tt := tc tt := tc