Skip to content

Commit

Permalink
Merge pull request #685 from camunda/mob-582-filter-null
Browse files Browse the repository at this point in the history
feat: Improve null handling in filter expressions
  • Loading branch information
saig0 authored Jul 21, 2023
2 parents 0d85ebb + 96aa1e9 commit 2fe6c5e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,9 @@ class FeelInterpreter {
val withBooleanFilter = (list: List[Val]) => mapEither[Val, Val](
list,
item =>
withBoolean(filter(item), {
case true => item
case false => conditionNotFulfilled
(filter(item) match {
case ValBoolean(true) => item
case _ => conditionNotFulfilled
}).toEither,
items => ValList(items.filterNot(_ == conditionNotFulfilled))
)
Expand All @@ -809,7 +809,10 @@ class FeelInterpreter {
case fulFilledItems: ValList => fulFilledItems
case error => error
}
case other => error(s"Expected boolean filter or number but found '$other'")
case _ => withBooleanFilter(list.tail) match {
case ValList(fulFilledItems) => ValList(fulFilledItems)
case error => error
}
})
).getOrElse(
// Return always an empty list if the given list is empty. Note that we would return `null`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,36 @@ class InterpreterListExpressionTest
ValList(List(ValNumber(3), ValNumber(4))))
}

it should "be filtered via comparison with null" in {
// items that are not comparable to null are ignored
eval("[1,2,3,4][item > null]") should be(
ValList(List()))

// items that are not comparable to null are ignored
eval("[1,2,3,4][item < null]") should be(
ValList(List()))
}

it should "be filtered via comparison with null elements" in {
// null is not comparable to 2, so it's ignored
eval("[1,2,null,4][item > 2]") should be(
ValList(List(ValNumber(4))))

// null is the only item for which the comparison returns true
eval("[1,2,null,4][item = null]") should be(
ValList(List(ValNull)))
}

ignore should "be filtered via comparison with missing variable" in {
// null is the only item for which the comparison returns true
eval("[1,2,x,4][item = null]") should be(
ValList(List(ValNull)))

// missing variable becomes null, so same as direct null item
eval("[1,2,x,4][item > 2]") should be(
ValList(List(ValNumber(4))))
}

it should "be filtered via index" in {

eval("[1,2,3,4][1]") should be(ValNumber(1))
Expand Down Expand Up @@ -234,15 +264,12 @@ class InterpreterListExpressionTest
ValNumber(1))
}

it should "fail if the filter doesn't return a boolean or a number" in {
it should "be filtered if the filter doesn't always return a boolean or a number" in {
eval(""" [1,2,3,4]["not a valid filter"] """) should be (
ValError("Expected boolean filter or number but found 'ValString(not a valid filter)'")
ValList(List())
)
}

it should "fail if the filter doesn't return always a boolean" in {
eval("[1,2,3,4][if item < 3 then true else null]") should be (
ValError("Expected Boolean but found 'ValNull'")
ValList(List(ValNumber(1), ValNumber(2)))
)
}

Expand Down

0 comments on commit 2fe6c5e

Please sign in to comment.