package org.openflexo.antar.expr.parser; import junit.framework.TestCase; import org.openflexo.antar.expr.BinaryOperatorExpression; import org.openflexo.antar.expr.BindingValueAsExpression; import org.openflexo.antar.expr.BooleanBinaryOperator; import org.openflexo.antar.expr.ConditionalExpression; import org.openflexo.antar.expr.Constant; import org.openflexo.antar.expr.Constant.BooleanConstant; import org.openflexo.antar.expr.Constant.FloatConstant; import org.openflexo.antar.expr.Constant.FloatSymbolicConstant; import org.openflexo.antar.expr.Constant.IntegerConstant; import org.openflexo.antar.expr.Constant.StringConstant; import org.openflexo.antar.expr.DefaultExpressionPrettyPrinter; import org.openflexo.antar.expr.Expression; import org.openflexo.antar.expr.NullReferenceException; import org.openflexo.antar.expr.TypeMismatchException; import org.openflexo.antar.expr.UnaryOperatorExpression; public class TestExpressionParser extends TestCase { private DefaultExpressionPrettyPrinter prettyPrinter; @Override protected void setUp() throws Exception { super.setUp(); prettyPrinter = new DefaultExpressionPrettyPrinter(); } private Expression tryToParse(String anExpression, String expectedEvaluatedExpression, Class<? extends Expression> expectedExpressionClass, Object expectedEvaluation, boolean shouldFail) { try { System.out.println("Parsing... " + anExpression); Expression parsed = ExpressionParser.parse(anExpression); Expression evaluated = parsed.evaluate(); System.out.println("Parsed " + anExpression); System.out.println("Successfully parsed as : " + parsed.getClass().getSimpleName()); System.out.println("Normalized: " + prettyPrinter.getStringRepresentation(parsed)); System.out.println("Evaluated: " + prettyPrinter.getStringRepresentation(evaluated)); if (shouldFail) { fail(); } assertEquals(expectedExpressionClass, parsed.getClass()); assertEquals(expectedEvaluatedExpression, prettyPrinter.getStringRepresentation(evaluated)); if (expectedEvaluation != null) { if (!(evaluated instanceof Constant)) { fail("Evaluated value is not a constant (expected: " + expectedEvaluation + ") but " + expectedEvaluation); } if (expectedEvaluation instanceof Number) { Object value = ((Constant<?>) evaluated).getValue(); if (value instanceof Number) { assertEquals(((Number) expectedEvaluation).doubleValue(), ((Number) value).doubleValue()); } else { fail("Evaluated value is not a number (expected: " + expectedEvaluation + ") but " + expectedEvaluation); } } else { assertEquals(expectedEvaluation, ((Constant<?>) evaluated).getValue()); } } return parsed; } catch (ParseException e) { if (!shouldFail) { e.printStackTrace(); fail(); } else { System.out.println("Parsing " + anExpression + " has failed as expected: " + e.getMessage()); } return null; } catch (TypeMismatchException e) { if (!shouldFail) { e.printStackTrace(); fail(); } else { System.out.println("Parsing " + anExpression + " has failed as expected: " + e.getMessage()); } return null; } catch (NullReferenceException e) { if (!shouldFail) { e.printStackTrace(); fail(); } else { System.out.println("Parsing " + anExpression + " has failed as expected: " + e.getMessage()); } return null; } /*try { System.out.println("\nParsing " + aString); Expression parsed = parser.parse(aString); System.out.println("Successfully parsed as : " + parsed.getClass().getSimpleName()); System.out.println("Normalized: " + prettyPrinter.getStringRepresentation(parsed)); System.out.println("Evaluated: " + prettyPrinter.getStringRepresentation(parsed.evaluate())); if (shouldFail) { fail(); } assertEquals(expectedEvaluatedExpression, prettyPrinter.getStringRepresentation(parsed.evaluate())); } catch (ParseException e) { if (!shouldFail) { e.printStackTrace(); fail(); } else { System.out.println("Parsing " + aString + " has failed as expected: " + e.getMessage()); } } catch (TypeMismatchException e) { if (!shouldFail) { e.printStackTrace(); fail(); } else { System.out.println("Parsing " + aString + " has failed as expected: " + e.getMessage()); } }*/ } public void testBindingValue() { tryToParse("foo", "foo", BindingValueAsExpression.class, null, false); } public void testBindingValue2() { tryToParse("foo_foo2", "foo_foo2", BindingValueAsExpression.class, null, false); } public void testBindingValue3() { tryToParse("foo.foo2.foo3", "foo.foo2.foo3", BindingValueAsExpression.class, null, false); } public void testBindingValue4() { tryToParse("method(1)", "method(1)", BindingValueAsExpression.class, null, false); } public void testBindingValue5() { tryToParse("a.b.c.method(1)", "a.b.c.method(1)", BindingValueAsExpression.class, null, false); } public void testBindingValue6() { tryToParse("i.am.a(1,2+3,7.8,'foo').little.test(1)", "i.am.a(1,5,7.8,\"foo\").little.test(1)", BindingValueAsExpression.class, null, false); } public void testNumericValue1() { tryToParse("34", "34", IntegerConstant.class, 34, false); } public void testNumericValue2() { tryToParse("7.8", "7.8", FloatConstant.class, 7.8, false); } public void testNumericValue3() { tryToParse("1.876E12", "1.876E12", FloatConstant.class, 1.876E12, false); } public void testNumericValue4() { tryToParse("0.876e-9", "8.76E-10", FloatConstant.class, 8.76E-10, false); } public void testNumericValue5() { tryToParse("-89", "-89", IntegerConstant.class, -89, false); } public void testNumericValue6() { tryToParse("-89.7856", "-89.7856", FloatConstant.class, -89.7856, false); } public void testNumericValue7() { tryToParse("1+1", "2", BinaryOperatorExpression.class, 2, false); } public void testNumericValue8() { tryToParse("1+(2*7-9)", "6", BinaryOperatorExpression.class, 6, false); } public void testNumericValue9() { tryToParse("1+((298*7.1e-3)-9)", "-5.8842", BinaryOperatorExpression.class, -5.8842, false); } public void testStringValue1() { tryToParse("\"foo1\"", "\"foo1\"", StringConstant.class, "foo1", false); } public void testStringValue2() { tryToParse("'foo1'", "\"foo1\"", StringConstant.class, "foo1", false); } public void testStringValue3() { tryToParse("\"foo1\"+\"foo2\"", "\"foo1foo2\"", BinaryOperatorExpression.class, "foo1foo2", false); } public void testStringValue4() { tryToParse("\"foo1\"+'and'+\"foo2\"", "\"foo1andfoo2\"", BinaryOperatorExpression.class, "foo1andfoo2", false); } public void testExpression1() { tryToParse("machin+1", "(machin + 1)", BinaryOperatorExpression.class, null, false); } public void testExpression2() { tryToParse("machin+1*6-8/7+bidule", "(((machin + 6) - 1.1428571428571428) + bidule)", BinaryOperatorExpression.class, null, false); } public void testExpression3() { tryToParse("7-x-(-x-6-8*2)", "((7 - x) - (((-(x)) - 6) - 16))", BinaryOperatorExpression.class, null, false); } public void testExpression4() { tryToParse("1+function(test,4<7-x)", "(1 + function(test,(4 < (7 - x))))", BinaryOperatorExpression.class, null, false); } public void testTrigonometricComputing1() { tryToParse("sin(-pi/2)", "-1.0", UnaryOperatorExpression.class, -1, false); } public void testTrigonometricComputing2() { tryToParse("-atan(2)", "-1.1071487177940904", UnaryOperatorExpression.class, -1.1071487177940904, false); } public void testTrigonometricComputing3() { tryToParse("-(atan(-pi/2)*(3-5*pi/7+8/9))", "1.651284257012876", UnaryOperatorExpression.class, 1.651284257012876, false); } public void testTrigonometricComputing4() { tryToParse("-cos(atan(-pi/2)*(3-5*pi/7+8/9))", "0.08040105411083133", UnaryOperatorExpression.class, 0.08040105411083133, false); } public void testEquality() { Expression e = tryToParse("a==b", "(a = b)", BinaryOperatorExpression.class, null, false); assertEquals(BooleanBinaryOperator.EQUALS, ((BinaryOperatorExpression) e).getOperator()); } public void testEquality2() { tryToParse("binding1.a.b == binding2.a.b*7", "(binding1.a.b = (binding2.a.b * 7))", BinaryOperatorExpression.class, null, false); } public void testOr1() { Expression e = tryToParse("a|b", "(a | b)", BinaryOperatorExpression.class, null, false); assertEquals(BooleanBinaryOperator.OR, ((BinaryOperatorExpression) e).getOperator()); } public void testOr2() { Expression e = tryToParse("a||b", "(a | b)", BinaryOperatorExpression.class, null, false); assertEquals(BooleanBinaryOperator.OR, ((BinaryOperatorExpression) e).getOperator()); } public void testAnd1() { Expression e = tryToParse("a&b", "(a & b)", BinaryOperatorExpression.class, null, false); assertEquals(BooleanBinaryOperator.AND, ((BinaryOperatorExpression) e).getOperator()); } public void testAnd2() { Expression e = tryToParse("a&&b", "(a & b)", BinaryOperatorExpression.class, null, false); assertEquals(BooleanBinaryOperator.AND, ((BinaryOperatorExpression) e).getOperator()); } public void testBoolean1() { tryToParse("false", "false", BooleanConstant.FALSE.getClass(), false, false); } public void testBoolean2() { tryToParse("true", "true", BooleanConstant.TRUE.getClass(), true, false); } public void testBoolean3() { tryToParse("false && true", "false", BinaryOperatorExpression.class, false, false); } public void testBooleanExpression1() { tryToParse("!a&&b", "((!(a)) & b)", BinaryOperatorExpression.class, null, false); } public void testPi() { tryToParse("pi", "3.141592653589793", FloatSymbolicConstant.class, null, false); } public void testPi2() { tryToParse("-pi/2", "-1.5707963267948966", BinaryOperatorExpression.class, null, false); } public void testComplexCall() { tryToParse("testFunction(-pi/2,7.8,1-9*7/9,aVariable,foo1+foo2,e)", "testFunction(-1.5707963267948966,7.8,-6.0,aVariable,(foo1 + foo2),e)", BindingValueAsExpression.class, null, false); } public void testImbricatedCall() { tryToParse("function1(function2(8+1,9,10-1))", "function1(function2(9,9,9))", BindingValueAsExpression.class, null, false); } public void testEmptyCall() { tryToParse("function1()", "function1()", BindingValueAsExpression.class, null, false); } public void testComplexBooleanExpression() { tryToParse("a && (c || d && (!f)) ||b", "((a & (c | (d & (!(f))))) | b)", BinaryOperatorExpression.class, null, false); } public void testArithmeticNumberComparison1() { tryToParse("1 < 2", "true", BinaryOperatorExpression.class, true, false); } public void testArithmeticNumberComparison2() { tryToParse("0.1109 < 1.1108E-03", "false", BinaryOperatorExpression.class, false, false); } public void testStringConcatenation() { tryToParse("\"a + ( 2 + b )\"+2", "\"a + ( 2 + b )2\"", BinaryOperatorExpression.class, null, false); } public void testParsingError1() { tryToParse("a\"b", "", null, null, true); } public void testParsingError2() { tryToParse("a'b", "", null, null, true); } public void testParsingError3() { tryToParse("\"", "", null, null, true); } public void testParsingError4() { tryToParse("test23 ( fdfd + 1", "", null, null, true); } public void testParsingError5() { tryToParse("test24 [ fdfd + 1", "", null, null, true); } public void testIgnoredChars() { tryToParse(" test \n\n", "test", BindingValueAsExpression.class, null, false); } public void testConditional1() { tryToParse("a?b:c", "(a ? b : c)", ConditionalExpression.class, null, false); } public void testConditional2() { tryToParse("a > 9 ?true:false", "((a > 9) ? true : false)", ConditionalExpression.class, null, false); } public void testConditional3() { tryToParse("a+1 > 10-7 ?8+4:5", "(((a + 1) > 3) ? 12 : 5)", ConditionalExpression.class, null, false); } public void testConditional4() { tryToParse("a+1 > (a?1:2) ?8+4:5", "(((a + 1) > (a ? 1 : 2)) ? 12 : 5)", ConditionalExpression.class, null, false); } public void testConditional5() { tryToParse("2 < 3 ? 4:2", "4", ConditionalExpression.class, 4, false); } public void testConditional6() { tryToParse("2 > 3 ? 4:2", "2", ConditionalExpression.class, 2, false); } public void testInvalidConditional() { tryToParse("2 > 3 ? 3", "", ConditionalExpression.class, null, true); } /*public void test25() throws java.text.ParseException { Date date = new SimpleDateFormat("dd/MM/yy HH:mm").parse("17/12/07 15:55"); SimpleDateFormat localeDateFormat = new SimpleDateFormat(); tryToParse("(([dd/MM/yy HH:mm,17/12/07 12:54] + [3h] ) + [1min])", "[" + localeDateFormat.toPattern() + "," + localeDateFormat.format(date) + "]", false); } public void test26() throws java.text.ParseException { Date date = new SimpleDateFormat("dd/MM/yy HH:mm").parse("17/12/07 15:55"); SimpleDateFormat localeDateFormat = new SimpleDateFormat(); tryToParse("([dd/MM/yy HH:mm,17/12/07 12:54] + ( [3h] + [1min]))", "[" + localeDateFormat.toPattern() + "," + localeDateFormat.format(date) + "]", false); } */ }