225 lines
5 KiB
Go
225 lines
5 KiB
Go
|
package grammar_test
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/maxatome/go-testdeep/td"
|
||
|
|
||
|
"github.com/baez90/nurse/grammar"
|
||
|
"github.com/baez90/nurse/internal/values"
|
||
|
)
|
||
|
|
||
|
var wantParsedScript = td.Struct(new(grammar.Script), td.StructFields{
|
||
|
"Checks": td.Bag(
|
||
|
grammar.Check{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Get",
|
||
|
Params: params(grammar.Param{String: values.StringP("https://www.gogol.com/")}),
|
||
|
},
|
||
|
Validators: &grammar.Filters{
|
||
|
Chain: []grammar.Call{
|
||
|
{
|
||
|
Name: "Status",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
Int: values.IntP(404),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
grammar.Check{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Get",
|
||
|
Params: params(grammar.Param{String: values.StringP("https://www.microsoft.com/")}),
|
||
|
},
|
||
|
Validators: &grammar.Filters{
|
||
|
Chain: []grammar.Call{
|
||
|
{
|
||
|
Name: "Status",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
Int: values.IntP(200),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Name: "Header",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
String: values.StringP("Content-Type"),
|
||
|
},
|
||
|
{
|
||
|
String: values.StringP("text/html"),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
),
|
||
|
})
|
||
|
|
||
|
func TestParser_Parse(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
rawRule string
|
||
|
want any
|
||
|
wantErr bool
|
||
|
}{
|
||
|
{
|
||
|
name: "Check - Initiator only - string argument",
|
||
|
rawRule: `http.Get("https://www.microsoft.com/")`,
|
||
|
want: &grammar.Script{
|
||
|
Checks: []grammar.Check{
|
||
|
{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Get",
|
||
|
Params: params(grammar.Param{String: values.StringP("https://www.microsoft.com/")}),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
{
|
||
|
name: "Check - Initiator only - raw string argument",
|
||
|
rawRule: "http.Post(\"https://www.microsoft.com/\", `{\"Name\":\"Ted.Tester\"}`)",
|
||
|
want: &grammar.Script{
|
||
|
Checks: []grammar.Check{
|
||
|
{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Post",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
String: values.StringP("https://www.microsoft.com/"),
|
||
|
},
|
||
|
{
|
||
|
String: values.StringP(`{"Name":"Ted.Tester"}`),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "Check - Initiator and single filter",
|
||
|
rawRule: `http.Get("https://www.microsoft.com/") => Status(200)`,
|
||
|
want: &grammar.Script{
|
||
|
Checks: []grammar.Check{
|
||
|
{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Get",
|
||
|
Params: params(grammar.Param{String: values.StringP("https://www.microsoft.com/")}),
|
||
|
},
|
||
|
Validators: &grammar.Filters{
|
||
|
Chain: []grammar.Call{
|
||
|
{
|
||
|
Name: "Status",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
Int: values.IntP(200),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "Check - Initiator and multiple filters",
|
||
|
rawRule: `http.Get("https://www.microsoft.com/") => Status(200) -> Header("Content-Type", "text/html")`,
|
||
|
want: &grammar.Script{
|
||
|
Checks: []grammar.Check{
|
||
|
{
|
||
|
Initiator: &grammar.Call{
|
||
|
Module: "http",
|
||
|
Name: "Get",
|
||
|
Params: params(grammar.Param{String: values.StringP("https://www.microsoft.com/")}),
|
||
|
},
|
||
|
Validators: &grammar.Filters{
|
||
|
Chain: []grammar.Call{
|
||
|
{
|
||
|
Name: "Status",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
Int: values.IntP(200),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Name: "Header",
|
||
|
Params: []grammar.Param{
|
||
|
{
|
||
|
String: values.StringP("Content-Type"),
|
||
|
},
|
||
|
{
|
||
|
String: values.StringP("text/html"),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "CheckScript without comments",
|
||
|
rawRule: `
|
||
|
http.Get("https://www.gogol.com/") => Status(404)
|
||
|
http.Get("https://www.microsoft.com/") => Status(200) -> Header("Content-Type", "text/html")
|
||
|
`,
|
||
|
want: wantParsedScript,
|
||
|
},
|
||
|
{
|
||
|
name: "CheckScript without comments - single line",
|
||
|
//nolint:lll // required at this point
|
||
|
rawRule: `http.Get("https://www.gogol.com/") => Status(404) http.Get("https://www.microsoft.com/") => Status(200) -> Header("Content-Type", "text/html")`,
|
||
|
want: wantParsedScript,
|
||
|
},
|
||
|
{
|
||
|
name: "CheckScript with comments",
|
||
|
rawRule: `
|
||
|
# GET https://www.gogol.com/ expect a not found response
|
||
|
http.Get("https://www.gogol.com/") => Status(404)
|
||
|
|
||
|
// GET https://www.microsoft.com/ - expect status OK and HTML content
|
||
|
http.Get("https://www.microsoft.com/") => Status(200) -> Header("Content-Type", "text/html")
|
||
|
`,
|
||
|
|
||
|
want: wantParsedScript,
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
tt := tt
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
p, err := grammar.NewParser[grammar.Script]()
|
||
|
if err != nil {
|
||
|
t.Fatalf("NewParser() err = %v", err)
|
||
|
}
|
||
|
|
||
|
got, err := p.Parse(tt.rawRule)
|
||
|
if err != nil {
|
||
|
if !tt.wantErr {
|
||
|
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
td.Cmp(t, got, tt.want)
|
||
|
})
|
||
|
}
|
||
|
}
|