...
1 package exec
2
3 import (
4 "github.com/pkg/errors"
5
6 "github.com/noirbizarre/gonja/nodes"
7 )
8
9
10 type TestFunction func(*Context, *Value, *VarArgs) (bool, error)
11
12
13 type TestSet map[string]TestFunction
14
15
16 func (ts TestSet) Exists(name string) bool {
17 _, existing := ts[name]
18 return existing
19 }
20
21
22
23
24
25
26
27
28 func (ts *TestSet) Register(name string, fn TestFunction) error {
29 if ts.Exists(name) {
30 return errors.Errorf("test with name '%s' is already registered", name)
31 }
32 (*ts)[name] = fn
33 return nil
34 }
35
36
37
38 func (ts *TestSet) Replace(name string, fn TestFunction) error {
39 if !ts.Exists(name) {
40 return errors.Errorf("test with name '%s' does not exist (therefore cannot be overridden)", name)
41 }
42 (*ts)[name] = fn
43 return nil
44 }
45
46 func (ts *TestSet) Update(other TestSet) TestSet {
47 for name, test := range other {
48 (*ts)[name] = test
49 }
50 return *ts
51 }
52
53 func (e *Evaluator) EvalTest(expr *nodes.TestExpression) *Value {
54 value := e.Eval(expr.Expression)
55
56
57
58
59 return e.ExecuteTest(expr.Test, value)
60 }
61
62 func (e *Evaluator) ExecuteTest(tc *nodes.TestCall, v *Value) *Value {
63 params := &VarArgs{
64 Args: []*Value{},
65 KwArgs: map[string]*Value{},
66 }
67
68 for _, param := range tc.Args {
69 value := e.Eval(param)
70 if value.IsError() {
71 return AsValue(errors.Wrapf(value, `Unable to evaluate parameter %s`, param))
72 }
73 params.Args = append(params.Args, value)
74 }
75
76 for key, param := range tc.Kwargs {
77 value := e.Eval(param)
78 if value.IsError() {
79 return AsValue(errors.Wrapf(value, `Unable to evaluate parameter %s`, param))
80 }
81 params.KwArgs[key] = value
82 }
83
84 return e.ExecuteTestByName(tc.Name, v, params)
85 }
86
87 func (e *Evaluator) ExecuteTestByName(name string, in *Value, params *VarArgs) *Value {
88 if !e.Tests.Exists(name) {
89 return AsValue(errors.Errorf(`Test "%s" not found`, name))
90 }
91 test, _ := (*e.Tests)[name]
92
93 result, err := test(e.Ctx, in, params)
94 if err != nil {
95 return AsValue(errors.Wrapf(err, `Unable to execute test %s`, name))
96 } else {
97 return AsValue(result)
98 }
99 }
100
View as plain text