mirror of
https://github.com/MontFerret/ferret.git
synced 2025-11-06 08:39:09 +02:00
#11 Added params
This commit is contained in:
@@ -1718,24 +1718,80 @@ func TestForTernaryExpression(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestHtml(t *testing.T) {
|
||||
Convey("Should load a document", t, func() {
|
||||
c := compiler.New()
|
||||
func TestParam(t *testing.T) {
|
||||
Convey("Should be possible to use as a return value", t, func() {
|
||||
out := compiler.New().
|
||||
MustCompile(`
|
||||
RETURN @param
|
||||
`).
|
||||
MustRun(context.Background(), runtime.WithParam("param", "foobar"))
|
||||
|
||||
out, err := c.MustCompile(`
|
||||
LET doc = DOCUMENT("https://github.com/", true)
|
||||
LET btn = ELEMENT(doc, ".HeaderMenu a")
|
||||
So(string(out), ShouldEqual, `"foobar"`)
|
||||
})
|
||||
|
||||
CLICK(btn)
|
||||
WAIT_NAVIGATION(doc)
|
||||
WAIT_ELEMENT(doc, '.IconNav')
|
||||
Convey("Should be possible to use as a FOR source", t, func() {
|
||||
out := compiler.New().
|
||||
MustCompile(`
|
||||
FOR i IN @values
|
||||
SORT i
|
||||
RETURN i
|
||||
`).
|
||||
MustRun(context.Background(), runtime.WithParam("values", []int{1, 2, 3, 4}))
|
||||
|
||||
RETURN INNER_HTML_ALL(doc, '.IconNav a')
|
||||
So(string(out), ShouldEqual, `[1,2,3,4]`)
|
||||
|
||||
`).Run(context.Background())
|
||||
out2 := compiler.New().
|
||||
MustCompile(`
|
||||
FOR i IN @values
|
||||
SORT i
|
||||
RETURN i
|
||||
`).
|
||||
MustRun(context.Background(), runtime.WithParam("values", map[string]int{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"faz": 3,
|
||||
"qaz": 4,
|
||||
}))
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(string(out2), ShouldEqual, `[1,2,3,4]`)
|
||||
})
|
||||
|
||||
Convey("Should be possible to use in range", t, func() {
|
||||
out := compiler.New().
|
||||
MustCompile(`
|
||||
FOR i IN @start..@end
|
||||
SORT i
|
||||
RETURN i
|
||||
`).
|
||||
MustRun(
|
||||
context.Background(),
|
||||
runtime.WithParam("start", 1),
|
||||
runtime.WithParam("end", 4),
|
||||
)
|
||||
|
||||
So(string(out), ShouldEqual, `[1,2,3,4]`)
|
||||
|
||||
So(string(out), ShouldEqual, `"int"`)
|
||||
})
|
||||
}
|
||||
|
||||
func TestHtml(t *testing.T) {
|
||||
// Convey("Should load a document", t, func() {
|
||||
// c := compiler.New()
|
||||
//
|
||||
// out, err := c.MustCompile(`
|
||||
//LET doc = DOCUMENT("https://github.com/", true)
|
||||
//LET btn = ELEMENT(doc, ".HeaderMenu a")
|
||||
//
|
||||
//CLICK(btn)
|
||||
//WAIT_NAVIGATION(doc)
|
||||
//WAIT_ELEMENT(doc, '.IconNav')
|
||||
//
|
||||
//RETURN INNER_HTML_ALL(doc, '.IconNav a')
|
||||
//
|
||||
// `).Run(context.Background())
|
||||
//
|
||||
// So(err, ShouldBeNil)
|
||||
//
|
||||
// So(string(out), ShouldEqual, `"int"`)
|
||||
// })
|
||||
}
|
||||
|
||||
@@ -406,6 +406,12 @@ func (v *visitor) doVisitForExpressionSource(ctx *fql.ForExpressionSourceContext
|
||||
return v.doVisitRangeOperator(rangeOp.(*fql.RangeOperatorContext), scope)
|
||||
}
|
||||
|
||||
param := ctx.Param()
|
||||
|
||||
if param != nil {
|
||||
return v.doVisitParamContext(param.(*fql.ParamContext), scope)
|
||||
}
|
||||
|
||||
return nil, core.Error(ErrInvalidDataSource, ctx.GetText())
|
||||
}
|
||||
|
||||
@@ -684,32 +690,62 @@ func (v *visitor) doVisitRangeOperator(ctx *fql.RangeOperatorContext, scope *sco
|
||||
)
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitChildren(node antlr.RuleNode, scope *scope) ([]core.Expression, error) {
|
||||
children := node.GetChildren()
|
||||
func (v *visitor) doVisitFunctionCallExpression(context *fql.FunctionCallExpressionContext, scope *scope) (collections.IterableExpression, error) {
|
||||
args := make([]core.Expression, 0, 5)
|
||||
argsCtx := context.Arguments()
|
||||
|
||||
if children == nil {
|
||||
return make([]core.Expression, 0, 0), nil
|
||||
if argsCtx != nil {
|
||||
argsCtx := argsCtx.(*fql.ArgumentsContext)
|
||||
|
||||
for _, arg := range argsCtx.AllExpression() {
|
||||
exp, err := v.doVisitExpression(arg.(*fql.ExpressionContext), scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args = append(args, exp)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]core.Expression, 0, len(children))
|
||||
funcName := context.Identifier().GetText()
|
||||
|
||||
for _, child := range children {
|
||||
_, ok := child.(antlr.TerminalNode)
|
||||
fun, exists := v.funcs[funcName]
|
||||
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
if !exists {
|
||||
return nil, core.Error(core.ErrNotFound, fmt.Sprintf("function: '%s'", funcName))
|
||||
}
|
||||
|
||||
out, err := v.visit(child, scope)
|
||||
return expressions.NewFunctionCallExpression(
|
||||
v.getSourceMap(context),
|
||||
fun,
|
||||
args...,
|
||||
)
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitParamContext(context *fql.ParamContext, scope *scope) (collections.IterableExpression, error) {
|
||||
name := context.Identifier().GetText()
|
||||
|
||||
return expressions.NewParameterExpression(
|
||||
v.getSourceMap(context),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitAllExpressions(contexts []fql.IExpressionContext, scope *scope) ([]core.Expression, error) {
|
||||
ret := make([]core.Expression, 0, len(contexts))
|
||||
|
||||
for _, ctx := range contexts {
|
||||
exp, err := v.doVisitExpression(ctx.(*fql.ExpressionContext), scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, out)
|
||||
ret = append(ret, exp)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitExpression(ctx *fql.ExpressionContext, scope *scope) (core.Expression, error) {
|
||||
@@ -882,77 +918,42 @@ func (v *visitor) doVisitExpression(ctx *fql.ExpressionContext, scope *scope) (c
|
||||
return v.doVisitRangeOperator(rangeOp.(*fql.RangeOperatorContext), scope)
|
||||
}
|
||||
|
||||
param := ctx.Param()
|
||||
|
||||
if param != nil {
|
||||
return v.doVisitParamContext(param.(*fql.ParamContext), scope)
|
||||
}
|
||||
|
||||
// TODO: Complete it
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitAllExpressions(contexts []fql.IExpressionContext, scope *scope) ([]core.Expression, error) {
|
||||
ret := make([]core.Expression, 0, len(contexts))
|
||||
func (v *visitor) doVisitChildren(node antlr.RuleNode, scope *scope) ([]core.Expression, error) {
|
||||
children := node.GetChildren()
|
||||
|
||||
for _, ctx := range contexts {
|
||||
exp, err := v.doVisitExpression(ctx.(*fql.ExpressionContext), scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret = append(ret, exp)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (v *visitor) doVisitFunctionCallExpression(context *fql.FunctionCallExpressionContext, scope *scope) (collections.IterableExpression, error) {
|
||||
args := make([]core.Expression, 0, 5)
|
||||
argsCtx := context.Arguments()
|
||||
|
||||
if argsCtx != nil {
|
||||
argsCtx := argsCtx.(*fql.ArgumentsContext)
|
||||
|
||||
for _, arg := range argsCtx.AllExpression() {
|
||||
exp, err := v.doVisitExpression(arg.(*fql.ExpressionContext), scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args = append(args, exp)
|
||||
}
|
||||
}
|
||||
|
||||
funcName := context.Identifier().GetText()
|
||||
|
||||
fun, exists := v.funcs[funcName]
|
||||
|
||||
if !exists {
|
||||
return nil, core.Error(core.ErrNotFound, fmt.Sprintf("function: '%s'", funcName))
|
||||
}
|
||||
|
||||
return expressions.NewFunctionCallExpression(
|
||||
v.getSourceMap(context),
|
||||
fun,
|
||||
args...,
|
||||
)
|
||||
}
|
||||
|
||||
func (v *visitor) visitAll(nodes []antlr.Tree, scope *scope) ([]core.Expression, error) {
|
||||
if nodes == nil {
|
||||
if children == nil {
|
||||
return make([]core.Expression, 0, 0), nil
|
||||
}
|
||||
|
||||
res := make([]core.Expression, 0, len(nodes))
|
||||
result := make([]core.Expression, 0, len(children))
|
||||
|
||||
for idx, node := range nodes {
|
||||
out, err := v.visit(node, scope)
|
||||
for _, child := range children {
|
||||
_, ok := child.(antlr.TerminalNode)
|
||||
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
out, err := v.visit(child, scope)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res[idx] = out
|
||||
result = append(result, out)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (v *visitor) visit(node antlr.Tree, scope *scope) (core.Expression, error) {
|
||||
@@ -988,6 +989,8 @@ func (v *visitor) visit(node antlr.Tree, scope *scope) (core.Expression, error)
|
||||
out, err = v.doVisitVariableDeclaration(node.(*fql.VariableDeclarationContext), scope)
|
||||
case *fql.FunctionCallExpressionContext:
|
||||
out, err = v.doVisitFunctionCallExpression(node.(*fql.FunctionCallExpressionContext), scope)
|
||||
case *fql.ParamContext:
|
||||
out, err = v.doVisitParamContext(node.(*fql.ParamContext), scope)
|
||||
default:
|
||||
err = v.unexpectedToken(node)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user