Skip to content

Commit

Permalink
Assert caching, lifting parser works within CEL
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyhb committed Jan 5, 2024
1 parent b1b4210 commit 65b33c4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
14 changes: 13 additions & 1 deletion expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ func (a *aggregator) Add(ctx context.Context, eval Evaluable) (bool, error) {
return false, err
}

// NOTE: When modifying, ensure that Remove() is updated. We should reconcile
// the core loops to use the same code.

aggregateable := true
for _, g := range parsed.RootGroups() {
ok, err := a.addGroup(ctx, g, parsed)
Expand Down Expand Up @@ -297,7 +300,16 @@ func (a *aggregator) addNode(ctx context.Context, n *Node, gid groupID, parsed *
}

func (a *aggregator) Remove(ctx context.Context, eval Evaluable) error {
// TODO
// parse the expression using our tree parser.
parsed, err := a.parser.Parse(ctx, eval)
if err != nil {
return err
}

for _, g := range parsed.RootGroups() {
_ = g
}

return fmt.Errorf("not implemented")
}

Expand Down
4 changes: 2 additions & 2 deletions lift.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
const (
// VarPrefix is the lifted variable name used when extracting idents from an
// expression.
VarPrefix = "vars."
VarPrefix = "vars"
)

var (
Expand Down Expand Up @@ -97,7 +97,7 @@ func (l *liftParser) addLiftedVar(val argMapValue) {
l.vars.vars[letter] = val
l.varCounter++

l.rewritten.WriteString(VarPrefix + letter)
l.rewritten.WriteString(VarPrefix + "." + letter)
}

func (l *liftParser) consumeString(quoteChar byte) argMapValue {
Expand Down
4 changes: 2 additions & 2 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ func callToPredicate(item celast.Expr, negated bool, vars LiftedArgs) *Predicate
}

if aIsVar && vars != nil {
if val, ok := vars.Get(strings.TrimPrefix(identA, VarPrefix)); ok {
if val, ok := vars.Get(strings.TrimPrefix(identA, VarPrefix+".")); ok {
// Normalize.
literal = val
identA = identB
Expand All @@ -549,7 +549,7 @@ func callToPredicate(item celast.Expr, negated bool, vars LiftedArgs) *Predicate
}

if bIsVar && vars != nil {
if val, ok := vars.Get(strings.TrimPrefix(identB, VarPrefix)); ok {
if val, ok := vars.Get(strings.TrimPrefix(identB, VarPrefix+".")); ok {
// Normalize.
literal = val
identB = ""
Expand Down
45 changes: 45 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,51 @@ func TestParse_LiftedVars(t *testing.T) {
})
}

// TestParsedCELAST tests the CachingParser as a CEL parser, ensuring that complex expressions
// can be evaluated using CEL when parsed.
func TestParsedCELAST(t *testing.T) {
env := newEnv()

p := NewCachingParser(env, nil)

ast, iss, args := p.Parse("event.data.id == 'ok'")
require.Nil(t, iss)
require.EqualValues(t, map[string]any{"a": "ok"}, args.Map())

program, err := env.Program(
ast,
cel.EvalOptions(cel.OptExhaustiveEval, cel.OptTrackState, cel.OptPartialEval),
)
require.NoError(t, err)

t.Run("It returns true with a matching expression", func(t *testing.T) {
result, _, err := program.Eval(map[string]any{
"event": map[string]any{
"data": map[string]any{
"id": "ok",
},
},
"vars": args.Map(),
})
require.NoError(t, err)
require.EqualValues(t, result, true)
})

t.Run("It returns false with an invalid expression", func(t *testing.T) {
result, _, err := program.Eval(map[string]any{
"event": map[string]any{
"data": map[string]any{
"id": "no",
},
},
"vars": args.Map(),
})
require.NoError(t, err)
require.EqualValues(t, result, false)
})

}

func TestRootGroups(t *testing.T) {
r := require.New(t)
ctx := context.Background()
Expand Down

0 comments on commit 65b33c4

Please sign in to comment.