From 937f9dd53679334b9b45c800cbc3cc9af49b2971 Mon Sep 17 00:00:00 2001 From: "Philip K. Warren" Date: Mon, 11 Sep 2023 13:09:38 -0500 Subject: [PATCH] Fix isInf() overload method and add tests --- .../internal/celext/CustomOverload.java | 7 ++- .../internal/celext/CustomOverloadTest.java | 62 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/test/java/build/buf/protovalidate/internal/celext/CustomOverloadTest.java diff --git a/src/main/java/build/buf/protovalidate/internal/celext/CustomOverload.java b/src/main/java/build/buf/protovalidate/internal/celext/CustomOverload.java index 5bea380c..27ca032b 100644 --- a/src/main/java/build/buf/protovalidate/internal/celext/CustomOverload.java +++ b/src/main/java/build/buf/protovalidate/internal/celext/CustomOverload.java @@ -329,7 +329,12 @@ private static Overload isInf() { value -> value.convertToNative(Double.TYPE).isInfinite() ? BoolT.True : BoolT.False, (lhs, rhs) -> { Double value = lhs.convertToNative(Double.TYPE); - return value.isInfinite(rhs.intValue()) ? BoolT.True : BoolT.False; + long sign = rhs.intValue(); + if (sign == 0) { + return value.isInfinite() ? BoolT.True : BoolT.False; + } + double expectedValue = (sign > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY; + return value == expectedValue ? BoolT.True : BoolT.False; }, null); } diff --git a/src/test/java/build/buf/protovalidate/internal/celext/CustomOverloadTest.java b/src/test/java/build/buf/protovalidate/internal/celext/CustomOverloadTest.java new file mode 100644 index 00000000..b0d829c5 --- /dev/null +++ b/src/test/java/build/buf/protovalidate/internal/celext/CustomOverloadTest.java @@ -0,0 +1,62 @@ +package build.buf.protovalidate.internal.celext; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import org.junit.Test; +import org.projectnessie.cel.Ast; +import org.projectnessie.cel.Env; +import org.projectnessie.cel.Library; +import org.projectnessie.cel.Program; +import org.projectnessie.cel.interpreter.Activation; + +public class CustomOverloadTest { + + private final Env env = Env.newEnv(Library.Lib(new ValidateLibrary())); + + @Test + public void testIsInf() { + Map testCases = + ImmutableMap.builder() + .put("0.0.isInf()", false) + .put("(1.0/0.0).isInf()", true) + .put("(1.0/0.0).isInf(0)", true) + .put("(1.0/0.0).isInf(1)", true) + .put("(1.0/0.0).isInf(-1)", false) + .put("(-1.0/0.0).isInf()", true) + .put("(-1.0/0.0).isInf(0)", true) + .put("(-1.0/0.0).isInf(1)", false) + .put("(-1.0/0.0).isInf(-1)", true) + .build(); + for (Map.Entry testCase : testCases.entrySet()) { + Program.EvalResult result = eval(testCase.getKey()); + assertThat(result.getVal().booleanValue()).isEqualTo(testCase.getValue()); + } + } + + @Test + public void testIsNan() { + Map testCases = + ImmutableMap.builder() + .put("0.0.isNan()", false) + .put("(0.0/0.0).isNan()", true) + .put("(1.0/0.0).isNan()", false) + .build(); + for (Map.Entry testCase : testCases.entrySet()) { + Program.EvalResult result = eval(testCase.getKey()); + assertThat(result.getVal().booleanValue()).isEqualTo(testCase.getValue()); + } + } + + private Program.EvalResult eval(String source) { + return eval(source, Activation.emptyActivation()); + } + + private Program.EvalResult eval(String source, Object vars) { + Env.AstIssuesTuple parsed = env.parse(source); + assertThat(parsed.hasIssues()).isFalse(); + Ast ast = parsed.getAst(); + return env.program(ast).eval(vars); + } +}