diff --git a/extensions/src/main/java/dev/cel/extensions/CelEncoderExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelEncoderExtensions.java index a98f9db41..498b8555e 100644 --- a/extensions/src/main/java/dev/cel/extensions/CelEncoderExtensions.java +++ b/extensions/src/main/java/dev/cel/extensions/CelEncoderExtensions.java @@ -135,9 +135,13 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) { functions.forEach( function -> { if (celOptions.evaluateCanonicalTypesToNativeValues()) { - runtimeBuilder.addFunctionBindings(function.nativeBytesFunctionBinding); + runtimeBuilder.addFunctionBindings( + CelFunctionBinding.fromOverloads( + function.getFunction(), function.nativeBytesFunctionBinding)); } else { - runtimeBuilder.addFunctionBindings(function.protoBytesFunctionBinding); + runtimeBuilder.addFunctionBindings( + CelFunctionBinding.fromOverloads( + function.getFunction(), function.protoBytesFunctionBinding)); } }); } diff --git a/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java index 7eed3dd5a..b0a501ddb 100644 --- a/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java +++ b/extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java @@ -19,36 +19,45 @@ 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.compiler.CelCompiler; -import dev.cel.compiler.CelCompilerFactory; import dev.cel.runtime.CelEvaluationException; -import dev.cel.runtime.CelRuntime; -import dev.cel.runtime.CelRuntimeFactory; +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 { private static final CelOptions CEL_OPTIONS = - CelOptions.current().build(); - - private static final CelCompiler CEL_COMPILER = - CelCompilerFactory.standardCelCompilerBuilder() - .addVar("stringVar", SimpleType.STRING) - .addLibraries(CelExtensions.encoders(CEL_OPTIONS)) - .build(); - private static final CelRuntime CEL_RUNTIME = - CelRuntimeFactory.standardCelRuntimeBuilder() - .setOptions(CEL_OPTIONS) - .addLibraries(CelExtensions.encoders(CEL_OPTIONS)) - .build(); + 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(); + } @Test public void library() { @@ -63,22 +72,14 @@ public void library() { @Test public void encode_success() throws Exception { - String encodedBytes = - (String) - CEL_RUNTIME - .createProgram(CEL_COMPILER.compile("base64.encode(b'hello')").getAst()) - .eval(); + String encodedBytes = (String) eval("base64.encode(b'hello')"); assertThat(encodedBytes).isEqualTo("aGVsbG8="); } @Test public void decode_success() throws Exception { - CelByteString decodedBytes = - (CelByteString) - CEL_RUNTIME - .createProgram(CEL_COMPILER.compile("base64.decode('aGVsbG8=')").getAst()) - .eval(); + CelByteString decodedBytes = (CelByteString) eval("base64.decode('aGVsbG8=')"); assertThat(decodedBytes.size()).isEqualTo(5); assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("hello"); @@ -86,12 +87,7 @@ public void decode_success() throws Exception { @Test public void decode_withoutPadding_success() throws Exception { - CelByteString decodedBytes = - (CelByteString) - CEL_RUNTIME - // RFC2045 6.8, padding can be ignored. - .createProgram(CEL_COMPILER.compile("base64.decode('aGVsbG8')").getAst()) - .eval(); + CelByteString decodedBytes = (CelByteString) eval("base64.decode('aGVsbG8')"); assertThat(decodedBytes.size()).isEqualTo(5); assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("hello"); @@ -99,50 +95,49 @@ public void decode_withoutPadding_success() throws Exception { @Test public void roundTrip_success() throws Exception { - String encodedString = - (String) - CEL_RUNTIME - .createProgram(CEL_COMPILER.compile("base64.encode(b'Hello World!')").getAst()) - .eval(); + String encodedString = (String) eval("base64.encode(b'Hello World!')"); CelByteString decodedBytes = (CelByteString) - CEL_RUNTIME - .createProgram(CEL_COMPILER.compile("base64.decode(stringVar)").getAst()) - .eval(ImmutableMap.of("stringVar", encodedString)); + eval("base64.decode(stringVar)", ImmutableMap.of("stringVar", encodedString)); assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("Hello World!"); } @Test public void encode_invalidParam_throwsCompilationException() { + Assume.assumeFalse(isParseOnly); CelValidationException e = assertThrows( - CelValidationException.class, - () -> CEL_COMPILER.compile("base64.encode('hello')").getAst()); + CelValidationException.class, () -> cel.compile("base64.encode('hello')").getAst()); assertThat(e).hasMessageThat().contains("found no matching overload for 'base64.encode'"); } @Test public void decode_invalidParam_throwsCompilationException() { + Assume.assumeFalse(isParseOnly); CelValidationException e = assertThrows( - CelValidationException.class, - () -> CEL_COMPILER.compile("base64.decode(b'aGVsbG8=')").getAst()); + CelValidationException.class, () -> cel.compile("base64.decode(b'aGVsbG8=')").getAst()); assertThat(e).hasMessageThat().contains("found no matching overload for 'base64.decode'"); } @Test public void decode_malformedBase64Char_throwsEvaluationException() throws Exception { - CelAbstractSyntaxTree ast = CEL_COMPILER.compile("base64.decode('z!')").getAst(); - CelEvaluationException e = - assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval()); + assertThrows(CelEvaluationException.class, () -> eval("base64.decode('z!')")); - assertThat(e) - .hasMessageThat() - .contains("Function 'base64_decode_string' failed with arg(s) 'z!'"); + assertThat(e).hasMessageThat().contains("failed with arg(s) 'z!'"); 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); + } }