private CompiledFEELExpression parse(String input) { return parse( input, Collections.emptyMap() ); }
@Test public void test_Misc_fromOriginalFEELInterpretedTestSuite() { assertThat(parseCompileEvaluate("if null then \"foo\" else \"bar\""), is("bar")); assertThat(parseCompileEvaluate("{ hello world : function() \"Hello World!\", message : hello world() }.message"), is("Hello World!")); assertThat(parseCompileEvaluate("1 + if true then 1 else 2"), is(new BigDecimal("2"))); assertThat(parseCompileEvaluate("\"string with \\\"quotes\\\"\""), is("string with \"quotes\"")); assertThat(parseCompileEvaluate("date( -0105, 8, 2 )"), is(LocalDate.of(-105, 8, 2))); assertThat(parseCompileEvaluate("string(null)"), is(nullValue())); assertThat(parseCompileEvaluate("[ null ]"), is(Arrays.asList(new Object[]{null}))); assertThat(parseCompileEvaluate("[ null, null ]"), is(Arrays.asList(new Object[]{null, null}))); assertThat(parseCompileEvaluate("[ null, 47, null ]"), is(Arrays.asList(new Object[]{null, BigDecimal.valueOf(47), null}))); }
@Test public void test_for() { // for assertThat(parseCompileEvaluate("for x in [ 10, 20, 30 ], y in [ 1, 2, 3 ] return x * y"), is(Arrays.asList(10, 20, 30, 20, 40, 60, 30, 60, 90).stream().map(x -> BigDecimal.valueOf(x)).collect(Collectors.toList()))); // normal: assertThat(parseCompileEvaluate("for x in [1, 2, 3] return x+1"), is(Arrays.asList(1, 2, 3).stream().map(x -> BigDecimal.valueOf(x + 1)).collect(Collectors.toList()))); // TODO in order to parse correctly the enhanced for loop it is required to configure the FEEL Profiles }
private Object parseCompileEvaluate(String feelLiteralExpression) { CompiledFEELExpression compiledExpression = parse( feelLiteralExpression ); LOG.debug("{}", compiledExpression); EvaluationContext emptyContext = CodegenTestUtil.newEmptyEvaluationContext(); Object result = compiledExpression.apply(emptyContext); LOG.debug("{}", result); return result; }
@Test public void test_between() { assertThat(parseCompileEvaluate("10 between 5 and 12"), is(true)); assertThat(parseCompileEvaluate("10 between 20 and 30"), is(false)); assertThat(parseCompileEvaluate("10 between 20 and \"foo\""), nullValue()); assertThat(parseCompileEvaluate("\"foo\" between 5 and 12"), nullValue()); assertThat(parseCompileEvaluate("\"foo\" between \"bar\" and \"zap\""), is(true)); assertThat(parseCompileEvaluate("\"foo\" between null and \"zap\""), nullValue()); }
@Test public void test_filterPath_tricky2() { CompiledFEELExpression nameRef = parse("[ {x:1, y:2}, {x:2, y:3} ][x]"); LOG.debug("{}", nameRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("x", false); Object result = nameRef.apply(context); LOG.debug("{}", result); assertThat(result, is(Collections.emptyList())); }
@Test public void test_primary_parens() { assertThat(parseCompileEvaluate("(\"some string\")"), is( "some string" )); assertThat(parseCompileEvaluate("(123)"), is( BigDecimal.valueOf(123) )); assertThat(parseCompileEvaluate("(-123)"), is( BigDecimal.valueOf(-123) )); assertThat(parseCompileEvaluate("-(123)"), is( BigDecimal.valueOf(-123) )); assertThat(parseCompileEvaluate("(false)"), is( false )); assertThat(parseCompileEvaluate("(true)"), is( true )); }
@Test public void testQualifiedName3() { String inputExpression = "a date.year"; Type dateType = BuiltInType.DATE; CompiledFEELExpression qualRef = parse(inputExpression, mapOf(entry("a date", dateType))); LOG.debug("{}", qualRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("a date", LocalDate.of(2016, 8, 2)); Object result = qualRef.apply(context); LOG.debug("{}", result); assertThat(result, is(BigDecimal.valueOf(2016))); }
@Test public void test_logicalNegationExpression() { // this is all invalid syntax assertThat(parseCompileEvaluate("not true"), nullValue()); assertThat(parseCompileEvaluate("not false"), nullValue()); assertThat(parseCompileEvaluate("not null"), nullValue()); assertThat(parseCompileEvaluate("not 3"), nullValue()); }
@Test public void testNameReference() { String inputExpression = "someSimpleName"; CompiledFEELExpression nameRef = parse( inputExpression, mapOf( entry("someSimpleName", BuiltInType.STRING) ) ); LOG.debug("{}", nameRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("someSimpleName", 123L); Object result = nameRef.apply(context); LOG.debug("{}", result); assertThat(result, is( BigDecimal.valueOf(123) )); }
@Test public void test_listExpression() { assertThat(parseCompileEvaluate("[]"), is(Collections.emptyList())); assertThat(parseCompileEvaluate("[ ]"), is(Collections.emptyList())); assertThat(parseCompileEvaluate("[1]"), is(Arrays.asList(BigDecimal.valueOf(1)))); assertThat(parseCompileEvaluate("[1, 2,3]"), is(Arrays.asList(BigDecimal.valueOf(1), BigDecimal.valueOf(2), BigDecimal.valueOf(3)))); }
@Test public void test_filterPath_tricky1() { CompiledFEELExpression nameRef = parse( "[ {x:1, y:2}, {x:2, y:3} ][x]"); LOG.debug("{}", nameRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("x", 2); Object result = nameRef.apply(context); LOG.debug("{}", result); assertThat(result, is(mapOf(entry("x", new BigDecimal(2)), entry("y", new BigDecimal(3))))); }
@Test public void test_quantifiedExpressions() { // quantified expressions assertThat(parseCompileEvaluate("some price in [ 80, 11, 110 ] satisfies price > 100"), is(Boolean.TRUE)); assertThat(parseCompileEvaluate("some price in [ 80, 11, 90 ] satisfies price > 100"), is(Boolean.FALSE)); assertThat(parseCompileEvaluate("some x in [ 5, 6, 7 ], y in [ 10, 11, 6 ] satisfies x > y"), is(Boolean.TRUE)); assertThat(parseCompileEvaluate("every price in [ 80, 11, 90 ] satisfies price > 10"), is(Boolean.TRUE)); assertThat(parseCompileEvaluate("every price in [ 80, 11, 90 ] satisfies price > 70"), is(Boolean.FALSE)); assertThat(parseCompileEvaluate("some x in [ 5, 6, 7 ], y in [ 10, 11, 12 ] satisfies x < y"), is(Boolean.TRUE)); assertThat(parseCompileEvaluate("some price in [ 80, 11, 110 ] satisfies price > max(100, 50, 10)"), is(Boolean.TRUE)); }
@Test public void testQualifiedName2() { String inputExpression = "My Person.Full Name"; Type personType = JavaBackedType.of(MyPerson.class); CompiledFEELExpression qualRef = parse( inputExpression, mapOf( entry("My Person", personType) ) ); LOG.debug("{}", qualRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("My Person", new MyPerson()); Object result = qualRef.apply(context); LOG.debug("{}", result); assertThat(result, is( "John Doe" )); }
@Test public void test_filterPathSelection() { // Selection assertThat(parseCompileEvaluate("[ {x:1, y:2}, {x:2, y:3} ].y"), is(Arrays.asList(BigDecimal.valueOf(2), BigDecimal.valueOf(3)))); assertThat(parseCompileEvaluate("[ {x:1, y:2}, {x:2} ].y"), is(Arrays.asList(BigDecimal.valueOf(2)))); assertThat(parseCompileEvaluate("[ {x:1, y:2}, {x:2, y:3} ].z"), is(Collections.emptyList())); }
@Test public void testQualifiedName() { String inputExpression = "My Person.Full Name"; Type personType = new MapBackedType("Person", mapOf( entry("Full Name", BuiltInType.STRING), entry("Age", BuiltInType.NUMBER) ) ); CompiledFEELExpression qualRef = parse( inputExpression, mapOf( entry("My Person", personType) ) ); LOG.debug("{}", qualRef); EvaluationContext context = CodegenTestUtil.newEmptyEvaluationContext(); context.setValue("My Person", mapOf( entry("Full Name", "John Doe"), entry("Age", 47) )); Object result = qualRef.apply(context); LOG.debug("{}", result); assertThat(result, is( "John Doe" )); // check number coercion for qualified name CompiledFEELExpression personAgeExpression = parse("My Person.Age", mapOf(entry("My Person", personType))); LOG.debug("{}", personAgeExpression); Object resultPersonAge = personAgeExpression.apply(context); // Please notice input variable in context is a Map containing and entry value for int 47. LOG.debug("{}", resultPersonAge); assertThat(resultPersonAge, is(BigDecimal.valueOf(47))); }
@Test public void test_additiveExpression() { assertThat(parseCompileEvaluate( "1 + 2"), is(BigDecimal.valueOf( 3 ))); assertThat(parseCompileEvaluate( "1 + null"), nullValue()); assertThat(parseCompileEvaluate( "1 - 2"), is(BigDecimal.valueOf( -1 ))); assertThat(parseCompileEvaluate( "1 - null"), nullValue()); assertThat(parseCompileEvaluate( "\"Hello, \" + \"World\""), is("Hello, World")); }
/** * Partially from {@link FEELConditionsAndLoopsTest} */ @Test public void test_if() { assertThat(parseCompileEvaluate( "if true then 15 else 5"), is(BigDecimal.valueOf( 15 ))); assertThat(parseCompileEvaluate( "if false then 15 else 5"), is(BigDecimal.valueOf( 5 ))); assertThat(parseCompileEvaluate("if null then 15 else 5"), is(BigDecimal.valueOf(5))); assertThat(parseCompileEvaluate("if \"hello\" then 15 else 5"), is(BigDecimal.valueOf(5))); }
@Test public void test_multiplicativeExpression() { assertThat(parseCompileEvaluate("3 * 5"), is(BigDecimal.valueOf(15))); assertThat(parseCompileEvaluate("3 * null"), nullValue()); assertThat(parseCompileEvaluate("10 / 2"), is(BigDecimal.valueOf(5))); assertThat(parseCompileEvaluate("10 / null"), nullValue()); }
@Test public void test_FEEL_DROOLS_2143() { // DROOLS-2143: Allow ''--1' expression as per FEEL grammar rule 26 assertThat(parseCompileEvaluate("--10"), is(BigDecimal.valueOf(10))); assertThat(parseCompileEvaluate("---10"), is(BigDecimal.valueOf(-10))); assertThat(parseCompileEvaluate("+10"), is(BigDecimal.valueOf(10))); }