diff --git a/src/main/scala/org/camunda/feel/impl/builtin/ConversionBuiltinFunctions.scala b/src/main/scala/org/camunda/feel/impl/builtin/ConversionBuiltinFunctions.scala index 087746530..b60d71012 100644 --- a/src/main/scala/org/camunda/feel/impl/builtin/ConversionBuiltinFunctions.scala +++ b/src/main/scala/org/camunda/feel/impl/builtin/ConversionBuiltinFunctions.scala @@ -231,8 +231,10 @@ object ConversionBuiltinFunctions { private def stringFunction = builtinFunction( params = List("from"), - invoke = { case List(from) => - ValString(from.toString) + invoke = { + case List(ValNull) => ValNull + case List(from: ValString) => from + case List(from) => ValString(from.toString) } ) diff --git a/src/test/scala/org/camunda/feel/impl/builtin/BuiltinConversionFunctionsTest.scala b/src/test/scala/org/camunda/feel/impl/builtin/BuiltinConversionFunctionsTest.scala index e317f2dd6..5778b0715 100644 --- a/src/test/scala/org/camunda/feel/impl/builtin/BuiltinConversionFunctionsTest.scala +++ b/src/test/scala/org/camunda/feel/impl/builtin/BuiltinConversionFunctionsTest.scala @@ -20,279 +20,351 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.flatspec.AnyFlatSpec import org.camunda.feel.syntaxtree._ import org.camunda.feel._ -import org.camunda.feel.impl.FeelIntegrationTest +import org.camunda.feel.impl.{EvaluationResultMatchers, FeelEngineTest, FeelIntegrationTest} -import java.time.ZonedDateTime +import java.time.{Duration, LocalDate, LocalDateTime, LocalTime, OffsetTime, Period, ZonedDateTime} import scala.math.BigDecimal.double2bigDecimal import scala.math.BigDecimal.int2bigDecimal /** @author * Philipp */ -class BuiltinConversionFunctionsTest extends AnyFlatSpec with Matchers with FeelIntegrationTest { +class BuiltinConversionFunctionsTest + extends AnyFlatSpec + with Matchers + with FeelEngineTest + with EvaluationResultMatchers { "A date() function" should "convert String" in { - eval(""" date(x) """, Map("x" -> "2012-12-25")) should be(ValDate("2012-12-25")) + evaluateExpression(""" date(x) """, Map("x" -> "2012-12-25")) should returnResult( + LocalDate.parse("2012-12-25") + ) } it should "convert Date-Time" in { - eval(""" date( date and time("2012-12-25T11:00:00") ) """) should be(ValDate("2012-12-25")) + evaluateExpression(""" date( date and time("2012-12-25T11:00:00") ) """) should returnResult( + LocalDate.parse("2012-12-25") + ) - eval(""" date( date and time("2012-12-25T11:00:00+01:00") ) """) should be( - ValDate("2012-12-25") + evaluateExpression( + """ date( date and time("2012-12-25T11:00:00+01:00") ) """ + ) should returnResult( + LocalDate.parse("2012-12-25") ) } it should "convert (year,month,day)" in { - eval(""" date(2012, 12, 25) """) should be(ValDate("2012-12-25")) + evaluateExpression(""" date(2012, 12, 25) """) should returnResult( + LocalDate.parse("2012-12-25") + ) } "A date and time() function" should "convert String" in { - eval(""" date and time(x) """, Map("x" -> "2012-12-24T23:59:00")) should be( - ValLocalDateTime("2012-12-24T23:59:00") + evaluateExpression( + """ date and time(x) """, + Map("x" -> "2012-12-24T23:59:00") + ) should returnResult( + LocalDateTime.parse("2012-12-24T23:59:00") ) - eval(""" date and time(x) """, Map("x" -> "2012-12-24T23:59:00+01:00")) should be( - ValDateTime("2012-12-24T23:59:00+01:00") + evaluateExpression( + """ date and time(x) """, + Map("x" -> "2012-12-24T23:59:00+01:00") + ) should returnResult( + ZonedDateTime.parse("2012-12-24T23:59:00+01:00") ) } it should "convert (DateTime, Timezone)" in { - eval("""date and time(@"2020-07-31T14:27:30@Europe/Berlin", "Z")""") should be( - ValDateTime(ZonedDateTime.parse("2020-07-31T12:27:30Z")) + evaluateExpression( + """date and time(@"2020-07-31T14:27:30@Europe/Berlin", "Z")""" + ) should returnResult( + ZonedDateTime.parse("2020-07-31T12:27:30Z") ) - eval( + evaluateExpression( """date and time(@"2020-07-31T14:27:30@Europe/Berlin", "America/Los_Angeles")""" - ) should be(ValDateTime(ZonedDateTime.parse("2020-07-31T05:27:30-07:00[America/Los_Angeles]"))) + ) should returnResult(ZonedDateTime.parse("2020-07-31T05:27:30-07:00[America/Los_Angeles]")) - eval("""date and time(@"2020-07-31T14:27:30", "Z")""") should be( - ValDateTime(ZonedDateTime.parse("2020-07-31T14:27:30Z")) + evaluateExpression("""date and time(@"2020-07-31T14:27:30", "Z")""") should returnResult( + ZonedDateTime.parse("2020-07-31T14:27:30Z") ) } it should "convert (Date,Time)" in { - eval(""" date and time(date("2012-12-24"),time("T23:59:00")) """) should be( - ValLocalDateTime("2012-12-24T23:59:00") + evaluateExpression( + """ date and time(date("2012-12-24"),time("T23:59:00")) """ + ) should returnResult( + LocalDateTime.parse("2012-12-24T23:59:00") ) - eval(""" date and time(date("2012-12-24"),time("T23:59:00+01:00")) """) should be( - ValDateTime("2012-12-24T23:59:00+01:00") + evaluateExpression( + """ date and time(date("2012-12-24"),time("T23:59:00+01:00")) """ + ) should returnResult( + ZonedDateTime.parse("2012-12-24T23:59:00+01:00") ) } it should "convert (DateTime,Time)" in { - eval(""" date and time(date and time("2012-12-24T10:24:00"),time("T23:59:00")) """) should be( - ValLocalDateTime("2012-12-24T23:59:00") + evaluateExpression( + """ date and time(date and time("2012-12-24T10:24:00"),time("T23:59:00")) """ + ) should returnResult( + LocalDateTime.parse("2012-12-24T23:59:00") ) - eval( + evaluateExpression( """ date and time(date and time("2012-12-24T10:24:00"),time("T23:59:00+01:00")) """ - ) should be(ValDateTime("2012-12-24T23:59:00+01:00")) - eval( + ) should returnResult(ZonedDateTime.parse("2012-12-24T23:59:00+01:00")) + evaluateExpression( """ date and time(date and time("2012-12-24T10:24:00+01:00"),time("T23:59:00")) """ - ) should be(ValLocalDateTime("2012-12-24T23:59:00")) - eval( + ) should returnResult(LocalDateTime.parse("2012-12-24T23:59:00")) + evaluateExpression( """ date and time(date and time("2012-12-24T10:24:00+01:00"),time("T23:59:00+01:00")) """ - ) should be(ValDateTime("2012-12-24T23:59:00+01:00")) + ) should returnResult(ZonedDateTime.parse("2012-12-24T23:59:00+01:00")) } "A time() function" should "convert String" in { - eval(""" time(x) """, Map("x" -> "23:59:00")) should be(ValLocalTime("23:59:00")) + evaluateExpression(""" time(x) """, Map("x" -> "23:59:00")) should returnResult( + LocalTime.parse("23:59:00") + ) - eval(""" time(x) """, Map("x" -> "23:59:00+01:00")) should be(ValTime("23:59:00+01:00")) + evaluateExpression(""" time(x) """, Map("x" -> "23:59:00+01:00")) should returnResult( + OffsetTime.parse("23:59:00+01:00") + ) - eval(""" time(x) """, Map("x" -> "23:59:00@Europe/Paris")) should be( - ValTime("23:59:00@Europe/Paris") + evaluateExpression(""" time(x) """, Map("x" -> "23:59:00@Europe/Paris")) should returnResult( + OffsetTime.parse("23:59:00+01:00") ) } it should "convert Date-Time" in { - eval(""" time( date and time("2012-12-25T11:00:00") ) """) should be(ValLocalTime("11:00:00")) + evaluateExpression(""" time( date and time("2012-12-25T11:00:00") ) """) should returnResult( + LocalTime.parse("11:00:00") + ) - eval(""" time( date and time("2012-12-25T11:00:00+01:00") ) """) should be( - ValTime("11:00:00+01:00") + evaluateExpression( + """ time( date and time("2012-12-25T11:00:00+01:00") ) """ + ) should returnResult( + OffsetTime.parse("11:00:00+01:00") ) } it should "convert (hour,minute,second)" in { - eval(""" time(23, 59, 0) """) should be(ValLocalTime("23:59:00")) + evaluateExpression(""" time(23, 59, 0) """) should returnResult(LocalTime.parse("23:59:00")) } it should "convert (hour,minute,second, offset)" in { - eval(""" time(14, 30, 0, duration("PT1H")) """) should be(ValTime("14:30:00+01:00")) + evaluateExpression(""" time(14, 30, 0, duration("PT1H")) """) should returnResult( + OffsetTime.parse("14:30:00+01:00") + ) } "A number() function" should "convert String" in { - eval(""" number("1500.5") """) should be(ValNumber(1500.5)) + evaluateExpression(""" number("1500.5") """) should returnResult(1500.5) } it should "convert String with Grouping Separator ' '" in { - eval(""" number("1 500.5", " ") """) should be(ValNumber(1500.5)) + evaluateExpression(""" number("1 500.5", " ") """) should returnResult(1500.5) } it should "convert String with Grouping Separator ','" in { - eval(""" number("1,500", ",") """) should be(ValNumber(1500)) + evaluateExpression(""" number("1,500", ",") """) should returnResult(1500) } it should "convert String with Grouping Separator '.'" in { - eval(""" number("1.500", ".") """) should be(ValNumber(1500)) + evaluateExpression(""" number("1.500", ".") """) should returnResult(1500) } it should "convert String with Grouping ' ' and Decimal Separator '.'" in { - eval(""" number("1 500.5", " ", ".") """) should be(ValNumber(1500.5)) + evaluateExpression(""" number("1 500.5", " ", ".") """) should returnResult(1500.5) } it should "convert String with Grouping ' ' and Decimal Separator ','" in { - eval(""" number("1 500,5", " ", ",") """) should be(ValNumber(1500.5)) + evaluateExpression(""" number("1 500,5", " ", ",") """) should returnResult(1500.5) } it should "convert String with Grouping null and Decimal Separator ','" in { - eval(""" number("1500,5", null, ",") """) should be(ValNumber(1500.5)) + evaluateExpression(""" number("1500,5", null, ",") """) should returnResult(1500.5) } it should "convert String with Grouping '.' and Decimal null" in { - eval(""" number("1.500", ".", null) """) should be(ValNumber(1500)) + evaluateExpression(""" number("1.500", ".", null) """) should returnResult(1500) } it should "be invoked with named parameter" in { - eval(""" number(from: "1.500", grouping separator: ".", decimal separator: null) """) should be( - ValNumber(1500) + evaluateExpression( + """ number(from: "1.500", grouping separator: ".", decimal separator: null) """ + ) should returnResult( + 1500 ) } "A string() function" should "convert Number" in { - eval(""" string(1.1) """) should be(ValString("1.1")) + evaluateExpression(""" string(1.1) """) should returnResult("1.1") + } + + it should "convert a string" in { + evaluateExpression(""" string("hello") """) should returnResult("hello") } it should "convert Boolean" in { - eval(""" string(true) """) should be(ValString("true")) + evaluateExpression(""" string(true) """) should returnResult("true") } it should "convert Date" in { - eval(""" string(date("2012-12-25")) """) should be(ValString("2012-12-25")) + evaluateExpression(""" string(date("2012-12-25")) """) should returnResult("2012-12-25") } it should "convert Time" in { - eval(""" string(time("23:59:00")) """) should be(ValString("23:59:00")) - eval(""" string(time("23:59:00+01:00")) """) should be(ValString("23:59:00+01:00")) + evaluateExpression(""" string(time("23:59:00")) """) should returnResult("23:59:00") + evaluateExpression(""" string(time("23:59:00+01:00")) """) should returnResult("23:59:00+01:00") } it should "convert Date-Time" in { - eval(""" string(date and time("2012-12-25T11:00:00")) """) should be( - ValString("2012-12-25T11:00:00") + evaluateExpression(""" string(date and time("2012-12-25T11:00:00")) """) should returnResult( + "2012-12-25T11:00:00" ) - eval(""" string(date and time("2012-12-25T11:00:00+02:00")) """) should be( - ValString("2012-12-25T11:00:00+02:00") + evaluateExpression( + """ string(date and time("2012-12-25T11:00:00+02:00")) """ + ) should returnResult( + "2012-12-25T11:00:00+02:00" ) } it should "convert zero-length days-time-duration" in { - eval(""" string(@"-PT0S") """) should be(ValString("P0D")) - eval(""" string(@"P0D") """) should be(ValString("P0D")) - eval(""" string(@"PT0H") """) should be(ValString("P0D")) - eval(""" string(@"PT0H0M") """) should be(ValString("P0D")) - eval(""" string(@"PT0H0M0S") """) should be(ValString("P0D")) - eval(""" string(@"P0DT0H0M0S") """) should be(ValString("P0D")) + evaluateExpression(""" string(@"-PT0S") """) should returnResult("P0D") + evaluateExpression(""" string(@"P0D") """) should returnResult("P0D") + evaluateExpression(""" string(@"PT0H") """) should returnResult("P0D") + evaluateExpression(""" string(@"PT0H0M") """) should returnResult("P0D") + evaluateExpression(""" string(@"PT0H0M0S") """) should returnResult("P0D") + evaluateExpression(""" string(@"P0DT0H0M0S") """) should returnResult("P0D") } it should "convert negative days-time-duration" in { - eval(""" string(@"-PT1S") """) should be(ValString("-PT1S")) - eval(""" string(@"-PT1H") """) should be(ValString("-PT1H")) - eval(""" string(@"-PT2M30S") """) should be(ValString("-PT2M30S")) - eval(""" string(@"-P1DT2H3M4S") """) should be(ValString("-P1DT2H3M4S")) + evaluateExpression(""" string(@"-PT1S") """) should returnResult("-PT1S") + evaluateExpression(""" string(@"-PT1H") """) should returnResult("-PT1H") + evaluateExpression(""" string(@"-PT2M30S") """) should returnResult("-PT2M30S") + evaluateExpression(""" string(@"-P1DT2H3M4S") """) should returnResult("-P1DT2H3M4S") } it should "convert days-time-duration" in { - eval(""" string(@"PT1H") """) should be(ValString("PT1H")) - eval(""" string(@"PT2M30S") """) should be(ValString("PT2M30S")) - eval(""" string(@"P1DT2H3M4S") """) should be(ValString("P1DT2H3M4S")) + evaluateExpression(""" string(@"PT1H") """) should returnResult("PT1H") + evaluateExpression(""" string(@"PT2M30S") """) should returnResult("PT2M30S") + evaluateExpression(""" string(@"P1DT2H3M4S") """) should returnResult("P1DT2H3M4S") } it should "convert zero-length years-months-duration" in { - eval(""" string(@"P0Y") """) should be(ValString("P0Y")) - eval(""" string(@"-P0M") """) should be(ValString("P0Y")) - eval(""" string(@"P0Y0M") """) should be(ValString("P0Y")) + evaluateExpression(""" string(@"P0Y") """) should returnResult("P0Y") + evaluateExpression(""" string(@"-P0M") """) should returnResult("P0Y") + evaluateExpression(""" string(@"P0Y0M") """) should returnResult("P0Y") } it should "convert negative years-months-duration" in { - eval(""" string(@"-P1Y") """) should be(ValString("-P1Y")) - eval(""" string(@"-P5M") """) should be(ValString("-P5M")) - eval(""" string(@"-P3Y1M") """) should be(ValString("-P3Y1M")) + evaluateExpression(""" string(@"-P1Y") """) should returnResult("-P1Y") + evaluateExpression(""" string(@"-P5M") """) should returnResult("-P5M") + evaluateExpression(""" string(@"-P3Y1M") """) should returnResult("-P3Y1M") } it should "convert years-months-duration" in { - eval(""" string(@"P1Y") """) should be(ValString("P1Y")) - eval(""" string(@"P2M") """) should be(ValString("P2M")) - eval(""" string(@"P1Y2M") """) should be(ValString("P1Y2M")) + evaluateExpression(""" string(@"P1Y") """) should returnResult("P1Y") + evaluateExpression(""" string(@"P2M") """) should returnResult("P2M") + evaluateExpression(""" string(@"P1Y2M") """) should returnResult("P1Y2M") + } + + it should "return null if the argument is null" in { + evaluateExpression(""" string(null) """) should returnNull() } "A duration() function" should "convert day-time-String" in { - eval(""" duration(x) """, Map("x" -> "P2DT20H14M")) should be(ValDayTimeDuration("P2DT20H14M")) + evaluateExpression(""" duration(x) """, Map("x" -> "P2DT20H14M")) should returnResult( + Duration.parse("P2DT20H14M") + ) } it should "convert day-time-String with negative duration" in { - eval(""" duration(x) """, Map("x" -> "-PT5M")) should be(ValDayTimeDuration("-PT5M")) + evaluateExpression(""" duration(x) """, Map("x" -> "-PT5M")) should returnResult( + Duration.parse("-PT5M") + ) - eval(""" duration(x) """, Map("x" -> "PT-5M")) should be(ValDayTimeDuration("PT-5M")) + evaluateExpression(""" duration(x) """, Map("x" -> "PT-5M")) should returnResult( + Duration.parse("PT-5M") + ) - eval(""" duration(x) """, Map("x" -> "P-1D")) should be(ValDayTimeDuration("P-1D")) + evaluateExpression(""" duration(x) """, Map("x" -> "P-1D")) should returnResult( + Duration.parse("P-1D") + ) - eval(""" duration(x) """, Map("x" -> "PT-2H")) should be(ValDayTimeDuration("PT-2H")) + evaluateExpression(""" duration(x) """, Map("x" -> "PT-2H")) should returnResult( + Duration.parse("PT-2H") + ) - eval(""" duration(x) """, Map("x" -> "PT-3M-4S")) should be(ValDayTimeDuration("PT-3M-4S")) + evaluateExpression(""" duration(x) """, Map("x" -> "PT-3M-4S")) should returnResult( + Duration.parse("PT-3M-4S") + ) } it should "convert year-month-String" in { - eval(""" duration(x) """, Map("x" -> "P2Y4M")) should be(ValYearMonthDuration("P2Y4M")) + evaluateExpression(""" duration(x) """, Map("x" -> "P2Y4M")) should returnResult( + Period.parse("P2Y4M") + ) } it should "convert year-month-String with negative duration" in { - eval(""" duration(x) """, Map("x" -> "-P1Y2M")) should be(ValYearMonthDuration("-P1Y2M")) + evaluateExpression(""" duration(x) """, Map("x" -> "-P1Y2M")) should returnResult( + Period.parse("-P1Y2M") + ) - eval(""" duration(x) """, Map("x" -> "P-1Y")) should be(ValYearMonthDuration("P-1Y")) + evaluateExpression(""" duration(x) """, Map("x" -> "P-1Y")) should returnResult( + Period.parse("P-1Y") + ) - eval(""" duration(x) """, Map("x" -> "P-2M")) should be(ValYearMonthDuration("P-2M")) + evaluateExpression(""" duration(x) """, Map("x" -> "P-2M")) should returnResult( + Period.parse("P-2M") + ) - eval(""" duration(x) """, Map("x" -> "P-1Y-2M")) should be(ValYearMonthDuration("P-1Y-2M")) + evaluateExpression(""" duration(x) """, Map("x" -> "P-1Y-2M")) should returnResult( + Period.parse("P-1Y-2M") + ) } "A years and months duration(from,to) function" should "convert (Date,Date)" in { - eval(""" years and months duration( date("2011-12-22"), date("2013-08-24") ) """) should be( - ValYearMonthDuration("P1Y8M") + evaluateExpression( + """ years and months duration( date("2011-12-22"), date("2013-08-24") ) """ + ) should returnResult( + Period.parse("P1Y8M") ) - eval( + evaluateExpression( """ years and months duration( date and time("2011-12-22T10:00:00"), date and time("2013-08-24T10:00:00") ) """ - ) should be(ValYearMonthDuration("P1Y8M")) - eval( + ) should returnResult(Period.parse("P1Y8M")) + evaluateExpression( """ years and months duration( date and time("2011-12-22T10:00:00+01:00"), date and time("2013-08-24T10:00:00+01:00") ) """ - ) should be(ValYearMonthDuration("P1Y8M")) + ) should returnResult(Period.parse("P1Y8M")) } }