Closed felideon closed 2 years ago
@felideon thank you for raising this up! I collected the relevant content from the specification here.
In which context do you need these functions? Camunda BPM platform 7 or Zeebe?
Currently, we don't focus on DMN 1.3. It may take a while before someone from Camunda/Zeebe will implement this. So, feel free to contribute by creating pull requests!
Hi @saig0, thanks. This would be for the Camunda BPMN/DMN engine. The company I work for is an Enterprise customer.
Though tempting, I'll have to consider the feasibility of working on a PR. I've never worked with Scala (let alone Java).
@saig0, is this here up for grabs? Seems like an old issue 😄 But I guess I could create the RangeBuildinFunctions
as mentioned above.
@kaaquist go for it :rocket:
Since this is a big issue with many functions, I would prefer to create one PR for each function. So, I can review the PRs faster and give feedback.
@saig0 I thought that I would add a ValRange
case class in the Val.scala
. I can see from the above that we will be adding the ability to do inclusive and exclusive ranges. I'm not aware of a Java
or Scala
function that can do that. Maybe you know? I have started out creating a ValRange
which take a string. See WIP PR -> #345
I have tried not to give ValString as input, and can see that you have created an Interval in the FeelInterpreter.scala
which is tried to be used, but it end up with an error.
Test case:
it should "return true because range end is included and point is higher" in {
eval(" before([1..10], 20)") should be(ValBoolean(true))
}
I can see that we get a PositionalFunctionParameters(List(Interval(ClosedIntervalBoundary(ConstNumber(1)),ClosedIntervalBoundary(ConstNumber(10))), ConstNumber(20)))
And then the next step is the FeelInterpreter, but something does not go as expected and I get an error:
23:21:37.240 [ScalaTest-run-running-BuiltinRangeFunctionTest] WARN org.camunda.feel.FeelEngine - Failed to invoke function: no variable found for name 'cellInput'
ValNull was not equal to ValBoolean(true)
ScalaTestFailureLocation: org.camunda.feel.impl.builtin.BuiltinRangeFunctionTest at (BuiltinRangeFunctionTest.scala:74)
Expected :ValBoolean(true)
Actual :ValNull
<Click to see difference>
org.scalatest.exceptions.TestFailedException: ValNull was not equal to ValBoolean(true)
at org.scalatest.MatchersHelper$.indicateFailure(MatchersHelper.scala:343)
at org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(Matchers.scala:6723)
at org.scalatest.Matchers$AnyShouldWrapper.should(Matchers.scala:6759)
at org.camunda.feel.impl.builtin.BuiltinRangeFunctionTest.$anonfun$new$13(BuiltinRangeFunctionTest.scala:74)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FlatSpecLike$$anon$5.apply(FlatSpecLike.scala:1682)
at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
at org.scalatest.FlatSpec.withFixture(FlatSpec.scala:1685)
at org.scalatest.FlatSpecLike.invokeWithFixture$1(FlatSpecLike.scala:1680)
at org.scalatest.FlatSpecLike.$anonfun$runTest$1(FlatSpecLike.scala:1692)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:286)
at org.scalatest.FlatSpecLike.runTest(FlatSpecLike.scala:1692)
at org.scalatest.FlatSpecLike.runTest$(FlatSpecLike.scala:1674)
at org.scalatest.FlatSpec.runTest(FlatSpec.scala:1685)
at org.scalatest.FlatSpecLike.$anonfun$runTests$1(FlatSpecLike.scala:1750)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:393)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:381)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:370)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:407)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:381)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:376)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:458)
at org.scalatest.FlatSpecLike.runTests(FlatSpecLike.scala:1750)
at org.scalatest.FlatSpecLike.runTests$(FlatSpecLike.scala:1749)
at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1685)
at org.scalatest.Suite.run(Suite.scala:1124)
at org.scalatest.Suite.run$(Suite.scala:1106)
at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1685)
at org.scalatest.FlatSpecLike.$anonfun$run$1(FlatSpecLike.scala:1795)
at org.scalatest.SuperEngine.runImpl(Engine.scala:518)
at org.scalatest.FlatSpecLike.run(FlatSpecLike.scala:1795)
at org.scalatest.FlatSpecLike.run$(FlatSpecLike.scala:1793)
at org.scalatest.FlatSpec.run(FlatSpec.scala:1685)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1349)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1343)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1343)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:1033)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:1011)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1509)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1011)
at org.scalatest.tools.Runner$.run(Runner.scala:850)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:38)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:25)
So it seems that there is a default value in play: no variable found for name 'cellInput'
.. But I'm not totally sure.
Maybe you can point me in some direction?
@kaaquist this is the right direction. In the parser, we could reuse (parts of) the Interval
. But we need to adjust the interpreter. At the moment, the Interval
is used to compare the input value with the given interval. Here, the input value is read from the context (using the default name cellInput
).
We could create a new data type ConstRange
similar to Interval
. In the interpreter, we could distinguish both types and use the range for the new functions.
BTW: the new data type for range is also part of #293.
@saig0 I have updated the first PR #345, please have a look.
@saig0 seems like something is missing in the overlaps
function. I can't get it to pass when doing the following tests:
overlaps ([1..5], (5..8]) = false
return true
instead of false
.
overlaps ([1..5), [5..8]) = false
return true
instead of false
.
overlaps ([1..5), (5..8]) = false
return true
instead of false
.
Missing meaning some check in the description above. All other tests passes.
Please see code here #353
seems like something is missing in the overlaps function
True :+1: There is a bug in the spec description. In the first part of the condition, it should be range2.start included
instead of range2.end included
since it compares the start
of range2
.
The built-in range functions below were added to the DMN 1.3 standard (see § 10.3.4.7 Range Functions). These functions would be helpful when writing business rules with FEEL: