Skip to content

Commit

Permalink
Add Eval/EvalBool as functions
Browse files Browse the repository at this point in the history
  • Loading branch information
lawrencewoodman committed Apr 28, 2017
1 parent eb19db3 commit 130fe7b
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
29 changes: 29 additions & 0 deletions dexpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ func MustNew(expr string, callFuncs map[string]CallFun) *Expr {
return e
}

// Eval compiles an expression and evaluates it with the supplied callFuncs
// and vars. Any errors produced will be encapsulated in the returned
// Literal.
func Eval(
expr string,
callFuncs map[string]CallFun,
vars map[string]*dlit.Literal,
) *dlit.Literal {
e, err := New(expr, callFuncs)
if err != nil {
return dlit.MustNew(err)
}
return e.Eval(vars)
}

// EvalBool compiles an expression and evaluates it with the supplied callFuncs
// and vars.
func EvalBool(
expr string,
callFuncs map[string]CallFun,
vars map[string]*dlit.Literal,
) (bool, error) {
e, err := New(expr, callFuncs)
if err != nil {
return false, err
}
return e.EvalBool(vars)
}

func (expr *Expr) Eval(vars map[string]*dlit.Literal) *dlit.Literal {
l := expr.Node.Eval(vars)
if err := l.Err(); err != nil {
Expand Down
58 changes: 58 additions & 0 deletions dexpr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,64 @@ func TestNew_errors(t *testing.T) {
}
}

func TestDexprEval(t *testing.T) {
expr := "roundto(bob, 2) + 7"
want := dlit.MustNew(26.12)
funcs := map[string]CallFun{"roundto": roundTo}
vars := map[string]*dlit.Literal{"bob": dlit.MustNew(19.1234)}
got := Eval(expr, funcs, vars)
if got.String() != want.String() {
t.Errorf("Eval: got: %s, want: %s", got, want)
}
}

func TestDexprEvalBool(t *testing.T) {
cases := []struct {
expr string
want bool
}{
{expr: "roundto(bob, 2) + 7 == 26.12", want: true},
{expr: "roundto(bob, 2) + 7 == 26.11", want: false},
}
for _, c := range cases {
funcs := map[string]CallFun{"roundto": roundTo}
vars := map[string]*dlit.Literal{"bob": dlit.MustNew(19.1234)}
got, err := EvalBool(c.expr, funcs, vars)
if got != c.want {
t.Errorf("Eval: got: %t, want: %t", got, c.want)
}
if err != nil {
t.Errorf("Eval: err: %s", err)
}
}
}

func TestDexprEval_errors(t *testing.T) {
expr := "7 {} 3"
wantErr := InvalidExprError{"7 {} 3", ErrSyntax}
funcs := map[string]CallFun{}
vars := map[string]*dlit.Literal{}
got := Eval(expr, funcs, vars)
if err := got.Err(); err == nil || err.Error() != wantErr.Error() {
t.Errorf("Eval: gotErr: %s, want: %s", err, wantErr)
}
}

func TestDexprEvalBool_errors(t *testing.T) {
expr := "7 {} 3"
want := false
wantErr := InvalidExprError{"7 {} 3", ErrSyntax}
funcs := map[string]CallFun{}
vars := map[string]*dlit.Literal{}
got, err := EvalBool(expr, funcs, vars)
if got != want {
t.Errorf("Eval: got: %t, want: %t", got, want)
}
if err == nil || err.Error() != wantErr.Error() {
t.Errorf("Eval: gotErr: %s, want: %s", err, wantErr)
}
}

func TestEval_noerrors(t *testing.T) {
cases := []struct {
in string
Expand Down

0 comments on commit 130fe7b

Please sign in to comment.