diff --git a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel
index 2eb26846f..454b2a2fd 100644
--- a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel
+++ b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel
@@ -42,6 +42,7 @@ java_library(
":strings",
"//common:options",
"//extensions:extension_library",
+ "@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
],
)
diff --git a/extensions/src/main/java/dev/cel/extensions/CelExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelExtensions.java
index 2d14ed118..8f1770f3f 100644
--- a/extensions/src/main/java/dev/cel/extensions/CelExtensions.java
+++ b/extensions/src/main/java/dev/cel/extensions/CelExtensions.java
@@ -19,7 +19,9 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
+import com.google.errorprone.annotations.InlineMe;
import dev.cel.common.CelOptions;
+import dev.cel.extensions.CelMathExtensions.Function;
import java.util.Set;
/**
@@ -121,12 +123,9 @@ public static CelProtoExtensions protos() {
*
This will include all functions denoted in {@link CelMathExtensions.Function}, including any
* future additions. To expose only a subset of these, use {@link #math(CelOptions,
* CelMathExtensions.Function...)} or {@link #math(CelOptions,int)} instead.
- *
- * @param celOptions CelOptions to configure CelMathExtension with. This should be the same
- * options object used to configure the compilation/runtime environments.
*/
- public static CelMathExtensions math(CelOptions celOptions) {
- return CelMathExtensions.library(celOptions).latest();
+ public static CelMathExtensions math() {
+ return CelMathExtensions.library().latest();
}
/**
@@ -134,8 +133,8 @@ public static CelMathExtensions math(CelOptions celOptions) {
*
*
Refer to README.md for functions available in each version.
*/
- public static CelMathExtensions math(CelOptions celOptions, int version) {
- return CelMathExtensions.library(celOptions).version(version);
+ public static CelMathExtensions math(int version) {
+ return CelMathExtensions.library().version(version);
}
/**
@@ -150,13 +149,9 @@ public static CelMathExtensions math(CelOptions celOptions, int version) {
* collision.
*
*
This will include only the specific functions denoted by {@link CelMathExtensions.Function}.
- *
- * @param celOptions CelOptions to configure CelMathExtension with. This should be the same
- * options object used to configure the compilation/runtime environments.
*/
- public static CelMathExtensions math(
- CelOptions celOptions, CelMathExtensions.Function... functions) {
- return math(celOptions, ImmutableSet.copyOf(functions));
+ public static CelMathExtensions math(CelMathExtensions.Function... functions) {
+ return math(ImmutableSet.copyOf(functions));
}
/**
@@ -171,13 +166,49 @@ public static CelMathExtensions math(
* collision.
*
*
This will include only the specific functions denoted by {@link CelMathExtensions.Function}.
- *
- * @param celOptions CelOptions to configure CelMathExtension with. This should be the same
- * options object used to configure the compilation/runtime environments.
*/
+ public static CelMathExtensions math(Set functions) {
+ return new CelMathExtensions(functions);
+ }
+
+ /**
+ * @deprecated Use {@link #math()} instead.
+ */
+ @Deprecated
+ @InlineMe(replacement = "CelExtensions.math()", imports = "dev.cel.extensions.CelExtensions")
+ public static CelMathExtensions math(CelOptions unused) {
+ return math();
+ }
+
+ /**
+ * @deprecated Use {@link #math(int)} instead.
+ */
+ @Deprecated
+ @InlineMe(
+ replacement = "CelExtensions.math(version)",
+ imports = "dev.cel.extensions.CelExtensions")
+ public static CelMathExtensions math(CelOptions unused, int version) {
+ return math(version);
+ }
+
+ /**
+ * @deprecated Use {@link #math(Function...)} instead.
+ */
+ @Deprecated
+ public static CelMathExtensions math(CelOptions unused, CelMathExtensions.Function... functions) {
+ return math(ImmutableSet.copyOf(functions));
+ }
+
+ /**
+ * @deprecated Use {@link #math(Set)} instead.
+ */
+ @Deprecated
+ @InlineMe(
+ replacement = "CelExtensions.math(functions)",
+ imports = "dev.cel.extensions.CelExtensions")
public static CelMathExtensions math(
- CelOptions celOptions, Set functions) {
- return new CelMathExtensions(celOptions, functions);
+ CelOptions unused, Set functions) {
+ return math(functions);
}
/**
@@ -354,7 +385,7 @@ public static CelExtensionLibrary extends CelExtensionLibrary.FeatureSet> getE
case "lists":
return CelListsExtensions.library();
case "math":
- return CelMathExtensions.library(options);
+ return CelMathExtensions.library();
case "optional":
return CelOptionalLibrary.library();
case "protos":
diff --git a/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java
index 22336eb22..78a0fd51c 100644
--- a/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java
+++ b/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java
@@ -27,7 +27,6 @@
import dev.cel.checker.CelCheckerBuilder;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelIssue;
-import dev.cel.common.CelOptions;
import dev.cel.common.CelOverloadDecl;
import dev.cel.common.ast.CelConstant;
import dev.cel.common.ast.CelExpr;
@@ -136,7 +135,8 @@ public final class CelMathExtensions
return builder.buildOrThrow();
}
- enum Function {
+ /** Enumeration of functions for Math extension. */
+ public enum Function {
MAX(
CelFunctionDecl.newFunctionDeclaration(
MATH_MAX_FUNCTION,
@@ -206,51 +206,59 @@ enum Function {
MATH_MAX_OVERLOAD_DOC,
SimpleType.DYN,
ListType.create(SimpleType.DYN))),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@max_double", Double.class, x -> x),
- CelFunctionBinding.from("math_@max_int", Long.class, x -> x),
- CelFunctionBinding.from(
- "math_@max_double_double", Double.class, Double.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_int_int", Long.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_int_double", Long.class, Double.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_double_int", Double.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from("math_@max_list_dyn", List.class, CelMathExtensions::maxList)),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@max_uint", Long.class, x -> x),
- CelFunctionBinding.from(
- "math_@max_uint_uint", Long.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_double_uint", Double.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_uint_int", Long.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_uint_double", Long.class, Double.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_int_uint", Long.class, Long.class, CelMathExtensions::maxPair)),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@max_uint", UnsignedLong.class, x -> x),
- CelFunctionBinding.from(
- "math_@max_uint_uint",
- UnsignedLong.class,
- UnsignedLong.class,
- CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_double_uint",
- Double.class,
- UnsignedLong.class,
- CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_uint_int", UnsignedLong.class, Long.class, CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_uint_double",
- UnsignedLong.class,
- Double.class,
- CelMathExtensions::maxPair),
- CelFunctionBinding.from(
- "math_@max_int_uint", Long.class, UnsignedLong.class, CelMathExtensions::maxPair))),
+ ImmutableSet.builder()
+ .add(CelFunctionBinding.from("math_@max_double", Double.class, x -> x))
+ .add(CelFunctionBinding.from("math_@max_int", Long.class, x -> x))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_double_double",
+ Double.class,
+ Double.class,
+ CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_int_int", Long.class, Long.class, CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_int_double", Long.class, Double.class, CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_double_int", Double.class, Long.class, CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_list_dyn", List.class, CelMathExtensions::maxList))
+ .add(CelFunctionBinding.from("math_@max_uint", UnsignedLong.class, x -> x))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_uint_uint",
+ UnsignedLong.class,
+ UnsignedLong.class,
+ CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_double_uint",
+ Double.class,
+ UnsignedLong.class,
+ CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_uint_int",
+ UnsignedLong.class,
+ Long.class,
+ CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_uint_double",
+ UnsignedLong.class,
+ Double.class,
+ CelMathExtensions::maxPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@max_int_uint",
+ Long.class,
+ UnsignedLong.class,
+ CelMathExtensions::maxPair))
+ .build()),
MIN(
CelFunctionDecl.newFunctionDeclaration(
MATH_MIN_FUNCTION,
@@ -320,51 +328,59 @@ enum Function {
MATH_MIN_OVERLOAD_DOC,
SimpleType.DYN,
ListType.create(SimpleType.DYN))),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@min_double", Double.class, x -> x),
- CelFunctionBinding.from("math_@min_int", Long.class, x -> x),
- CelFunctionBinding.from(
- "math_@min_double_double", Double.class, Double.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_int_int", Long.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_int_double", Long.class, Double.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_double_int", Double.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from("math_@min_list_dyn", List.class, CelMathExtensions::minList)),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@min_uint", Long.class, x -> x),
- CelFunctionBinding.from(
- "math_@min_uint_uint", Long.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_double_uint", Double.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_uint_int", Long.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_uint_double", Long.class, Double.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_int_uint", Long.class, Long.class, CelMathExtensions::minPair)),
- ImmutableSet.of(
- CelFunctionBinding.from("math_@min_uint", UnsignedLong.class, x -> x),
- CelFunctionBinding.from(
- "math_@min_uint_uint",
- UnsignedLong.class,
- UnsignedLong.class,
- CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_double_uint",
- Double.class,
- UnsignedLong.class,
- CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_uint_int", UnsignedLong.class, Long.class, CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_uint_double",
- UnsignedLong.class,
- Double.class,
- CelMathExtensions::minPair),
- CelFunctionBinding.from(
- "math_@min_int_uint", Long.class, UnsignedLong.class, CelMathExtensions::minPair))),
+ ImmutableSet.builder()
+ .add(CelFunctionBinding.from("math_@min_double", Double.class, x -> x))
+ .add(CelFunctionBinding.from("math_@min_int", Long.class, x -> x))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_double_double",
+ Double.class,
+ Double.class,
+ CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_int_int", Long.class, Long.class, CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_int_double", Long.class, Double.class, CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_double_int", Double.class, Long.class, CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_list_dyn", List.class, CelMathExtensions::minList))
+ .add(CelFunctionBinding.from("math_@min_uint", UnsignedLong.class, x -> x))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_uint_uint",
+ UnsignedLong.class,
+ UnsignedLong.class,
+ CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_double_uint",
+ Double.class,
+ UnsignedLong.class,
+ CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_uint_int",
+ UnsignedLong.class,
+ Long.class,
+ CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_uint_double",
+ UnsignedLong.class,
+ Double.class,
+ CelMathExtensions::minPair))
+ .add(
+ CelFunctionBinding.from(
+ "math_@min_int_uint",
+ Long.class,
+ UnsignedLong.class,
+ CelMathExtensions::minPair))
+ .build()),
CEIL(
CelFunctionDecl.newFunctionDeclaration(
MATH_CEIL_FUNCTION,
@@ -646,36 +662,14 @@ enum Function {
private final CelFunctionDecl functionDecl;
private final ImmutableSet functionBindings;
- private final ImmutableSet functionBindingsULongSigned;
- private final ImmutableSet functionBindingsULongUnsigned;
String getFunction() {
return functionDecl.name();
}
Function(CelFunctionDecl functionDecl, ImmutableSet bindings) {
- this(functionDecl, bindings, ImmutableSet.of(), ImmutableSet.of());
- }
-
- Function(
- CelFunctionDecl functionDecl,
- ImmutableSet functionBindings,
- ImmutableSet functionBindingsULongSigned,
- ImmutableSet functionBindingsULongUnsigned) {
this.functionDecl = functionDecl;
- this.functionBindings =
- functionBindings.isEmpty()
- ? ImmutableSet.of()
- : CelFunctionBinding.fromOverloads(functionDecl.name(), functionBindings);
- this.functionBindingsULongSigned =
- functionBindingsULongSigned.isEmpty()
- ? ImmutableSet.of()
- : CelFunctionBinding.fromOverloads(functionDecl.name(), functionBindingsULongSigned);
- this.functionBindingsULongUnsigned =
- functionBindingsULongUnsigned.isEmpty()
- ? ImmutableSet.of()
- : CelFunctionBinding.fromOverloads(
- functionDecl.name(), functionBindingsULongUnsigned);
+ this.functionBindings = bindings;
}
}
@@ -684,10 +678,8 @@ private static final class Library implements CelExtensionLibrarybuilder()
.addAll(version1.functions)
.add(Function.SQRT)
- .build(),
- enableUnsignedLongs);
+ .build());
}
@Override
@@ -734,25 +724,20 @@ public ImmutableSet versions() {
}
}
- private static final Library LIBRARY_UNSIGNED_LONGS_ENABLED = new Library(true);
- private static final Library LIBRARY_UNSIGNED_LONGS_DISABLED = new Library(false);
+ private static final Library LIBRARY = new Library();
- static CelExtensionLibrary library(CelOptions celOptions) {
- return celOptions.enableUnsignedLongs()
- ? LIBRARY_UNSIGNED_LONGS_ENABLED
- : LIBRARY_UNSIGNED_LONGS_DISABLED;
+ static CelExtensionLibrary library() {
+ return LIBRARY;
}
- private final boolean enableUnsignedLongs;
private final ImmutableSet functions;
private final int version;
- CelMathExtensions(CelOptions celOptions, Set functions) {
- this(-1, functions, celOptions.enableUnsignedLongs());
+ CelMathExtensions(Set functions) {
+ this(-1, functions);
}
- private CelMathExtensions(int version, Set functions, boolean enableUnsignedLongs) {
- this.enableUnsignedLongs = enableUnsignedLongs;
+ private CelMathExtensions(int version, Set functions) {
this.version = version;
this.functions = ImmutableSet.copyOf(functions);
}
@@ -788,11 +773,11 @@ public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
functions.forEach(
function -> {
- runtimeBuilder.addFunctionBindings(function.functionBindings);
- runtimeBuilder.addFunctionBindings(
- enableUnsignedLongs
- ? function.functionBindingsULongUnsigned
- : function.functionBindingsULongSigned);
+ ImmutableSet combined = function.functionBindings;
+ if (!combined.isEmpty()) {
+ runtimeBuilder.addFunctionBindings(
+ CelFunctionBinding.fromOverloads(function.functionDecl.name(), combined));
+ }
});
}
diff --git a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel
index 19fd3657e..eed240317 100644
--- a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel
+++ b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel
@@ -12,6 +12,7 @@ java_library(
"//bundle:cel",
"//bundle:cel_experimental_factory",
"//common:cel_ast",
+ "//common:cel_exception",
"//common:compiler_common",
"//common:container",
"//common:options",
diff --git a/extensions/src/test/java/dev/cel/extensions/CelBindingsExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelBindingsExtensionsTest.java
index b87967d0e..00fcad473 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelBindingsExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelBindingsExtensionsTest.java
@@ -23,7 +23,6 @@
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.bundle.Cel;
-import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOptions;
import dev.cel.common.CelOverloadDecl;
@@ -36,36 +35,24 @@
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelFunctionBinding;
-import dev.cel.testing.CelRuntimeFlavor;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public final class CelBindingsExtensionsTest {
-
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- cel =
- runtimeFlavor
- .builder()
- .setOptions(CelOptions.current().enableHeterogeneousNumericComparisons(true).build())
- .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
- .addCompilerLibraries(CelOptionalLibrary.INSTANCE, CelExtensions.bindings())
- .addRuntimeLibraries(CelOptionalLibrary.INSTANCE)
- .build();
+public final class CelBindingsExtensionsTest extends CelExtensionTestBase {
+
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .setOptions(CelOptions.current().enableHeterogeneousNumericComparisons(true).build())
+ .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
+ .addCompilerLibraries(CelOptionalLibrary.INSTANCE, CelExtensions.bindings())
+ .addRuntimeLibraries(CelOptionalLibrary.INSTANCE)
+ .build();
}
@Test
@@ -331,21 +318,5 @@ public void lazyBinding_boundAttributeInNestedComprehension() throws Exception {
assertThat(invocation.get()).isEqualTo(1);
}
- private Object eval(Cel cel, String expression) throws Exception {
- return eval(cel, expression, ImmutableMap.of());
- }
-
- private Object eval(Cel cel, String expression, Map variables) throws Exception {
- CelAbstractSyntaxTree ast;
- if (isParseOnly) {
- ast = cel.parse(expression).getAst();
- } else {
- ast = cel.compile(expression).getAst();
- }
- return cel.createProgram(ast).eval(variables);
- }
- private Object eval(String expression) throws Exception {
- return eval(this.cel, expression, ImmutableMap.of());
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java
index 207178cfe..42dc3e07d 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java
@@ -19,7 +19,6 @@
import static org.junit.Assert.assertThrows;
import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
@@ -40,15 +39,13 @@
import dev.cel.parser.CelUnparserFactory;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.testing.CelRuntimeFlavor;
-import java.util.Map;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link CelExtensions#comprehensions()} */
@RunWith(TestParameterInjector.class)
-public class CelComprehensionsExtensionsTest {
+public class CelComprehensionsExtensionsTest extends CelExtensionTestBase {
private static final CelOptions CEL_OPTIONS =
CelOptions.current()
@@ -57,29 +54,21 @@ public class CelComprehensionsExtensionsTest {
.populateMacroCalls(true)
.build();
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel =
- runtimeFlavor
- .builder()
- .setOptions(CEL_OPTIONS)
- .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
- .addCompilerLibraries(CelExtensions.comprehensions())
- .addCompilerLibraries(CelExtensions.lists())
- .addCompilerLibraries(CelExtensions.strings())
- .addCompilerLibraries(CelOptionalLibrary.INSTANCE, CelExtensions.bindings())
- .addRuntimeLibraries(CelOptionalLibrary.INSTANCE)
- .addRuntimeLibraries(CelExtensions.lists())
- .addRuntimeLibraries(CelExtensions.strings())
- .addRuntimeLibraries(CelExtensions.comprehensions())
- .build();
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .setOptions(CEL_OPTIONS)
+ .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
+ .addCompilerLibraries(CelExtensions.comprehensions())
+ .addCompilerLibraries(CelExtensions.lists())
+ .addCompilerLibraries(CelExtensions.strings())
+ .addCompilerLibraries(CelOptionalLibrary.INSTANCE, CelExtensions.bindings())
+ .addRuntimeLibraries(CelOptionalLibrary.INSTANCE)
+ .addRuntimeLibraries(CelExtensions.lists())
+ .addRuntimeLibraries(CelExtensions.strings())
+ .addRuntimeLibraries(CelExtensions.comprehensions())
+ .build();
}
private static final CelUnparser UNPARSER = CelUnparserFactory.newUnparser();
@@ -376,17 +365,5 @@ public void mutableMapValue_select_missingKeyException() throws Exception {
assertThat(e).hasCauseThat().hasMessageThat().contains("key 'b' is not present in map.");
}
- private Object eval(String expression) throws Exception {
- return eval(this.cel, expression, ImmutableMap.of());
- }
- private Object eval(Cel cel, String expression, Map variables) throws Exception {
- CelAbstractSyntaxTree ast;
- if (isParseOnly) {
- ast = cel.parse(expression).getAst();
- } else {
- ast = cel.compile(expression).getAst();
- }
- return cel.createProgram(ast).eval(variables);
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java
index b0a501ddb..afeaa9105 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java
@@ -19,44 +19,32 @@
import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableMap;
-import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import dev.cel.bundle.Cel;
-import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOptions;
import dev.cel.common.CelValidationException;
import dev.cel.common.types.SimpleType;
import dev.cel.common.values.CelByteString;
import dev.cel.runtime.CelEvaluationException;
-import dev.cel.testing.CelRuntimeFlavor;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public class CelEncoderExtensionsTest {
+public class CelEncoderExtensionsTest extends CelExtensionTestBase {
private static final CelOptions CEL_OPTIONS =
CelOptions.current().enableHeterogeneousNumericComparisons(true).build();
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel =
- runtimeFlavor
- .builder()
- .setOptions(CEL_OPTIONS)
- .addCompilerLibraries(CelExtensions.encoders(CEL_OPTIONS))
- .addRuntimeLibraries(CelExtensions.encoders(CEL_OPTIONS))
- .addVar("stringVar", SimpleType.STRING)
- .build();
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .setOptions(CEL_OPTIONS)
+ .addCompilerLibraries(CelExtensions.encoders(CEL_OPTIONS))
+ .addRuntimeLibraries(CelExtensions.encoders(CEL_OPTIONS))
+ .addVar("stringVar", SimpleType.STRING)
+ .build();
}
@Test
@@ -132,12 +120,5 @@ public void decode_malformedBase64Char_throwsEvaluationException() throws Except
assertThat(e).hasCauseThat().hasMessageThat().contains("Illegal base64 character");
}
- private Object eval(String expr) throws Exception {
- return eval(expr, ImmutableMap.of());
- }
- private Object eval(String expr, ImmutableMap vars) throws Exception {
- CelAbstractSyntaxTree ast = isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
- return cel.createProgram(ast).eval(vars);
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelExtensionTestBase.java b/extensions/src/test/java/dev/cel/extensions/CelExtensionTestBase.java
new file mode 100644
index 000000000..c80ee38b6
--- /dev/null
+++ b/extensions/src/test/java/dev/cel/extensions/CelExtensionTestBase.java
@@ -0,0 +1,66 @@
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dev.cel.extensions;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.testing.junit.testparameterinjector.TestParameter;
+import dev.cel.bundle.Cel;
+import dev.cel.common.CelAbstractSyntaxTree;
+import dev.cel.common.CelException;
+import dev.cel.testing.CelRuntimeFlavor;
+import java.util.Map;
+import org.junit.Assume;
+import org.junit.Before;
+
+/**
+ * Abstract base class for extension tests to facilitate executing tests with both legacy and
+ * planner runtime, along with parsed-only and checked expression evaluations for the planner.
+ */
+abstract class CelExtensionTestBase {
+ @TestParameter public CelRuntimeFlavor runtimeFlavor;
+ @TestParameter public boolean isParseOnly;
+
+ @Before
+ public void setUpBase() {
+ // Legacy runtime does not support parsed-only evaluation.
+ Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
+ this.cel = newCelEnv();
+ }
+
+ protected Cel cel;
+
+ /**
+ * Subclasses must implement this to provide a Cel instance configured with the specific
+ * extensions being tested.
+ */
+ protected abstract Cel newCelEnv();
+
+ protected Object eval(String expr) throws CelException {
+ return eval(cel, expr, ImmutableMap.of());
+ }
+
+ protected Object eval(String expr, Map variables) throws CelException {
+ return eval(cel, expr, variables);
+ }
+
+ protected Object eval(Cel cel, String expr) throws CelException {
+ return eval(cel, expr, ImmutableMap.of());
+ }
+
+ protected Object eval(Cel cel, String expr, Map variables) throws CelException {
+ CelAbstractSyntaxTree ast = isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
+ return cel.createProgram(ast).eval(variables);
+ }
+}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelListsExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelListsExtensionsTest.java
index f36d90e2d..4520f81ba 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelListsExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelListsExtensionsTest.java
@@ -19,12 +19,9 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMultiset;
import com.google.common.collect.ImmutableSortedSet;
-import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.bundle.Cel;
-import dev.cel.bundle.CelBuilder;
-import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelContainer;
import dev.cel.common.CelValidationException;
import dev.cel.common.CelValidationResult;
@@ -33,24 +30,24 @@
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.testing.CelRuntimeFlavor;
-import java.util.Map;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public class CelListsExtensionsTest {
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
+public class CelListsExtensionsTest extends CelExtensionTestBase {
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel = setupEnv(runtimeFlavor.builder());
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
+ .addCompilerLibraries(CelExtensions.lists())
+ .addRuntimeLibraries(CelExtensions.lists())
+ .setContainer(CelContainer.ofName("cel.expr.conformance.test"))
+ .addMessageTypes(SimpleTest.getDescriptor())
+ .addVar("non_list", SimpleType.DYN)
+ .build();
}
@Test
@@ -147,7 +144,7 @@ public void flatten_negativeDepth_throws() {
CelEvaluationException e =
assertThrows(CelEvaluationException.class, () -> eval(cel, "[1,2,3,4].flatten(-1)"));
- if (isParseOnly) {
+ if (runtimeFlavor.equals(CelRuntimeFlavor.PLANNER)) {
assertThat(e)
.hasMessageThat()
.contains("evaluation error at :17: Function 'flatten' failed");
@@ -322,23 +319,5 @@ public void sortBy_throws_evaluationException(String expression, String expected
.contains(expectedError);
}
- private static Cel setupEnv(CelBuilder celBuilder) {
- return celBuilder
- .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
- .addCompilerLibraries(CelExtensions.lists())
- .addRuntimeLibraries(CelExtensions.lists())
- .setContainer(CelContainer.ofName("cel.expr.conformance.test"))
- .addMessageTypes(SimpleTest.getDescriptor())
- .addVar("non_list", SimpleType.DYN)
- .build();
- }
-
- private Object eval(Cel cel, String expr) throws Exception {
- return eval(cel, expr, ImmutableMap.of());
- }
- private Object eval(Cel cel, String expr, Map vars) throws Exception {
- CelAbstractSyntaxTree ast = isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
- return cel.createProgram(ast).eval(vars);
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelMathExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelMathExtensionsTest.java
index bcdfb0a21..383e50aa2 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelMathExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelMathExtensionsTest.java
@@ -20,8 +20,10 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.UnsignedLong;
+import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
+import dev.cel.bundle.Cel;
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOptions;
@@ -35,34 +37,36 @@
import dev.cel.runtime.CelFunctionBinding;
import dev.cel.runtime.CelRuntime;
import dev.cel.runtime.CelRuntimeFactory;
+import dev.cel.testing.CelRuntimeFlavor;
+import java.util.Map;
+import org.junit.Assume;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
public class CelMathExtensionsTest {
- private static final CelOptions CEL_OPTIONS =
- CelOptions.current().enableUnsignedLongs(false).build();
- private static final CelCompiler CEL_COMPILER =
- CelCompilerFactory.standardCelCompilerBuilder()
- .setOptions(CEL_OPTIONS)
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
- .build();
- private static final CelRuntime CEL_RUNTIME =
- CelRuntimeFactory.standardCelRuntimeBuilder()
- .setOptions(CEL_OPTIONS)
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
- .build();
- private static final CelOptions CEL_UNSIGNED_OPTIONS = CelOptions.current().build();
- private static final CelCompiler CEL_UNSIGNED_COMPILER =
- CelCompilerFactory.standardCelCompilerBuilder()
- .setOptions(CEL_UNSIGNED_OPTIONS)
- .addLibraries(CelExtensions.math(CEL_UNSIGNED_OPTIONS))
- .build();
- private static final CelRuntime CEL_UNSIGNED_RUNTIME =
- CelRuntimeFactory.standardCelRuntimeBuilder()
- .setOptions(CEL_UNSIGNED_OPTIONS)
- .addLibraries(CelExtensions.math(CEL_UNSIGNED_OPTIONS))
- .build();
+ @TestParameter public CelRuntimeFlavor runtimeFlavor;
+ @TestParameter public boolean isParseOnly;
+
+ private Cel cel;
+
+ @Before
+ public void setUp() {
+ // Legacy runtime does not support parsed-only evaluation mode.
+ Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
+ this.cel =
+ runtimeFlavor
+ .builder()
+ .setOptions(
+ CelOptions.current()
+ .enableHeterogeneousNumericComparisons(
+ runtimeFlavor.equals(CelRuntimeFlavor.PLANNER))
+ .build())
+ .addCompilerLibraries(CelExtensions.math())
+ .addRuntimeLibraries(CelExtensions.math())
+ .build();
+ }
@Test
@TestParameters("{expr: 'math.greatest(-5)', expectedResult: -5}")
@@ -97,9 +101,7 @@ public class CelMathExtensionsTest {
"{expr: 'math.greatest([dyn(5.4), dyn(10), dyn(3u), dyn(-5.0), dyn(3.5)])', expectedResult:"
+ " 10}")
public void greatest_intResult_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
@@ -136,9 +138,7 @@ public void greatest_intResult_success(String expr, long expectedResult) throws
"{expr: 'math.greatest([dyn(5.4), dyn(10.0), dyn(3u), dyn(-5.0), dyn(3.5)])', expectedResult:"
+ " 10.0}")
public void greatest_doubleResult_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
@@ -163,16 +163,16 @@ public void greatest_doubleResult_success(String expr, double expectedResult) th
+ " '10.0'}")
public void greatest_doubleResult_withUnsignedLongsEnabled_success(
String expr, double expectedResult) throws Exception {
- CelOptions celOptions = CelOptions.current().enableUnsignedLongs(true).build();
+ CelOptions celOptions = CelOptions.DEFAULT;
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelRuntime celRuntime =
CelRuntimeFactory.standardCelRuntimeBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
@@ -182,44 +182,7 @@ public void greatest_doubleResult_withUnsignedLongsEnabled_success(
}
@Test
- @TestParameters("{expr: 'math.greatest(5u)', expectedResult: 5}")
- @TestParameters("{expr: 'math.greatest(1u, 1.0)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(1u, 1)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(1u, 1u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(3u, 3.0)', expectedResult: 3}")
- @TestParameters("{expr: 'math.greatest(9u, 10u)', expectedResult: 10}")
- @TestParameters("{expr: 'math.greatest(15u, 14u)', expectedResult: 15}")
- @TestParameters(
- "{expr: 'math.greatest(1, 9223372036854775807u)', expectedResult: 9223372036854775807}")
- @TestParameters(
- "{expr: 'math.greatest(9223372036854775807u, 1)', expectedResult: 9223372036854775807}")
- @TestParameters("{expr: 'math.greatest(1u, 1, 1)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(3u, 1u, 10u)', expectedResult: 10}")
- @TestParameters("{expr: 'math.greatest(1u, 5u, 2u)', expectedResult: 5}")
- @TestParameters("{expr: 'math.greatest(-1, 1u, 0u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(dyn(1u), 1, 1.0)', expectedResult: 1}")
- @TestParameters("{expr: 'math.greatest(5u, 1.0, 3u)', expectedResult: 5}")
- @TestParameters("{expr: 'math.greatest(5.4, 10u, 3u, -5.0, 3.5)', expectedResult: 10}")
- @TestParameters(
- "{expr: 'math.greatest(5.4, 10, 3u, -5.0, 9223372036854775807)', expectedResult:"
- + " 9223372036854775807}")
- @TestParameters(
- "{expr: 'math.greatest(9223372036854775807, 10, 3u, -5.0, 0)', expectedResult:"
- + " 9223372036854775807}")
- @TestParameters("{expr: 'math.greatest([5.4, 10, 3u, -5.0, 3.5])', expectedResult: 10}")
- @TestParameters(
- "{expr: 'math.greatest([dyn(5.4), dyn(10), dyn(3u), dyn(-5.0), dyn(3.5)])', expectedResult:"
- + " 10}")
- public void greatest_unsignedLongResult_withSignedLongType_success(
- String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
-
- assertThat(result).isEqualTo(expectedResult);
- }
-
- @Test
+ @TestParameters("{expr: 'math.greatest(5u)', expectedResult: '5'}")
@TestParameters(
"{expr: 'math.greatest(18446744073709551615u)', expectedResult: '18446744073709551615'}")
@TestParameters("{expr: 'math.greatest(1u, 1.0)', expectedResult: '1'}")
@@ -251,16 +214,16 @@ public void greatest_unsignedLongResult_withSignedLongType_success(
+ " '10'}")
public void greatest_unsignedLongResult_withUnsignedLongType_success(
String expr, String expectedResult) throws Exception {
- CelOptions celOptions = CelOptions.current().enableUnsignedLongs(true).build();
+ CelOptions celOptions = CelOptions.DEFAULT;
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelRuntime celRuntime =
CelRuntimeFactory.standardCelRuntimeBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
@@ -271,9 +234,9 @@ public void greatest_unsignedLongResult_withUnsignedLongType_success(
@Test
public void greatest_noArgs_throwsCompilationException() {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(
- CelValidationException.class, () -> CEL_COMPILER.compile("math.greatest()").getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile("math.greatest()").getAst());
assertThat(e).hasMessageThat().contains("math.greatest() requires at least one argument");
}
@@ -283,8 +246,9 @@ public void greatest_noArgs_throwsCompilationException() {
@TestParameters("{expr: 'math.greatest({})'}")
@TestParameters("{expr: 'math.greatest([])'}")
public void greatest_invalidSingleArg_throwsCompilationException(String expr) {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("math.greatest() invalid single argument value");
}
@@ -297,8 +261,9 @@ public void greatest_invalidSingleArg_throwsCompilationException(String expr) {
@TestParameters("{expr: 'math.greatest([1, {}, 2])'}")
@TestParameters("{expr: 'math.greatest([1, [], 2])'}")
public void greatest_invalidArgs_throwsCompilationException(String expr) {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e)
.hasMessageThat()
@@ -312,19 +277,16 @@ public void greatest_invalidArgs_throwsCompilationException(String expr) {
@TestParameters("{expr: 'math.greatest([1, dyn({}), 2])'}")
@TestParameters("{expr: 'math.greatest([1, dyn([]), 2])'}")
public void greatest_invalidDynArgs_throwsRuntimeException(String expr) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- CelEvaluationException e =
- assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval());
+ CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> eval(expr));
- assertThat(e).hasMessageThat().contains("Function 'math_@max_list_dyn' failed with arg(s)");
+ assertThat(e).hasMessageThat().contains("failed with arg(s)");
}
@Test
public void greatest_listVariableIsEmpty_throwsRuntimeException() throws Exception {
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
+ .addLibraries(CelExtensions.math())
.addVar("listVar", ListType.create(SimpleType.INT))
.build();
CelAbstractSyntaxTree ast = celCompiler.compile("math.greatest(listVar)").getAst();
@@ -332,12 +294,9 @@ public void greatest_listVariableIsEmpty_throwsRuntimeException() throws Excepti
CelEvaluationException e =
assertThrows(
CelEvaluationException.class,
- () ->
- CEL_RUNTIME
- .createProgram(ast)
- .eval(ImmutableMap.of("listVar", ImmutableList.of())));
+ () -> cel.createProgram(ast).eval(ImmutableMap.of("listVar", ImmutableList.of())));
- assertThat(e).hasMessageThat().contains("Function 'math_@max_list_dyn' failed with arg(s)");
+ assertThat(e).hasMessageThat().contains("failed with arg(s)");
assertThat(e)
.hasCauseThat()
.hasMessageThat()
@@ -347,25 +306,25 @@ public void greatest_listVariableIsEmpty_throwsRuntimeException() throws Excepti
@Test
@TestParameters("{expr: '100.greatest(1) == 1'}")
@TestParameters("{expr: 'dyn(100).greatest(1) == 1'}")
- public void greatest_nonProtoNamespace_success(String expr) throws Exception {
- CelCompiler celCompiler =
- CelCompilerFactory.standardCelCompilerBuilder()
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
+ public void greatest_nonMathNamespace_success(String expr) throws Exception {
+ Cel cel =
+ runtimeFlavor
+ .builder()
+ .addCompilerLibraries(CelExtensions.math())
+ .addRuntimeLibraries(CelExtensions.math())
.addFunctionDeclarations(
CelFunctionDecl.newFunctionDeclaration(
"greatest",
CelOverloadDecl.newMemberOverload(
"int_greatest_int", SimpleType.INT, SimpleType.INT, SimpleType.INT)))
- .build();
- CelRuntime celRuntime =
- CelRuntimeFactory.standardCelRuntimeBuilder()
.addFunctionBindings(
- CelFunctionBinding.from(
- "int_greatest_int", Long.class, Long.class, (arg1, arg2) -> arg2))
+ CelFunctionBinding.fromOverloads(
+ "greatest",
+ CelFunctionBinding.from(
+ "int_greatest_int", Long.class, Long.class, (arg1, arg2) -> arg2)))
.build();
- CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
- boolean result = (boolean) celRuntime.createProgram(ast).eval();
+ boolean result = (boolean) eval(cel, expr);
assertThat(result).isTrue();
}
@@ -400,13 +359,14 @@ public void greatest_nonProtoNamespace_success(String expr) throws Exception {
"{expr: 'math.least(-9223372036854775808, 10, 3u, -5.0, 0)', expectedResult:"
+ " -9223372036854775808}")
@TestParameters("{expr: 'math.least([5.4, -10, 3u, -5.0, 3.5])', expectedResult: -10}")
+ @TestParameters("{expr: 'math.least(1, 9223372036854775807u)', expectedResult: 1}")
+ @TestParameters("{expr: 'math.least(9223372036854775807u, 1)', expectedResult: 1}")
+ @TestParameters("{expr: 'math.least(9223372036854775807, 10, 3u, 5.0, 0)', expectedResult: 0}")
@TestParameters(
"{expr: 'math.least([dyn(5.4), dyn(-10), dyn(3u), dyn(-5.0), dyn(3.5)])', expectedResult:"
+ " -10}")
public void least_intResult_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
@@ -443,9 +403,7 @@ public void least_intResult_success(String expr, long expectedResult) throws Exc
"{expr: 'math.least([dyn(5.4), dyn(10.0), dyn(3u), dyn(-5.0), dyn(3.5)])', expectedResult:"
+ " -5.0}")
public void least_doubleResult_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
@@ -474,12 +432,12 @@ public void least_doubleResult_withUnsignedLongsEnabled_success(
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelRuntime celRuntime =
CelRuntimeFactory.standardCelRuntimeBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
@@ -489,37 +447,15 @@ public void least_doubleResult_withUnsignedLongsEnabled_success(
}
@Test
- @TestParameters("{expr: 'math.least(5u)', expectedResult: 5}")
- @TestParameters("{expr: 'math.least(1u, 1.0)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(1u, 1)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(1u, 1u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(3u, 3.0)', expectedResult: 3}")
- @TestParameters("{expr: 'math.least(9u, 10u)', expectedResult: 9}")
- @TestParameters("{expr: 'math.least(15u, 14u)', expectedResult: 14}")
- @TestParameters("{expr: 'math.least(1, 9223372036854775807u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(9223372036854775807u, 1)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(1u, 1, 1)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(3u, 1u, 10u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(1u, 5u, 2u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(9, 1u, 0u)', expectedResult: 0}")
- @TestParameters("{expr: 'math.least(dyn(1u), 1, 1.0)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(5.0, 1u, 3u)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(5.4, 1u, 3u, 9, 3.5)', expectedResult: 1}")
- @TestParameters("{expr: 'math.least(5.4, 10, 3u, 5.0, 9223372036854775807)', expectedResult: 3}")
- @TestParameters("{expr: 'math.least(9223372036854775807, 10, 3u, 5.0, 0)', expectedResult: 0}")
- @TestParameters("{expr: 'math.least([5.4, 10, 3u, 5.0, 3.5])', expectedResult: 3}")
+ @TestParameters("{expr: 'math.least(9, 1u, 0u)', expectedResult: '0'}")
+ @TestParameters("{expr: 'math.least(dyn(1u), 1, 1.0)', expectedResult: '1'}")
+ @TestParameters("{expr: 'math.least(5.0, 1u, 3u)', expectedResult: '1'}")
+ @TestParameters("{expr: 'math.least(5.4, 1u, 3u, 9, 3.5)', expectedResult: '1'}")
@TestParameters(
- "{expr: 'math.least([dyn(5.4), dyn(10), dyn(3u), dyn(5.0), dyn(3.5)])', expectedResult: 3}")
- public void least_unsignedLongResult_withSignedLongType_success(String expr, long expectedResult)
- throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- Object result = CEL_RUNTIME.createProgram(ast).eval();
-
- assertThat(result).isEqualTo(expectedResult);
- }
-
- @Test
+ "{expr: 'math.least(5.4, 10, 3u, 5.0, 9223372036854775807)', expectedResult: '3'}")
+ @TestParameters("{expr: 'math.least([5.4, 10, 3u, 5.0, 3.5])', expectedResult: '3'}")
+ @TestParameters(
+ "{expr: 'math.least([dyn(5.4), dyn(10), dyn(3u), dyn(5.0), dyn(3.5)])', expectedResult: '3'}")
@TestParameters(
"{expr: 'math.least(18446744073709551615u)', expectedResult: '18446744073709551615'}")
@TestParameters("{expr: 'math.least(1u, 1.0)', expectedResult: '1'}")
@@ -553,12 +489,12 @@ public void least_unsignedLongResult_withUnsignedLongType_success(
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelRuntime celRuntime =
CelRuntimeFactory.standardCelRuntimeBuilder()
.setOptions(celOptions)
- .addLibraries(CelExtensions.math(celOptions))
+ .addLibraries(CelExtensions.math())
.build();
CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
@@ -569,9 +505,9 @@ public void least_unsignedLongResult_withUnsignedLongType_success(
@Test
public void least_noArgs_throwsCompilationException() {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(
- CelValidationException.class, () -> CEL_COMPILER.compile("math.least()").getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile("math.least()").getAst());
assertThat(e).hasMessageThat().contains("math.least() requires at least one argument");
}
@@ -581,8 +517,9 @@ public void least_noArgs_throwsCompilationException() {
@TestParameters("{expr: 'math.least({})'}")
@TestParameters("{expr: 'math.least([])'}")
public void least_invalidSingleArg_throwsCompilationException(String expr) {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("math.least() invalid single argument value");
}
@@ -595,8 +532,9 @@ public void least_invalidSingleArg_throwsCompilationException(String expr) {
@TestParameters("{expr: 'math.least([1, {}, 2])'}")
@TestParameters("{expr: 'math.least([1, [], 2])'}")
public void least_invalidArgs_throwsCompilationException(String expr) {
+ Assume.assumeFalse(isParseOnly);
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e)
.hasMessageThat()
@@ -610,19 +548,16 @@ public void least_invalidArgs_throwsCompilationException(String expr) {
@TestParameters("{expr: 'math.least([1, dyn({}), 2])'}")
@TestParameters("{expr: 'math.least([1, dyn([]), 2])'}")
public void least_invalidDynArgs_throwsRuntimeException(String expr) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- CelEvaluationException e =
- assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval());
+ CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> eval(expr));
- assertThat(e).hasMessageThat().contains("Function 'math_@min_list_dyn' failed with arg(s)");
+ assertThat(e).hasMessageThat().contains("failed with arg(s)");
}
@Test
public void least_listVariableIsEmpty_throwsRuntimeException() throws Exception {
CelCompiler celCompiler =
CelCompilerFactory.standardCelCompilerBuilder()
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
+ .addLibraries(CelExtensions.math())
.addVar("listVar", ListType.create(SimpleType.INT))
.build();
CelAbstractSyntaxTree ast = celCompiler.compile("math.least(listVar)").getAst();
@@ -630,12 +565,9 @@ public void least_listVariableIsEmpty_throwsRuntimeException() throws Exception
CelEvaluationException e =
assertThrows(
CelEvaluationException.class,
- () ->
- CEL_RUNTIME
- .createProgram(ast)
- .eval(ImmutableMap.of("listVar", ImmutableList.of())));
+ () -> cel.createProgram(ast).eval(ImmutableMap.of("listVar", ImmutableList.of())));
- assertThat(e).hasMessageThat().contains("Function 'math_@min_list_dyn' failed with arg(s)");
+ assertThat(e).hasMessageThat().contains("failed with arg(s)");
assertThat(e)
.hasCauseThat()
.hasMessageThat()
@@ -645,24 +577,25 @@ public void least_listVariableIsEmpty_throwsRuntimeException() throws Exception
@Test
@TestParameters("{expr: '100.least(1) == 1'}")
@TestParameters("{expr: 'dyn(100).least(1) == 1'}")
- public void least_nonProtoNamespace_success(String expr) throws Exception {
- CelCompiler celCompiler =
- CelCompilerFactory.standardCelCompilerBuilder()
- .addLibraries(CelExtensions.math(CEL_OPTIONS))
+ public void least_nonMathNamespace_success(String expr) throws Exception {
+ Cel cel =
+ runtimeFlavor
+ .builder()
+ .addCompilerLibraries(CelExtensions.math())
+ .addRuntimeLibraries(CelExtensions.math())
.addFunctionDeclarations(
CelFunctionDecl.newFunctionDeclaration(
"least",
CelOverloadDecl.newMemberOverload(
"int_least", SimpleType.INT, SimpleType.INT, SimpleType.INT)))
- .build();
- CelRuntime celRuntime =
- CelRuntimeFactory.standardCelRuntimeBuilder()
.addFunctionBindings(
- CelFunctionBinding.from("int_least", Long.class, Long.class, (arg1, arg2) -> arg2))
+ CelFunctionBinding.fromOverloads(
+ "least",
+ CelFunctionBinding.from(
+ "int_least", Long.class, Long.class, (arg1, arg2) -> arg2)))
.build();
- CelAbstractSyntaxTree ast = celCompiler.compile(expr).getAst();
- boolean result = (boolean) celRuntime.createProgram(ast).eval();
+ boolean result = (boolean) eval(cel, expr);
assertThat(result).isTrue();
}
@@ -676,9 +609,9 @@ public void least_nonProtoNamespace_success(String expr) throws Exception {
@TestParameters("{expr: 'math.isNaN(math.sign(0.0/0.0))', expectedResult: true}")
@TestParameters("{expr: 'math.isNaN(math.sqrt(-4))', expectedResult: true}")
public void isNaN_success(String expr, boolean expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -690,7 +623,7 @@ public void isNaN_success(String expr, boolean expectedResult) throws Exception
@TestParameters("{expr: 'math.isNaN(1u)'}")
public void isNaN_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.isNaN'");
}
@@ -701,9 +634,9 @@ public void isNaN_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.isFinite(1.0/0.0)', expectedResult: false}")
@TestParameters("{expr: 'math.isFinite(0.0/0.0)', expectedResult: false}")
public void isFinite_success(String expr, boolean expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -715,7 +648,7 @@ public void isFinite_success(String expr, boolean expectedResult) throws Excepti
@TestParameters("{expr: 'math.isFinite(1u)'}")
public void isFinite_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.isFinite'");
}
@@ -726,9 +659,9 @@ public void isFinite_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.isInf(0.0/0.0)', expectedResult: false}")
@TestParameters("{expr: 'math.isInf(10.0)', expectedResult: false}")
public void isInf_success(String expr, boolean expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -740,7 +673,7 @@ public void isInf_success(String expr, boolean expectedResult) throws Exception
@TestParameters("{expr: 'math.isInf(1u)'}")
public void isInf_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.isInf'");
}
@@ -752,9 +685,9 @@ public void isInf_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.ceil(20.0)' , expectedResult: 20.0}")
@TestParameters("{expr: 'math.ceil(0.0/0.0)' , expectedResult: NaN}")
public void ceil_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -766,7 +699,7 @@ public void ceil_success(String expr, double expectedResult) throws Exception {
@TestParameters("{expr: 'math.ceil(1u)'}")
public void ceil_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.ceil'");
}
@@ -777,9 +710,9 @@ public void ceil_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.floor(0.0/0.0)' , expectedResult: NaN}")
@TestParameters("{expr: 'math.floor(50.0)' , expectedResult: 50.0}")
public void floor_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -791,7 +724,7 @@ public void floor_success(String expr, double expectedResult) throws Exception {
@TestParameters("{expr: 'math.floor(1u)'}")
public void floor_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.floor'");
}
@@ -806,9 +739,9 @@ public void floor_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.round(1.0/0.0)' , expectedResult: Infinity}")
@TestParameters("{expr: 'math.round(-1.0/0.0)' , expectedResult: -Infinity}")
public void round_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -820,7 +753,7 @@ public void round_success(String expr, double expectedResult) throws Exception {
@TestParameters("{expr: 'math.round(1u)'}")
public void round_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.round'");
}
@@ -832,9 +765,9 @@ public void round_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.trunc(1.0/0.0)' , expectedResult: Infinity}")
@TestParameters("{expr: 'math.trunc(-1.0/0.0)' , expectedResult: -Infinity}")
public void trunc_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -846,7 +779,7 @@ public void trunc_success(String expr, double expectedResult) throws Exception {
@TestParameters("{expr: 'math.trunc(1u)'}")
public void trunc_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.trunc'");
}
@@ -856,9 +789,9 @@ public void trunc_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.abs(-1657643)', expectedResult: 1657643}")
@TestParameters("{expr: 'math.abs(-2147483648)', expectedResult: 2147483648}")
public void abs_intResult_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -871,9 +804,9 @@ public void abs_intResult_success(String expr, long expectedResult) throws Excep
@TestParameters("{expr: 'math.abs(1.0/0.0)' , expectedResult: Infinity}")
@TestParameters("{expr: 'math.abs(-1.0/0.0)' , expectedResult: Infinity}")
public void abs_doubleResult_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -883,7 +816,7 @@ public void abs_overflow_throwsException() {
CelValidationException e =
assertThrows(
CelValidationException.class,
- () -> CEL_COMPILER.compile("math.abs(-9223372036854775809)").getAst());
+ () -> cel.compile("math.abs(-9223372036854775809)").getAst());
assertThat(e)
.hasMessageThat()
@@ -896,9 +829,9 @@ public void abs_overflow_throwsException() {
@TestParameters("{expr: 'math.sign(-0)', expectedResult: 0}")
@TestParameters("{expr: 'math.sign(11213)', expectedResult: 1}")
public void sign_intResult_success(String expr, int expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -914,9 +847,9 @@ public void sign_intResult_success(String expr, int expectedResult) throws Excep
@TestParameters("{expr: 'math.sign(1.0/0.0)' , expectedResult: 1.0}")
@TestParameters("{expr: 'math.sign(-1.0/0.0)' , expectedResult: -1.0}")
public void sign_doubleResult_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -926,7 +859,7 @@ public void sign_doubleResult_success(String expr, double expectedResult) throws
@TestParameters("{expr: 'math.sign(\"\")'}")
public void sign_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.sign'");
}
@@ -938,9 +871,9 @@ public void sign_invalidArgs_throwsException(String expr) {
"{expr: 'math.bitAnd(9223372036854775807,9223372036854775807)' , expectedResult:"
+ " 9223372036854775807}")
public void bitAnd_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -950,9 +883,9 @@ public void bitAnd_signedInt_success(String expr, long expectedResult) throws Ex
@TestParameters("{expr: 'math.bitAnd(1u,3u)' , expectedResult: 1}")
public void bitAnd_unSignedInt_success(String expr, UnsignedLong expectedResult)
throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -963,7 +896,7 @@ public void bitAnd_unSignedInt_success(String expr, UnsignedLong expectedResult)
@TestParameters("{expr: 'math.bitAnd(1)'}")
public void bitAnd_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.bitAnd'");
}
@@ -973,10 +906,7 @@ public void bitAnd_maxValArg_throwsException() {
CelValidationException e =
assertThrows(
CelValidationException.class,
- () ->
- CEL_COMPILER
- .compile("math.bitAnd(9223372036854775807,9223372036854775809)")
- .getAst());
+ () -> cel.compile("math.bitAnd(9223372036854775807,9223372036854775809)").getAst());
assertThat(e)
.hasMessageThat()
@@ -987,9 +917,9 @@ public void bitAnd_maxValArg_throwsException() {
@TestParameters("{expr: 'math.bitOr(1,2)' , expectedResult: 3}")
@TestParameters("{expr: 'math.bitOr(1,-1)' , expectedResult: -1}")
public void bitOr_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -998,9 +928,9 @@ public void bitOr_signedInt_success(String expr, long expectedResult) throws Exc
@TestParameters("{expr: 'math.bitOr(1u,2u)' , expectedResult: 3}")
@TestParameters("{expr: 'math.bitOr(1090u,3u)' , expectedResult: 1091}")
public void bitOr_unSignedInt_success(String expr, UnsignedLong expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1011,7 +941,7 @@ public void bitOr_unSignedInt_success(String expr, UnsignedLong expectedResult)
@TestParameters("{expr: 'math.bitOr(1)'}")
public void bitOr_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.bitOr'");
}
@@ -1020,9 +950,9 @@ public void bitOr_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.bitXor(1,2)' , expectedResult: 3}")
@TestParameters("{expr: 'math.bitXor(3,5)' , expectedResult: 6}")
public void bitXor_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1032,9 +962,9 @@ public void bitXor_signedInt_success(String expr, long expectedResult) throws Ex
@TestParameters("{expr: 'math.bitXor(3u, 5u)' , expectedResult: 6}")
public void bitXor_unSignedInt_success(String expr, UnsignedLong expectedResult)
throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1045,7 +975,7 @@ public void bitXor_unSignedInt_success(String expr, UnsignedLong expectedResult)
@TestParameters("{expr: 'math.bitXor(1)'}")
public void bitXor_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.bitXor'");
}
@@ -1055,9 +985,9 @@ public void bitXor_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.bitNot(0)' , expectedResult: -1}")
@TestParameters("{expr: 'math.bitNot(-1)' , expectedResult: 0}")
public void bitNot_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1067,9 +997,9 @@ public void bitNot_signedInt_success(String expr, long expectedResult) throws Ex
@TestParameters("{expr: 'math.bitNot(12310u)' , expectedResult: 18446744073709539305}")
public void bitNot_unSignedInt_success(String expr, UnsignedLong expectedResult)
throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1080,7 +1010,7 @@ public void bitNot_unSignedInt_success(String expr, UnsignedLong expectedResult)
@TestParameters("{expr: 'math.bitNot(\"\")'}")
public void bitNot_invalidArgs_throwsException(String expr) {
CelValidationException e =
- assertThrows(CelValidationException.class, () -> CEL_COMPILER.compile(expr).getAst());
+ assertThrows(CelValidationException.class, () -> cel.compile(expr).getAst());
assertThat(e).hasMessageThat().contains("found no matching overload for 'math.bitNot'");
}
@@ -1090,9 +1020,9 @@ public void bitNot_invalidArgs_throwsException(String expr) {
@TestParameters("{expr: 'math.bitShiftLeft(12121, 11)' , expectedResult: 24823808}")
@TestParameters("{expr: 'math.bitShiftLeft(-1, 64)' , expectedResult: 0}")
public void bitShiftLeft_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1103,9 +1033,9 @@ public void bitShiftLeft_signedInt_success(String expr, long expectedResult) thr
@TestParameters("{expr: 'math.bitShiftLeft(1u, 65)' , expectedResult: 0}")
public void bitShiftLeft_unSignedInt_success(String expr, UnsignedLong expectedResult)
throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1114,11 +1044,10 @@ public void bitShiftLeft_unSignedInt_success(String expr, UnsignedLong expectedR
@TestParameters("{expr: 'math.bitShiftLeft(1, -2)'}")
@TestParameters("{expr: 'math.bitShiftLeft(1u, -2)'}")
public void bitShiftLeft_invalidArgs_throwsException(String expr) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
CelEvaluationException e =
- assertThrows(
- CelEvaluationException.class, () -> CEL_UNSIGNED_RUNTIME.createProgram(ast).eval());
+ assertThrows(CelEvaluationException.class, () -> cel.createProgram(ast).eval());
assertThat(e).hasMessageThat().contains("evaluation error");
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
@@ -1131,9 +1060,9 @@ public void bitShiftLeft_invalidArgs_throwsException(String expr) throws Excepti
@TestParameters("{expr: 'math.bitShiftRight(12121, 11)' , expectedResult: 5}")
@TestParameters("{expr: 'math.bitShiftRight(-1, 64)' , expectedResult: 0}")
public void bitShiftRight_signedInt_success(String expr, long expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
+ CelAbstractSyntaxTree ast = cel.compile(expr).getAst();
- Object result = CEL_RUNTIME.createProgram(ast).eval();
+ Object result = cel.createProgram(ast).eval();
assertThat(result).isEqualTo(expectedResult);
}
@@ -1144,9 +1073,7 @@ public void bitShiftRight_signedInt_success(String expr, long expectedResult) th
@TestParameters("{expr: 'math.bitShiftRight(1u, 65)' , expectedResult: 0}")
public void bitShiftRight_unSignedInt_success(String expr, UnsignedLong expectedResult)
throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
-
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
@@ -1155,11 +1082,7 @@ public void bitShiftRight_unSignedInt_success(String expr, UnsignedLong expected
@TestParameters("{expr: 'math.bitShiftRight(23111u, -212)'}")
@TestParameters("{expr: 'math.bitShiftRight(23, -212)'}")
public void bitShiftRight_invalidArgs_throwsException(String expr) throws Exception {
- CelAbstractSyntaxTree ast = CEL_COMPILER.compile(expr).getAst();
-
- CelEvaluationException e =
- assertThrows(
- CelEvaluationException.class, () -> CEL_UNSIGNED_RUNTIME.createProgram(ast).eval());
+ CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> eval(expr));
assertThat(e).hasMessageThat().contains("evaluation error");
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
@@ -1174,10 +1097,26 @@ public void bitShiftRight_invalidArgs_throwsException(String expr) throws Except
@TestParameters("{expr: 'math.sqrt(1.0/0.0)', expectedResult: Infinity}")
@TestParameters("{expr: 'math.sqrt(-1)', expectedResult: NaN}")
public void sqrt_success(String expr, double expectedResult) throws Exception {
- CelAbstractSyntaxTree ast = CEL_UNSIGNED_COMPILER.compile(expr).getAst();
-
- Object result = CEL_UNSIGNED_RUNTIME.createProgram(ast).eval();
+ Object result = eval(expr);
assertThat(result).isEqualTo(expectedResult);
}
+
+ private Object eval(Cel cel, String expression, Map variables) throws Exception {
+ CelAbstractSyntaxTree ast;
+ if (isParseOnly) {
+ ast = cel.parse(expression).getAst();
+ } else {
+ ast = cel.compile(expression).getAst();
+ }
+ return cel.createProgram(ast).eval(variables);
+ }
+
+ private Object eval(Cel celInstance, String expression) throws Exception {
+ return eval(celInstance, expression, ImmutableMap.of());
+ }
+
+ private Object eval(String expression) throws Exception {
+ return eval(this.cel, expression, ImmutableMap.of());
+ }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelProtoExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelProtoExtensionsTest.java
index 2e55619db..f46ea5b1a 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelProtoExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelProtoExtensionsTest.java
@@ -26,7 +26,6 @@
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.bundle.Cel;
-import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelContainer;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOptions;
@@ -41,34 +40,23 @@
import dev.cel.parser.CelMacro;
import dev.cel.parser.CelStandardMacro;
import dev.cel.runtime.CelFunctionBinding;
-import dev.cel.testing.CelRuntimeFlavor;
-import java.util.Map;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public final class CelProtoExtensionsTest {
-
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel =
- runtimeFlavor
- .builder()
- .addCompilerLibraries(CelExtensions.protos())
- .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
- .addFileTypes(TestAllTypesExtensions.getDescriptor())
- .addVar("msg", StructTypeReference.create("cel.expr.conformance.proto2.TestAllTypes"))
- .setContainer(CelContainer.ofName("cel.expr.conformance.proto2"))
- .build();
+public final class CelProtoExtensionsTest extends CelExtensionTestBase {
+
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .addCompilerLibraries(CelExtensions.protos())
+ .setStandardMacros(CelStandardMacro.STANDARD_MACROS)
+ .addFileTypes(TestAllTypesExtensions.getDescriptor())
+ .addVar("msg", StructTypeReference.create("cel.expr.conformance.proto2.TestAllTypes"))
+ .setContainer(CelContainer.ofName("cel.expr.conformance.proto2"))
+ .build();
}
private static final TestAllTypes PACKAGE_SCOPED_EXT_MSG =
@@ -342,13 +330,5 @@ public void parseErrors(@TestParameter ParseErrorTestCase testcase) {
assertThat(e).hasMessageThat().isEqualTo(testcase.error);
}
- private Object eval(String expression, Map variables) throws Exception {
- return eval(this.cel, expression, variables);
- }
- private Object eval(Cel cel, String expression, Map variables) throws Exception {
- CelAbstractSyntaxTree ast =
- this.isParseOnly ? cel.parse(expression).getAst() : cel.compile(expression).getAst();
- return cel.createProgram(ast).eval(variables);
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java
index 924344b25..97d0cc90c 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java
@@ -21,35 +21,23 @@
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.bundle.Cel;
-import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOptions;
import dev.cel.runtime.CelEvaluationException;
-import dev.cel.testing.CelRuntimeFlavor;
import java.util.Optional;
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public final class CelRegexExtensionsTest {
-
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel =
- runtimeFlavor
- .builder()
- .addCompilerLibraries(CelExtensions.regex())
- .addRuntimeLibraries(CelExtensions.regex())
- .build();
+public final class CelRegexExtensionsTest extends CelExtensionTestBase {
+
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .addCompilerLibraries(CelExtensions.regex())
+ .addRuntimeLibraries(CelExtensions.regex())
+ .build();
}
@@ -276,9 +264,5 @@ public void extractAll_multipleCaptureGroups_throwsException(String target, Stri
.contains("Regular expression has more than one capturing group:");
}
- private Object eval(String expr) throws Exception {
- CelAbstractSyntaxTree ast =
- isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
- return cel.createProgram(ast).eval();
- }
+
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelSetsExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelSetsExtensionsTest.java
index 9007bba2e..091d456f5 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelSetsExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelSetsExtensionsTest.java
@@ -23,7 +23,6 @@
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import dev.cel.bundle.Cel;
-import dev.cel.bundle.CelBuilder;
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelContainer;
import dev.cel.common.CelFunctionDecl;
@@ -39,27 +38,39 @@
import dev.cel.runtime.CelRuntime;
import dev.cel.testing.CelRuntimeFlavor;
import java.util.List;
-import java.util.Map;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public final class CelSetsExtensionsTest {
+public final class CelSetsExtensionsTest extends CelExtensionTestBase {
private static final CelOptions CEL_OPTIONS =
CelOptions.current().enableHeterogeneousNumericComparisons(true).build();
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel = setupEnv(runtimeFlavor.builder());
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .addMessageTypes(TestAllTypes.getDescriptor())
+ .setOptions(CEL_OPTIONS)
+ .setContainer(CelContainer.ofName("cel.expr.conformance.proto3"))
+ .addCompilerLibraries(CelExtensions.sets(CEL_OPTIONS))
+ .addRuntimeLibraries(CelExtensions.sets(CEL_OPTIONS))
+ .addVar("list", ListType.create(SimpleType.INT))
+ .addVar("subList", ListType.create(SimpleType.INT))
+ .addFunctionDeclarations(
+ CelFunctionDecl.newFunctionDeclaration(
+ "new_int",
+ CelOverloadDecl.newGlobalOverload("new_int_int64", SimpleType.INT, SimpleType.INT)))
+ .addFunctionBindings(
+ CelFunctionBinding.fromOverloads(
+ "new_int",
+ CelFunctionBinding.from(
+ "new_int_int64",
+ Long.class,
+ // Intentionally return java.lang.Integer to test primitive type adaptation
+ Math::toIntExact)))
+ .build();
}
@Test
@@ -375,7 +386,7 @@ public void setsExtension_containsFunctionSubset_succeeds() throws Exception {
.addRuntimeLibraries(setsExtensions)
.build();
- Object evaluatedResult = eval(cel, "sets.contains([1, 2], [2])", ImmutableMap.of());
+ Object evaluatedResult = eval(cel, "sets.contains([1, 2], [2])");
assertThat(evaluatedResult).isEqualTo(true);
}
@@ -391,7 +402,7 @@ public void setsExtension_equivalentFunctionSubset_succeeds() throws Exception {
.addRuntimeLibraries(setsExtensions)
.build();
- Object evaluatedResult = eval(cel, "sets.equivalent([1, 1], [1])", ImmutableMap.of());
+ Object evaluatedResult = eval(cel, "sets.equivalent([1, 1], [1])");
assertThat(evaluatedResult).isEqualTo(true);
}
@@ -407,7 +418,7 @@ public void setsExtension_intersectsFunctionSubset_succeeds() throws Exception {
.addRuntimeLibraries(setsExtensions)
.build();
- Object evaluatedResult = eval(cel, "sets.intersects([1, 1], [1])", ImmutableMap.of());
+ Object evaluatedResult = eval(cel, "sets.intersects([1, 1], [1])");
assertThat(evaluatedResult).isEqualTo(true);
}
@@ -450,45 +461,5 @@ public void setsExtension_evaluateUnallowedFunction_throws() throws Exception {
}
}
- private Object eval(Cel cel, String expression, Map variables) throws Exception {
- CelAbstractSyntaxTree ast;
- if (isParseOnly) {
- ast = cel.parse(expression).getAst();
- } else {
- ast = cel.compile(expression).getAst();
- }
- return cel.createProgram(ast).eval(variables);
- }
-
- private Object eval(String expression) throws Exception {
- return eval(this.cel, expression, ImmutableMap.of());
- }
-
- private Object eval(String expression, Map variables) throws Exception {
- return eval(this.cel, expression, variables);
- }
- private static Cel setupEnv(CelBuilder celBuilder) {
- return celBuilder
- .addMessageTypes(TestAllTypes.getDescriptor())
- .setOptions(CEL_OPTIONS)
- .setContainer(CelContainer.ofName("cel.expr.conformance.proto3"))
- .addCompilerLibraries(CelExtensions.sets(CEL_OPTIONS))
- .addRuntimeLibraries(CelExtensions.sets(CEL_OPTIONS))
- .addVar("list", ListType.create(SimpleType.INT))
- .addVar("subList", ListType.create(SimpleType.INT))
- .addFunctionDeclarations(
- CelFunctionDecl.newFunctionDeclaration(
- "new_int",
- CelOverloadDecl.newGlobalOverload("new_int_int64", SimpleType.INT, SimpleType.INT)))
- .addFunctionBindings(
- CelFunctionBinding.fromOverloads(
- "new_int",
- CelFunctionBinding.from(
- "new_int_int64",
- Long.class,
- // Intentionally return java.lang.Integer to test primitive type adaptation
- Math::toIntExact)))
- .build();
- }
}
diff --git a/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java
index e7542b7b7..4b242ddcd 100644
--- a/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java
+++ b/extensions/src/test/java/dev/cel/extensions/CelStringExtensionsTest.java
@@ -33,40 +33,29 @@
import dev.cel.extensions.CelStringExtensions.Function;
import dev.cel.runtime.CelEvaluationException;
import dev.cel.runtime.CelRuntime;
-import dev.cel.testing.CelRuntimeFlavor;
import java.util.List;
-import java.util.Map;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(TestParameterInjector.class)
-public final class CelStringExtensionsTest {
-
- @TestParameter public CelRuntimeFlavor runtimeFlavor;
- @TestParameter public boolean isParseOnly;
-
- private Cel cel;
-
- @Before
- public void setUp() {
- // Legacy runtime does not support parsed-only evaluation mode.
- Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
- this.cel =
- runtimeFlavor
- .builder()
- .addCompilerLibraries(CelExtensions.strings())
- .addRuntimeLibraries(CelExtensions.strings())
- .addVar("s", SimpleType.STRING)
- .addVar("separator", SimpleType.STRING)
- .addVar("index", SimpleType.INT)
- .addVar("offset", SimpleType.INT)
- .addVar("indexOfParam", SimpleType.STRING)
- .addVar("beginIndex", SimpleType.INT)
- .addVar("endIndex", SimpleType.INT)
- .addVar("limit", SimpleType.INT)
- .build();
+public final class CelStringExtensionsTest extends CelExtensionTestBase {
+
+ @Override
+ protected Cel newCelEnv() {
+ return runtimeFlavor
+ .builder()
+ .addCompilerLibraries(CelExtensions.strings())
+ .addRuntimeLibraries(CelExtensions.strings())
+ .addVar("s", SimpleType.STRING)
+ .addVar("separator", SimpleType.STRING)
+ .addVar("index", SimpleType.INT)
+ .addVar("offset", SimpleType.INT)
+ .addVar("indexOfParam", SimpleType.STRING)
+ .addVar("beginIndex", SimpleType.INT)
+ .addVar("endIndex", SimpleType.INT)
+ .addVar("limit", SimpleType.INT)
+ .build();
}
@Test
@@ -388,13 +377,10 @@ public void split_withLimit_separatorIsNonString_throwsException() {
@Test
public void split_withLimitOverflow_throwsException() throws Exception {
+ ImmutableMap variables = ImmutableMap.of("limit", 2147483648L); // INT_MAX + 1
CelEvaluationException exception =
assertThrows(
- CelEvaluationException.class,
- () ->
- eval(
- "'test'.split('', limit)",
- ImmutableMap.of("limit", 2147483648L))); // INT_MAX + 1
+ CelEvaluationException.class, () -> eval("'test'.split('', limit)", variables));
assertThat(exception)
.hasMessageThat()
@@ -454,13 +440,10 @@ public void substring_beginAndEndIndex_unicode_success(
@TestParameters("{string: '', beginIndex: 2}")
public void substring_beginIndexOutOfRange_ascii_throwsException(String string, int beginIndex)
throws Exception {
+ ImmutableMap variables = ImmutableMap.of("s", string, "beginIndex", beginIndex);
CelEvaluationException exception =
assertThrows(
- CelEvaluationException.class,
- () ->
- eval(
- "s.substring(beginIndex)",
- ImmutableMap.of("s", string, "beginIndex", beginIndex)));
+ CelEvaluationException.class, () -> eval("s.substring(beginIndex)", variables));
String exceptionMessage =
String.format(
@@ -478,13 +461,10 @@ public void substring_beginIndexOutOfRange_ascii_throwsException(String string,
@TestParameters("{string: '😁가나', beginIndex: 4, uniqueCharCount: 3}")
public void substring_beginIndexOutOfRange_unicode_throwsException(
String string, int beginIndex, int uniqueCharCount) throws Exception {
+ ImmutableMap variables = ImmutableMap.of("s", string, "beginIndex", beginIndex);
CelEvaluationException exception =
assertThrows(
- CelEvaluationException.class,
- () ->
- eval(
- "s.substring(beginIndex)",
- ImmutableMap.of("s", string, "beginIndex", beginIndex)));
+ CelEvaluationException.class, () -> eval("s.substring(beginIndex)", variables));
String exceptionMessage =
String.format(
@@ -501,13 +481,12 @@ public void substring_beginIndexOutOfRange_unicode_throwsException(
@TestParameters("{string: '😁😑😦', beginIndex: 2, endIndex: 1}")
public void substring_beginAndEndIndexOutOfRange_throwsException(
String string, int beginIndex, int endIndex) throws Exception {
+ ImmutableMap variables =
+ ImmutableMap.of("s", string, "beginIndex", beginIndex, "endIndex", endIndex);
CelEvaluationException exception =
assertThrows(
CelEvaluationException.class,
- () ->
- eval(
- "s.substring(beginIndex, endIndex)",
- ImmutableMap.of("s", string, "beginIndex", beginIndex, "endIndex", endIndex)));
+ () -> eval("s.substring(beginIndex, endIndex)", variables));
String exceptionMessage =
String.format("substring failure: Range [%d, %d) out of bounds", beginIndex, endIndex);
@@ -516,13 +495,11 @@ public void substring_beginAndEndIndexOutOfRange_throwsException(
@Test
public void substring_beginIndexOverflow_throwsException() throws Exception {
+ ImmutableMap variables =
+ ImmutableMap.of("beginIndex", 2147483648L); // INT_MAX + 1
CelEvaluationException exception =
assertThrows(
- CelEvaluationException.class,
- () ->
- eval(
- "'abcd'.substring(beginIndex)",
- ImmutableMap.of("beginIndex", 2147483648L))); // INT_MAX + 1
+ CelEvaluationException.class, () -> eval("'abcd'.substring(beginIndex)", variables));
assertThat(exception)
.hasMessageThat()
@@ -1381,10 +1358,7 @@ public void stringExtension_functionSubset_success() throws Exception {
.build();
Object evaluatedResult =
- eval(
- customCel,
- "'test'.substring(2) == 'st' && 'hello'.charAt(1) == 'e'",
- ImmutableMap.of());
+ eval(customCel, "'test'.substring(2) == 'st' && 'hello'.charAt(1) == 'e'");
assertThat(evaluatedResult).isEqualTo(true);
}
@@ -1499,21 +1473,5 @@ public void stringExtension_evaluateUnallowedFunction_throws() throws Exception
assertThrows(CelEvaluationException.class, () -> customRuntimeCel.createProgram(ast).eval());
}
- private Object eval(Cel cel, String expression, Map variables) throws Exception {
- CelAbstractSyntaxTree ast;
- if (isParseOnly) {
- ast = cel.parse(expression).getAst();
- } else {
- ast = cel.compile(expression).getAst();
- }
- return cel.createProgram(ast).eval(variables);
- }
-
- private Object eval(String expression) throws Exception {
- return eval(this.cel, expression, ImmutableMap.of());
- }
- private Object eval(String expression, Map variables) throws Exception {
- return eval(this.cel, expression, variables);
- }
}
diff --git a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel
index 6f0607de4..ef0ac71d4 100644
--- a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel
+++ b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel
@@ -53,6 +53,7 @@ LITE_PROGRAM_IMPL_SOURCES = [
FUNCTION_BINDING_SOURCES = [
"CelFunctionBinding.java",
"FunctionBindingImpl.java",
+ "InternalCelFunctionBinding.java",
]
# keep sorted
@@ -740,6 +741,7 @@ java_library(
deps = [
":evaluation_exception",
":function_overload",
+ "//common/annotations",
"//common/exceptions:overload_not_found",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
@@ -754,6 +756,7 @@ cel_android_library(
deps = [
":evaluation_exception",
":function_overload_android",
+ "//common/annotations",
"//common/exceptions:overload_not_found",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven_android//:com_google_guava_guava",
@@ -890,7 +893,6 @@ java_library(
"//common/types:type_providers",
"//common/values:cel_value_provider",
"//common/values:proto_message_value_provider",
- "//runtime/standard:add",
"//runtime/standard:int",
"//runtime/standard:timestamp",
"@maven//:com_google_code_findbugs_annotations",
diff --git a/runtime/src/main/java/dev/cel/runtime/CelFunctionBinding.java b/runtime/src/main/java/dev/cel/runtime/CelFunctionBinding.java
index 88be0d3c3..98991d383 100644
--- a/runtime/src/main/java/dev/cel/runtime/CelFunctionBinding.java
+++ b/runtime/src/main/java/dev/cel/runtime/CelFunctionBinding.java
@@ -100,6 +100,7 @@ static CelFunctionBinding from(
overloadId, ImmutableList.copyOf(argTypes), impl, /* isStrict= */ true);
}
+
/** See {@link #fromOverloads(String, Collection)}. */
static ImmutableSet fromOverloads(
String functionName, CelFunctionBinding... overloadBindings) {
diff --git a/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java b/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java
index 3d75845cf..2da08120c 100644
--- a/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java
+++ b/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java
@@ -63,7 +63,12 @@ public static CelLateFunctionBindings from(Collection functi
}
private static CelResolvedOverload createResolvedOverload(CelFunctionBinding binding) {
+ String functionName = binding.getOverloadId();
+ if (binding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) binding).getFunctionName();
+ }
return CelResolvedOverload.of(
+ functionName,
binding.getOverloadId(),
binding.getDefinition(),
binding.isStrict(),
diff --git a/runtime/src/main/java/dev/cel/runtime/CelResolvedOverload.java b/runtime/src/main/java/dev/cel/runtime/CelResolvedOverload.java
index 7063720a1..fbe9a3289 100644
--- a/runtime/src/main/java/dev/cel/runtime/CelResolvedOverload.java
+++ b/runtime/src/main/java/dev/cel/runtime/CelResolvedOverload.java
@@ -30,6 +30,9 @@
@Internal
public abstract class CelResolvedOverload {
+ /** The base function name. */
+ public abstract String getFunctionName();
+
/** The overload id of the function. */
public abstract String getOverloadId();
@@ -61,7 +64,7 @@ public Object invoke(Object[] args) throws CelEvaluationException {
|| CelFunctionOverload.canHandle(args, getParameterTypes(), isStrict())) {
return getDefinition().apply(args);
}
- throw new CelOverloadNotFoundException(getOverloadId());
+ throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
public Object invoke(Object arg) throws CelEvaluationException {
@@ -69,7 +72,7 @@ public Object invoke(Object arg) throws CelEvaluationException {
|| CelFunctionOverload.canHandle(arg, getParameterTypes(), isStrict())) {
return getOptimizedDefinition().apply(arg);
}
- throw new CelOverloadNotFoundException(getOverloadId());
+ throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
public Object invoke(Object arg1, Object arg2) throws CelEvaluationException {
@@ -77,24 +80,28 @@ public Object invoke(Object arg1, Object arg2) throws CelEvaluationException {
|| CelFunctionOverload.canHandle(arg1, arg2, getParameterTypes(), isStrict())) {
return getOptimizedDefinition().apply(arg1, arg2);
}
- throw new CelOverloadNotFoundException(getOverloadId());
+ throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
/**
- * Creates a new resolved overload from the given overload id, parameter types, and definition.
+ * Creates a new resolved overload from the given function name, overload id, parameter types, and
+ * definition.
*/
public static CelResolvedOverload of(
+ String functionName,
String overloadId,
CelFunctionOverload definition,
boolean isStrict,
Class>... parameterTypes) {
- return of(overloadId, definition, isStrict, ImmutableList.copyOf(parameterTypes));
+ return of(functionName, overloadId, definition, isStrict, ImmutableList.copyOf(parameterTypes));
}
/**
- * Creates a new resolved overload from the given overload id, parameter types, and definition.
+ * Creates a new resolved overload from the given function name, overload id, parameter types, and
+ * definition.
*/
public static CelResolvedOverload of(
+ String functionName,
String overloadId,
CelFunctionOverload definition,
boolean isStrict,
@@ -104,7 +111,12 @@ public static CelResolvedOverload of(
? (OptimizedFunctionOverload) definition
: definition::apply;
return new AutoValue_CelResolvedOverload(
- overloadId, ImmutableList.copyOf(parameterTypes), isStrict, definition, optimizedDef);
+ functionName,
+ overloadId,
+ ImmutableList.copyOf(parameterTypes),
+ isStrict,
+ definition,
+ optimizedDef);
}
/**
diff --git a/runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java b/runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java
index cab2c666e..43b223fa0 100644
--- a/runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java
+++ b/runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java
@@ -381,7 +381,12 @@ private static DefaultDispatcher newDispatcher(
DefaultDispatcher.Builder builder = DefaultDispatcher.newBuilder();
for (CelFunctionBinding binding :
standardFunctions.newFunctionBindings(runtimeEquality, options)) {
+ String functionName = binding.getOverloadId();
+ if (binding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) binding).getFunctionName();
+ }
builder.addOverload(
+ functionName,
binding.getOverloadId(),
binding.getArgTypes(),
binding.isStrict(),
@@ -389,7 +394,12 @@ private static DefaultDispatcher newDispatcher(
}
for (CelFunctionBinding binding : customFunctionBindings) {
+ String functionName = binding.getOverloadId();
+ if (binding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) binding).getFunctionName();
+ }
builder.addOverload(
+ functionName,
binding.getOverloadId(),
binding.getArgTypes(),
binding.isStrict(),
diff --git a/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java b/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java
index 8ae4a9e3e..33702b2c6 100644
--- a/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java
+++ b/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java
@@ -305,7 +305,12 @@ public CelRuntimeLegacyImpl build() {
DefaultDispatcher.Builder dispatcherBuilder = DefaultDispatcher.newBuilder();
for (CelFunctionBinding standardFunctionBinding :
newStandardFunctionBindings(runtimeEquality)) {
+ String functionName = standardFunctionBinding.getOverloadId();
+ if (standardFunctionBinding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) standardFunctionBinding).getFunctionName();
+ }
dispatcherBuilder.addOverload(
+ functionName,
standardFunctionBinding.getOverloadId(),
standardFunctionBinding.getArgTypes(),
standardFunctionBinding.isStrict(),
@@ -313,7 +318,12 @@ public CelRuntimeLegacyImpl build() {
}
for (CelFunctionBinding customBinding : customFunctionBindings.values()) {
+ String functionName = customBinding.getOverloadId();
+ if (customBinding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) customBinding).getFunctionName();
+ }
dispatcherBuilder.addOverload(
+ functionName,
customBinding.getOverloadId(),
customBinding.getArgTypes(),
customBinding.isStrict(),
diff --git a/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java b/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java
index d6ddf3965..0a467db81 100644
--- a/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java
+++ b/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java
@@ -134,6 +134,8 @@ public static class Builder {
@AutoValue
@Immutable
abstract static class OverloadEntry {
+ abstract String functionName();
+
abstract ImmutableList> argTypes();
abstract boolean isStrict();
@@ -141,8 +143,12 @@ abstract static class OverloadEntry {
abstract CelFunctionOverload overload();
private static OverloadEntry of(
- ImmutableList> argTypes, boolean isStrict, CelFunctionOverload overload) {
- return new AutoValue_DefaultDispatcher_Builder_OverloadEntry(argTypes, isStrict, overload);
+ String functionName,
+ ImmutableList> argTypes,
+ boolean isStrict,
+ CelFunctionOverload overload) {
+ return new AutoValue_DefaultDispatcher_Builder_OverloadEntry(
+ functionName, argTypes, isStrict, overload);
}
}
@@ -150,16 +156,19 @@ private static OverloadEntry of(
@CanIgnoreReturnValue
public Builder addOverload(
+ String functionName,
String overloadId,
ImmutableList> argTypes,
boolean isStrict,
CelFunctionOverload overload) {
+ checkNotNull(functionName);
+ checkArgument(!functionName.isEmpty(), "Function name cannot be empty.");
checkNotNull(overloadId);
checkArgument(!overloadId.isEmpty(), "Overload ID cannot be empty.");
checkNotNull(argTypes);
checkNotNull(overload);
- OverloadEntry newEntry = OverloadEntry.of(argTypes, isStrict, overload);
+ OverloadEntry newEntry = OverloadEntry.of(functionName, argTypes, isStrict, overload);
overloads.merge(
overloadId,
@@ -188,7 +197,7 @@ private OverloadEntry mergeDynamicDispatchesOrThrow(
boolean isStrict =
mergedOverload.getOverloadBindings().stream().allMatch(CelFunctionBinding::isStrict);
- return OverloadEntry.of(incoming.argTypes(), isStrict, mergedOverload);
+ return OverloadEntry.of(overloadId, incoming.argTypes(), isStrict, mergedOverload);
}
throw new IllegalArgumentException("Duplicate overload ID binding: " + overloadId);
@@ -204,7 +213,11 @@ public DefaultDispatcher build() {
resolvedOverloads.put(
overloadId,
CelResolvedOverload.of(
- overloadId, overloadImpl, overloadEntry.isStrict(), overloadEntry.argTypes()));
+ overloadEntry.functionName(),
+ overloadId,
+ overloadImpl,
+ overloadEntry.isStrict(),
+ overloadEntry.argTypes()));
}
return new DefaultDispatcher(resolvedOverloads.buildOrThrow());
diff --git a/runtime/src/main/java/dev/cel/runtime/FunctionBindingImpl.java b/runtime/src/main/java/dev/cel/runtime/FunctionBindingImpl.java
index c1306ce19..7b8efe8fd 100644
--- a/runtime/src/main/java/dev/cel/runtime/FunctionBindingImpl.java
+++ b/runtime/src/main/java/dev/cel/runtime/FunctionBindingImpl.java
@@ -23,7 +23,9 @@
import dev.cel.common.exceptions.CelOverloadNotFoundException;
@Immutable
-final class FunctionBindingImpl implements CelFunctionBinding {
+final class FunctionBindingImpl implements InternalCelFunctionBinding {
+
+ private final String functionName;
private final String overloadId;
@@ -33,6 +35,11 @@ final class FunctionBindingImpl implements CelFunctionBinding {
private final boolean isStrict;
+ @Override
+ public String getFunctionName() {
+ return functionName;
+ }
+
@Override
public String getOverloadId() {
return overloadId;
@@ -54,20 +61,34 @@ public boolean isStrict() {
}
FunctionBindingImpl(
+ String functionName,
String overloadId,
ImmutableList> argTypes,
CelFunctionOverload definition,
boolean isStrict) {
+ this.functionName = functionName;
this.overloadId = overloadId;
this.argTypes = argTypes;
this.definition = definition;
this.isStrict = isStrict;
}
+ FunctionBindingImpl(
+ String overloadId,
+ ImmutableList> argTypes,
+ CelFunctionOverload definition,
+ boolean isStrict) {
+ this(overloadId, overloadId, argTypes, definition, isStrict);
+ }
+
static ImmutableSet groupOverloadsToFunction(
String functionName, ImmutableSet overloadBindings) {
ImmutableSet.Builder builder = ImmutableSet.builder();
- builder.addAll(overloadBindings);
+ for (CelFunctionBinding b : overloadBindings) {
+ builder.add(
+ new FunctionBindingImpl(
+ functionName, b.getOverloadId(), b.getArgTypes(), b.getDefinition(), b.isStrict()));
+ }
// If there is already a binding with the same name as the function, we treat it as a
// "Singleton" binding and do not create a dynamic dispatch wrapper for it.
@@ -80,11 +101,12 @@ static ImmutableSet groupOverloadsToFunction(
CelFunctionBinding singleBinding = Iterables.getOnlyElement(overloadBindings);
builder.add(
new FunctionBindingImpl(
+ functionName,
functionName,
singleBinding.getArgTypes(),
singleBinding.getDefinition(),
singleBinding.isStrict()));
- } else {
+ } else if (overloadBindings.size() > 1) {
builder.add(new DynamicDispatchBinding(functionName, overloadBindings));
}
}
@@ -93,7 +115,7 @@ static ImmutableSet groupOverloadsToFunction(
}
@Immutable
- static final class DynamicDispatchBinding implements CelFunctionBinding {
+ static final class DynamicDispatchBinding implements InternalCelFunctionBinding {
private final boolean isStrict;
private final DynamicDispatchOverload dynamicDispatchOverload;
@@ -103,6 +125,11 @@ public String getOverloadId() {
return dynamicDispatchOverload.functionName;
}
+ @Override
+ public String getFunctionName() {
+ return dynamicDispatchOverload.functionName;
+ }
+
@Override
public ImmutableList> getArgTypes() {
return ImmutableList.of();
diff --git a/runtime/src/main/java/dev/cel/runtime/InternalCelFunctionBinding.java b/runtime/src/main/java/dev/cel/runtime/InternalCelFunctionBinding.java
new file mode 100644
index 000000000..48a0f36d1
--- /dev/null
+++ b/runtime/src/main/java/dev/cel/runtime/InternalCelFunctionBinding.java
@@ -0,0 +1,29 @@
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package dev.cel.runtime;
+
+import com.google.errorprone.annotations.Immutable;
+import dev.cel.common.annotations.Internal;
+
+/**
+ * Internal interface to expose the function name associated with a binding.
+ *
+ * CEL Library Internals. Do Not Use.
+ */
+@Internal
+@Immutable
+public interface InternalCelFunctionBinding extends CelFunctionBinding {
+ String getFunctionName();
+}
diff --git a/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java b/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
index 0e5c5cf30..d58eb3be4 100644
--- a/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
+++ b/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
@@ -162,9 +162,18 @@ public CelLiteRuntime build() {
functionBindingsBuilder
.buildOrThrow()
.forEach(
- (String overloadId, CelFunctionBinding func) ->
- dispatcherBuilder.addOverload(
- overloadId, func.getArgTypes(), func.isStrict(), func.getDefinition()));
+ (String overloadId, CelFunctionBinding func) -> {
+ String functionName = func.getOverloadId();
+ if (func instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) func).getFunctionName();
+ }
+ dispatcherBuilder.addOverload(
+ functionName,
+ overloadId,
+ func.getArgTypes(),
+ func.isStrict(),
+ func.getDefinition());
+ });
Interpreter interpreter =
new DefaultInterpreter(
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
index 7771da3e6..16eba3cce 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
@@ -25,6 +25,7 @@
final class EvalBinary extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final PlannedInterpretable arg1;
private final PlannedInterpretable arg2;
@@ -48,25 +49,29 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
return unknowns;
}
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVal1, argVal2);
+ return EvalHelpers.dispatch(
+ functionName, resolvedOverload, celValueConverter, argVal1, argVal2);
}
static EvalBinary create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg1,
PlannedInterpretable arg2,
CelValueConverter celValueConverter) {
- return new EvalBinary(exprId, resolvedOverload, arg1, arg2, celValueConverter);
+ return new EvalBinary(exprId, functionName, resolvedOverload, arg1, arg2, celValueConverter);
}
private EvalBinary(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg1,
PlannedInterpretable arg2,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.arg1 = arg1;
this.arg2 = arg2;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
index a30f91880..220642f4a 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
@@ -56,7 +56,10 @@ static Object evalStrictly(
}
static Object dispatch(
- CelResolvedOverload overload, CelValueConverter valueConverter, Object[] args)
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object[] args)
throws CelEvaluationException {
try {
Object result = overload.invoke(args);
@@ -66,7 +69,11 @@ static Object dispatch(
}
}
- static Object dispatch(CelResolvedOverload overload, CelValueConverter valueConverter, Object arg)
+ static Object dispatch(
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object arg)
throws CelEvaluationException {
try {
Object result = overload.invoke(arg);
@@ -77,7 +84,11 @@ static Object dispatch(CelResolvedOverload overload, CelValueConverter valueConv
}
static Object dispatch(
- CelResolvedOverload overload, CelValueConverter valueConverter, Object arg1, Object arg2)
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object arg1,
+ Object arg2)
throws CelEvaluationException {
try {
Object result = overload.invoke(arg1, arg2);
@@ -97,7 +108,7 @@ private static RuntimeException handleDispatchException(
return new IllegalArgumentException(
String.format(
"Function '%s' failed with arg(s) '%s'",
- overload.getOverloadId(), Joiner.on(", ").join(args)),
+ overload.getFunctionName(), Joiner.on(", ").join(args)),
e);
}
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
index cdee878ee..0bd251185 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
@@ -55,7 +55,7 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
.findOverload(functionName, overloadIds, argVals)
.orElseThrow(() -> new CelOverloadNotFoundException(functionName, overloadIds));
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVals);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVals);
}
static EvalLateBoundCall create(
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
index 322648ee3..57834161f 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
@@ -24,6 +24,7 @@
final class EvalUnary extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final PlannedInterpretable arg;
private final CelValueConverter celValueConverter;
@@ -34,23 +35,26 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
resolvedOverload.isStrict()
? evalStrictly(arg, resolver, frame)
: evalNonstrictly(arg, resolver, frame);
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVal);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVal);
}
static EvalUnary create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg,
CelValueConverter celValueConverter) {
- return new EvalUnary(exprId, resolvedOverload, arg, celValueConverter);
+ return new EvalUnary(exprId, functionName, resolvedOverload, arg, celValueConverter);
}
private EvalUnary(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.arg = arg;
this.celValueConverter = celValueConverter;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
index eb8745632..fe7c6c430 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
@@ -25,6 +25,7 @@
final class EvalVarArgsCall extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
@SuppressWarnings("Immutable")
@@ -50,23 +51,26 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
return unknowns;
}
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVals);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVals);
}
static EvalVarArgsCall create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable[] args,
CelValueConverter celValueConverter) {
- return new EvalVarArgsCall(exprId, resolvedOverload, args, celValueConverter);
+ return new EvalVarArgsCall(exprId, functionName, resolvedOverload, args, celValueConverter);
}
private EvalVarArgsCall(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable[] args,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.args = args;
this.celValueConverter = celValueConverter;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
index 5b3138207..7798c8253 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
@@ -22,22 +22,30 @@
final class EvalZeroArity extends PlannedInterpretable {
private static final Object[] EMPTY_ARRAY = new Object[0];
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final CelValueConverter celValueConverter;
@Override
public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEvaluationException {
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, EMPTY_ARRAY);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, EMPTY_ARRAY);
}
static EvalZeroArity create(
- long exprId, CelResolvedOverload resolvedOverload, CelValueConverter celValueConverter) {
- return new EvalZeroArity(exprId, resolvedOverload, celValueConverter);
+ long exprId,
+ String functionName,
+ CelResolvedOverload resolvedOverload,
+ CelValueConverter celValueConverter) {
+ return new EvalZeroArity(exprId, functionName, resolvedOverload, celValueConverter);
}
private EvalZeroArity(
- long exprId, CelResolvedOverload resolvedOverload, CelValueConverter celValueConverter) {
+ long exprId,
+ String functionName,
+ CelResolvedOverload resolvedOverload,
+ CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.celValueConverter = celValueConverter;
}
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java b/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
index 9bd5f3ecd..a0b74fc99 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
@@ -308,15 +308,21 @@ private PlannedInterpretable planCall(CelExpr expr, PlannerContext ctx) {
switch (argCount) {
case 0:
- return EvalZeroArity.create(expr.id(), resolvedOverload, celValueConverter);
+ return EvalZeroArity.create(expr.id(), functionName, resolvedOverload, celValueConverter);
case 1:
- return EvalUnary.create(expr.id(), resolvedOverload, evaluatedArgs[0], celValueConverter);
+ return EvalUnary.create(
+ expr.id(), functionName, resolvedOverload, evaluatedArgs[0], celValueConverter);
case 2:
return EvalBinary.create(
- expr.id(), resolvedOverload, evaluatedArgs[0], evaluatedArgs[1], celValueConverter);
+ expr.id(),
+ functionName,
+ resolvedOverload,
+ evaluatedArgs[0],
+ evaluatedArgs[1],
+ celValueConverter);
default:
return EvalVarArgsCall.create(
- expr.id(), resolvedOverload, evaluatedArgs, celValueConverter);
+ expr.id(), functionName, resolvedOverload, evaluatedArgs, celValueConverter);
}
}
diff --git a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
index 577010971..7cd24f040 100644
--- a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
+++ b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
@@ -2,6 +2,7 @@ load("@rules_java//java:defs.bzl", "java_library")
load("//:cel_android_rules.bzl", "cel_android_local_test")
load("//:testing.bzl", "junit4_test_suites")
+# Invalidate cache after file removal
package(
default_applicable_licenses = ["//:license"],
default_testonly = True,
diff --git a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
index c1210c1ba..471282117 100644
--- a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
@@ -27,11 +27,13 @@ public final class CelResolvedOverloadTest {
CelResolvedOverload getIncrementIntOverload() {
return CelResolvedOverload.of(
- "increment_int",
- (args) -> {
- Long arg = (Long) args[0];
- return arg + 1;
- },
+ /* functionName= */ "increment_int",
+ /* overloadId= */ "increment_int_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ Long arg = (Long) args[0];
+ return arg + 1;
+ },
/* isStrict= */ true,
Long.class);
}
@@ -45,14 +47,23 @@ public void canHandle_matchingTypes_returnsTrue() {
public void canHandle_nullMessageType_returnsFalse() {
CelResolvedOverload overload =
CelResolvedOverload.of(
- "identity", (args) -> args[0], /* isStrict= */ true, TestAllTypes.class);
+ /* functionName= */ "identity",
+ /* overloadId= */ "identity_overload",
+ (CelFunctionOverload) (args) -> args[0],
+ /* isStrict= */ true,
+ TestAllTypes.class);
assertThat(overload.canHandle(new Object[] {null})).isFalse();
}
@Test
public void canHandle_nullPrimitive_returnsFalse() {
CelResolvedOverload overload =
- CelResolvedOverload.of("identity", (args) -> args[0], /* isStrict= */ true, Long.class);
+ CelResolvedOverload.of(
+ /* functionName= */ "identity",
+ /* overloadId= */ "identity_overload",
+ (CelFunctionOverload) (args) -> args[0],
+ /* isStrict= */ true,
+ Long.class);
assertThat(overload.canHandle(new Object[] {null})).isFalse();
}
@@ -70,10 +81,12 @@ public void canHandle_nonMatchingArgCount_returnsFalse() {
public void canHandle_nonStrictOverload_returnsTrue() {
CelResolvedOverload nonStrictOverload =
CelResolvedOverload.of(
- "non_strict",
- (args) -> {
- return false;
- },
+ /* functionName= */ "non_strict",
+ /* overloadId= */ "non_strict_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ return false;
+ },
/* isStrict= */ false,
Long.class,
Long.class);
@@ -87,10 +100,12 @@ public void canHandle_nonStrictOverload_returnsTrue() {
public void canHandle_nonStrictOverload_returnsFalse() {
CelResolvedOverload nonStrictOverload =
CelResolvedOverload.of(
- "non_strict",
- (args) -> {
- return false;
- },
+ /* functionName= */ "non_strict",
+ /* overloadId= */ "non_strict_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ return false;
+ },
/* isStrict= */ false,
Long.class,
Long.class);
diff --git a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
index 255360ee1..d862ddb33 100644
--- a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
@@ -37,11 +37,19 @@ public void setup() {
overloads.put(
"overload_1",
CelResolvedOverload.of(
- "overload_1", args -> (Long) args[0] + 1, /* isStrict= */ true, Long.class));
+ /* functionName= */ "overload_1",
+ /* overloadId= */ "overload_1",
+ args -> (Long) args[0] + 1,
+ /* isStrict= */ true,
+ Long.class));
overloads.put(
"overload_2",
CelResolvedOverload.of(
- "overload_2", args -> (Long) args[0] + 2, /* isStrict= */ true, Long.class));
+ /* functionName= */ "overload_2",
+ /* overloadId= */ "overload_2",
+ args -> (Long) args[0] + 2,
+ /* isStrict= */ true,
+ Long.class));
}
@Test
diff --git a/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java b/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
index 1a8f45161..bd0e96856 100644
--- a/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
@@ -77,15 +77,21 @@ public Object adapt(String messageName, Object message) {
CelAbstractSyntaxTree ast = celCompiler.compile("[1].all(x, [2].all(y, error()))").getAst();
DefaultDispatcher.Builder dispatcherBuilder = DefaultDispatcher.newBuilder();
dispatcherBuilder.addOverload(
- "error",
- ImmutableList.of(long.class),
+ /* functionName= */ "error",
+ /* overloadId= */ "error_overload",
+ ImmutableList.>of(long.class),
/* isStrict= */ true,
(args) -> new IllegalArgumentException("Always throws"));
CelFunctionBinding notStrictlyFalseBinding =
NotStrictlyFalseOverload.NOT_STRICTLY_FALSE.newFunctionBinding(
CelOptions.DEFAULT,
RuntimeEquality.create(RuntimeHelpers.create(), CelOptions.DEFAULT));
+ String functionName = notStrictlyFalseBinding.getOverloadId();
+ if (notStrictlyFalseBinding instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) notStrictlyFalseBinding).getFunctionName();
+ }
dispatcherBuilder.addOverload(
+ functionName,
notStrictlyFalseBinding.getOverloadId(),
notStrictlyFalseBinding.getArgTypes(),
notStrictlyFalseBinding.isStrict(),
diff --git a/runtime/src/test/java/dev/cel/runtime/PlannerInterpreterTest.java b/runtime/src/test/java/dev/cel/runtime/PlannerInterpreterTest.java
index 2b0e53298..c0b0f76c4 100644
--- a/runtime/src/test/java/dev/cel/runtime/PlannerInterpreterTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/PlannerInterpreterTest.java
@@ -82,13 +82,14 @@ protected CelAbstractSyntaxTree prepareTest(CelTypeProvider typeProvider) {
@Override
public void optional_errors() {
- if (isParseOnly) {
- // Parsed-only evaluation contains function name in the
- // error message instead of the function overload.
- skipBaselineVerification();
- } else {
- super.optional_errors();
- }
+ // Exercised in planner_optional_errors instead
+ skipBaselineVerification();
+ }
+
+ @Test
+ public void planner_optional_errors() {
+ source = "optional.unwrap([dyn(1)])";
+ runTest(ImmutableMap.of());
}
@Override
diff --git a/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java b/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java
index de30902d3..c58ae782b 100644
--- a/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java
@@ -75,6 +75,7 @@
import dev.cel.runtime.CelUnknownSet;
import dev.cel.runtime.DefaultDispatcher;
import dev.cel.runtime.DescriptorTypeResolver;
+import dev.cel.runtime.InternalCelFunctionBinding;
import dev.cel.runtime.PartialVars;
import dev.cel.runtime.Program;
import dev.cel.runtime.RuntimeEquality;
@@ -244,6 +245,7 @@ private static void addBindingsToDispatcher(
overloadBindings.forEach(
overload ->
builder.addOverload(
+ ((InternalCelFunctionBinding) overload).getFunctionName(),
overload.getOverloadId(),
overload.getArgTypes(),
overload.isStrict(),
@@ -494,15 +496,11 @@ public void plan_call_zeroArgs() throws Exception {
public void plan_call_throws() throws Exception {
CelAbstractSyntaxTree ast = compile("error()");
Program program = PLANNER.plan(ast);
- String expectedOverloadId = isParseOnly ? "error" : "error_overload";
CelEvaluationException e = assertThrows(CelEvaluationException.class, program::eval);
assertThat(e)
.hasMessageThat()
- .contains(
- "evaluation error at :5: Function '"
- + expectedOverloadId
- + "' failed with arg(s) ''");
+ .contains("evaluation error at :5: Function 'error' failed with arg(s) ''");
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
assertThat(e.getCause()).hasMessageThat().contains("Intentional error");
}
@@ -562,13 +560,11 @@ public void plan_call_mapIndex() throws Exception {
public void plan_call_noMatchingOverload_throws() throws Exception {
CelAbstractSyntaxTree ast = compile("concat(b'abc', dyn_var)");
Program program = PLANNER.plan(ast);
- String errorMsg;
+ String errorMsg =
+ "No matching overload for function 'concat'. Overload candidates: concat_bytes_bytes";
if (isParseOnly) {
- errorMsg =
- "No matching overload for function 'concat'. Overload candidates: concat_bytes_bytes,"
- + " bytes_concat_bytes";
- } else {
- errorMsg = "No matching overload for function 'concat_bytes_bytes'";
+ // Parsed-only evaluation includes both overloads as candidates due to dynamic dispatch
+ errorMsg += ", bytes_concat_bytes";
}
CelEvaluationException e =
diff --git a/runtime/src/test/resources/planner_optional_errors.baseline b/runtime/src/test/resources/planner_optional_errors.baseline
new file mode 100644
index 000000000..3d59fefca
--- /dev/null
+++ b/runtime/src/test/resources/planner_optional_errors.baseline
@@ -0,0 +1,5 @@
+Source: optional.unwrap([dyn(1)])
+=====>
+bindings: {}
+error: evaluation error at test_location:15: Function 'optional.unwrap' failed with arg(s) '[1]'
+error_code: INTERNAL_ERROR