/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.camunda.bpm.dmn.feel.impl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.camunda.bpm.dmn.feel.impl.juel.FeelEngineFactoryImpl;
import org.camunda.bpm.engine.variable.VariableMap;
import org.camunda.bpm.engine.variable.Variables;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class FeelExceptionTest {
public static final String INPUT_VARIABLE = "input";
public static FeelEngine feelEngine;
public VariableMap variables;
@BeforeClass
public static void initFeelEngine() {
feelEngine = new FeelEngineFactoryImpl().createInstance();
}
@Test
public void testSimpleExpressionNotSupported() {
try {
feelEngine.evaluateSimpleExpression("12 == 12", Variables.emptyVariableContext());
failBecauseExceptionWasNotThrown(UnsupportedOperationException.class);
}
catch (UnsupportedOperationException e) {
assertThat(e).hasMessageStartingWith("FEEL-01016");
}
}
@Before
public void initVariables() {
variables = Variables.createVariables();
variables.putValue(INPUT_VARIABLE, 13);
}
@Test
public void testInvalidNot() {
assertException("FEEL-01001",
"not(",
"not(2",
"not(2, 12",
"not(]",
"not(("
);
}
@Test
public void testInvalidInterval() {
assertException("FEEL-01002",
"[1..3",
"(1..3",
"]1..3",
"[1..3(",
"(1..3(",
"]1..3(",
"[1..",
"(1..",
"]1..",
"[1.3",
"[1.3]",
"[1.3)",
"[1.3[",
"(1.3",
"(1.3]",
"(1.3)",
"(1.3[",
"]1.3",
"]1.3]",
"]1.3)",
"]1.3[",
"(1.3",
"(1.3]",
"(1.3)",
"(1.3[",
"[1....3"
);
}
@Test
public void testInvalidComparison() {
assertException("FEEL-01003",
">",
">=",
"<",
"<="
);
}
@Test
public void testUnknownMethod() {
assertException("FEEL-01007",
"unknown(12)",
"not(unknown(12))",
"12,13,unknown(12),14",
"not(12,13,unknown(12),14)",
"[12..unknown(12))",
"not([12..unknown(12)))",
"12,13,[12..unknown(12)),14",
"not(12,13,[12..unknown(12)),14)"
);
}
@Test
public void testUnknownVariable() {
assertException("FEEL-01009",
"a",
"not(a)",
"12,13,a,14",
"not(12,13,a,14)",
"[12..a)",
"not([12..a))",
"12,13,[12..a),14",
"not(12,13,[12..a),14)"
);
}
@Test
public void testInvalidSyntax() {
assertException("FEEL-01010",
"!= x",
"== x",
"=< 12",
"=> 12",
"< = 12",
"> = 12",
"1..3]",
"1..3)",
"1..3[",
")1..3",
"1..3(",
"[1....3]",
"[1....3)",
"[1....3[",
"< [1..3)",
">= [1..3)",
"${cellInput == 12}"
);
}
@Test
public void testUnableToConvertToBoolean() {
variables.putValue(INPUT_VARIABLE, true);
assertException("FEEL-01015",
"''",
"'camunda'",
"12",
"'true'",
"\"false\""
);
}
@Test
public void testUnableToConvertToBigDecimal() {
variables.putValue(INPUT_VARIABLE, BigDecimal.valueOf(10));
assertException("FEEL-01015",
"''",
"< ''",
"'camunda'",
"< 'camunda'",
"false",
"< true",
"'12'",
"< '12'",
"\"12\"",
"< \"12\""
);
}
@Test
public void testUnableToConvertToBigInteger() {
variables.putValue(INPUT_VARIABLE, BigInteger.valueOf(10));
assertException("FEEL-01015",
"''",
"< ''",
"'camunda'",
"< 'camunda'",
"false",
"< true",
"'12'",
"< '12'",
"\"12\"",
"< \"12\""
);
}
@Test
public void testUnableToConvertToDouble() {
variables.putValue(INPUT_VARIABLE, 10.0);
assertException("FEEL-01015",
"''",
"< ''",
"'camunda'",
"< 'camunda'",
"false",
"< true",
"'12.2'",
"< '12.2'",
"\"12.2\"",
"< \"12.2\""
);
}
@Test
public void testUnableToConvertToLong() {
variables.putValue(INPUT_VARIABLE, 10L);
assertException("FEEL-01015",
"''",
"< ''",
"'camunda'",
"< 'camunda'",
"false",
"< true",
"'12'",
"< '12'",
"\"12\"",
"< \"12\""
);
}
@Test
public void testUnableToConvertToString() {
variables.putValue(INPUT_VARIABLE, "camunda");
assertException("FEEL-01015",
"false",
"< true",
"12",
"< 12"
);
}
@Test
public void testMissingInputVariable() {
variables.remove(INPUT_VARIABLE);
assertException("FEEL-01017",
"false",
"12",
"< 12",
"'Hello'"
);
}
@Test
public void testInvalidDateAndTimeFormat() {
assertException("FEEL-01019",
"date and time('camunda')",
"date and time('2012-13-13')",
"date and time('13:13:13')",
"date and time('2012-12-12T25:00')"
);
}
@Test
public void testInvalidListFormat() {
assertException("FEEL-01020",
",",
"1,",
"1,2,,3",
",1,2",
"1,2, ,3,4",
"1,\t,2"
);
}
public void assertException(String exceptionCode, String... feelExpressions) {
for (String feelExpression : feelExpressions) {
try {
evaluateFeel(feelExpression);
failBecauseExceptionWasNotThrown(FeelException.class);
}
catch (FeelException e) {
assertThat(e).hasMessageStartingWith(exceptionCode);
assertThat(e).hasMessageContaining(feelExpression);
if (!feelExpression.startsWith("${")) {
assertThat(e.getMessage()).doesNotContain("${");
}
}
}
}
public boolean evaluateFeel(String feelExpression) {
return feelEngine.evaluateSimpleUnaryTests(feelExpression, INPUT_VARIABLE, variables.asVariableContext());
}
}