use of org.projectnessie.cel.Env.AstIssuesTuple in project cel-java by projectnessie.
the class CELTest method AstToString.
@Test
void AstToString() {
Env stdEnv = newEnv();
String in = "a + b - (c ? (-d + 4) : e)";
AstIssuesTuple astIss = stdEnv.parse(in);
assertThat(astIss.hasIssues()).isFalse();
String expr = astToString(astIss.getAst());
assertThat(expr).isEqualTo(in);
}
use of org.projectnessie.cel.Env.AstIssuesTuple in project cel-java by projectnessie.
the class CELTest method HomogeneousAggregateLiterals.
@Test
void HomogeneousAggregateLiterals() {
Env e = newCustomEnv(declarations(Decls.newVar("name", Decls.String), Decls.newFunction(Operator.In.id, Decls.newOverload(Overloads.InList, asList(Decls.String, Decls.newListType(Decls.String)), Decls.Bool), Decls.newOverload(Overloads.InMap, asList(Decls.String, Decls.newMapType(Decls.String, Decls.Bool)), Decls.Bool))), homogeneousAggregateLiterals());
// t.Run("err_list", func(t *testing.T) {
AstIssuesTuple xIss = e.compile("name in ['hello', 0]");
assertThat(xIss.getIssues()).isNotNull();
assertThat(xIss.hasIssues()).isTrue();
// })
// t.Run("err_map_key", func(t *testing.T) {
xIss = e.compile("name in {'hello':'world', 1:'!'}");
assertThat(xIss.getIssues()).isNotNull();
assertThat(xIss.hasIssues()).isTrue();
// })
// t.Run("err_map_val", func(t *testing.T) {
xIss = e.compile("name in {'hello':'world', 'goodbye':true}");
assertThat(xIss.getIssues()).isNotNull();
assertThat(xIss.hasIssues()).isTrue();
// })
ProgramOption funcs = functions(Overload.binary(Operator.In.id, (lhs, rhs) -> {
if (rhs.type().hasTrait(Trait.ContainerType)) {
return ((Container) rhs).contains(lhs);
}
return valOrErr(rhs, "no such overload");
}));
// t.Run("ok_list", func(t *testing.T) {
AstIssuesTuple astIss = e.compile("name in ['hello', 'world']");
assertThat(astIss.hasIssues()).isFalse();
Program prg = e.program(astIss.getAst(), funcs);
EvalResult out = prg.eval(mapOf("name", "world"));
assertThat(out.getVal()).isSameAs(True);
// })
// t.Run("ok_map", func(t *testing.T) {
astIss = e.compile("name in {'hello': false, 'world': true}");
assertThat(astIss.hasIssues()).isFalse();
prg = e.program(astIss.getAst(), funcs);
out = prg.eval(mapOf("name", "world"));
assertThat(out.getVal()).isSameAs(True);
// })
}
use of org.projectnessie.cel.Env.AstIssuesTuple in project cel-java by projectnessie.
the class CELTest method CustomInterpreterDecorator.
@Test
void CustomInterpreterDecorator() {
AtomicReference<Interpretable> lastInstruction = new AtomicReference<>();
InterpretableDecorator optimizeArith = i -> {
lastInstruction.set(i);
// Only optimize the instruction if it is a call.
if (!(i instanceof InterpretableCall)) {
return i;
}
InterpretableCall call = (InterpretableCall) i;
// Only optimize the math functions when they have constant arguments.
switch(call.function()) {
case "_+_":
case "_-_":
case "_*_":
case "_/_":
// These are all binary operators so they should have to arguments
Interpretable[] args = call.args();
// an empty activation and the value returns as a constant.
if (!(args[0] instanceof InterpretableConst) || !(args[1] instanceof InterpretableConst)) {
return i;
}
Val val = call.eval(emptyActivation());
if (isError(val)) {
throw new RuntimeException(val.toString());
}
return newConstValue(call.id(), val);
default:
return i;
}
};
Env env = newEnv(declarations(Decls.newVar("foo", Decls.Int)));
AstIssuesTuple astIss = env.compile("foo == -1 + 2 * 3 / 3");
env.program(astIss.getAst(), evalOptions(OptPartialEval), customDecorator(optimizeArith));
assertThat(lastInstruction.get()).isInstanceOf(InterpretableCall.class);
InterpretableCall call = (InterpretableCall) lastInstruction.get();
Interpretable[] args = call.args();
Interpretable lhs = args[0];
assertThat(lhs).isInstanceOf(InterpretableAttribute.class);
InterpretableAttribute lastAttr = (InterpretableAttribute) lhs;
NamespacedAttribute absAttr = (NamespacedAttribute) lastAttr.attr();
String[] varNames = absAttr.candidateVariableNames();
assertThat(varNames).containsExactly("foo");
Interpretable rhs = args[1];
assertThat(rhs).isInstanceOf(InterpretableConst.class);
InterpretableConst lastConst = (InterpretableConst) rhs;
// This is the last number produced by the optimization.
assertThat(lastConst.value()).isSameAs(IntOne);
}
use of org.projectnessie.cel.Env.AstIssuesTuple in project cel-java by projectnessie.
the class CELTest method EvalRecover.
@Test
void EvalRecover() {
Env e = newEnv(declarations(Decls.newFunction("panic", Decls.newOverload("panic", singletonList(Type.getDefaultInstance()), Decls.Bool))));
ProgramOption funcs = functions(Overload.function("panic", args -> {
throw new RuntimeException("watch me recover");
}));
// Test standard evaluation.
AstIssuesTuple pAst = e.parse("panic()");
Program prgm1 = e.program(pAst.getAst(), funcs);
assertThatThrownBy(() -> prgm1.eval(emptyMap())).isExactlyInstanceOf(RuntimeException.class).hasMessage("internal error: watch me recover");
// Test the factory-based evaluation.
Program prgm2 = e.program(pAst.getAst(), funcs, evalOptions(OptTrackState));
assertThatThrownBy(() -> prgm2.eval(emptyMap())).isExactlyInstanceOf(RuntimeException.class).hasMessage("internal error: watch me recover");
}
use of org.projectnessie.cel.Env.AstIssuesTuple in project cel-java by projectnessie.
the class CELTest method GlobalVars.
@Test
void GlobalVars() {
Type mapStrDyn = Decls.newMapType(Decls.String, Decls.Dyn);
Env e = newEnv(declarations(Decls.newVar("attrs", mapStrDyn), Decls.newVar("default", Decls.Dyn), Decls.newFunction("get", Decls.newInstanceOverload("get_map", asList(mapStrDyn, Decls.String, Decls.Dyn), Decls.Dyn))));
AstIssuesTuple astIss = e.compile("attrs.get(\"first\", attrs.get(\"second\", default))");
// Create the program.
ProgramOption funcs = functions(Overload.function("get", args -> {
if (args.length != 3) {
return newErr("invalid arguments to 'get'");
}
if (!(args[0] instanceof Mapper)) {
return newErr("invalid operand of type '%s' to obj.get(key, def)", args[0].type());
}
Mapper attrs = (Mapper) args[0];
if (!(args[1] instanceof StringT)) {
return newErr("invalid key of type '%s' to obj.get(key, def)", args[1].type());
}
StringT key = (StringT) args[1];
Val defVal = args[2];
if (attrs.contains(key) == True) {
return attrs.get(key);
}
return defVal;
}));
// Global variables can be configured as a ProgramOption and optionally overridden on Eval.
Program prg = e.program(astIss.getAst(), funcs, globals(mapOf("default", "third")));
// t.Run("global_default", func(t *testing.T) {
Object vars = mapOf("attrs", mapOf());
EvalResult out = prg.eval(vars);
assertThat(out.getVal().equal(stringOf("third"))).isSameAs(True);
// })
// t.Run("attrs_alt", func(t *testing.T) {
vars = mapOf("attrs", mapOf("second", "yep"));
out = prg.eval(vars);
assertThat(out.getVal().equal(stringOf("yep"))).isSameAs(True);
// })
// t.Run("local_default", func(t *testing.T) {
vars = mapOf("attrs", mapOf(), "default", "fourth");
out = prg.eval(vars);
assertThat(out.getVal().equal(stringOf("fourth"))).isSameAs(True);
// })
}
Aggregations