package com.sap.runlet.expressionpad.tests;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.Date;
import java.util.Iterator;
import org.antlr.runtime.RecognitionException;
import org.eclipse.emf.ecore.resource.ResourceSet;
import com.sap.runlet.abstractexpressionpad.Evaluator.ExecuteResult;
import com.sap.runlet.abstractinterpreter.objects.RunletObject;
import com.sap.runlet.abstractinterpreter.util.DateParser;
import com.sap.runlet.abstractinterpreter.util.Fraction;
import com.sap.runlet.expressionpad.RunletEvaluator;
import com.sap.runlet.expressionpad.views.RunletHTTPHandler;
import com.sap.runlet.interpreter.Activator;
import com.sap.runlet.interpreter.RunletInterpreter;
import com.sap.runlet.interpreter.objects.NativeObject;
import com.sap.runlet.interpreter.repository.simpleimpl.RunletInMemoryRepository;
import com.sun.net.httpserver.HttpServer;
import data.classes.AssociationEnd;
import data.classes.ClassTypeDefinition;
import data.classes.TypeDefinition;
public class GeneralTests extends RunletTestCase {
public void testSimpleGroupByWithoutMapping() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"group 1->including(2) by dim1:fact.div(fact)",
"group 1->including(2) by dim1:fact");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(2, result.length);
assertEquals(0, errors.length);
assertEquals(1, result[0].size());
boolean found1 = false;
boolean found2 = false;
for (RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition> r : result[0].flatten()) {
if (((NativeObject) r).getNativeObject().equals(new Fraction(1))) {
found1 = true;
}
if (((NativeObject) r).getNativeObject().equals(new Fraction(2))) {
found2 = true;
}
}
assertTrue(found1 && found2);
assertEquals(2, result[1].size());
found1 = false;
found2 = false;
for (RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition> r : result[1].flatten()) {
if (((NativeObject) r).getNativeObject().equals(new Fraction(1))) {
found1 = true;
}
if (((NativeObject) r).getNativeObject().equals(new Fraction(2))) {
found2 = true;
}
}
assertTrue(found1 && found2);
}
public void testSimpleMap() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var f=const function(String s):Number { return s.length(); }",
"\"abc\"->map(f)",
"\"abc\"->including(\"defg\")->map(f)",
"\"abc\"->including(\"defg\")->map(f)->map(const function(Number n):Number { return n.times(2); })");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(4, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(3) },
result[1]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(3), new Fraction(4) },
result[2]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(6), new Fraction(8) },
result[3]);
}
public void testMultiFunctionCall() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new FunctionTest().test()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(16), new Fraction(8) },
result[0]);
}
public void testOqlWithEqualValuesForDifferentAliasCombinations() throws Exception {
// this test enforces the use of List instead of Set for the alias values cache
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new IteratorTest().m2()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(0), new Fraction(0), new Fraction(0), new Fraction(0) },
result[0]);
}
public void testOqlWithAliasUsagesInFromClause() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new OqlTest().testSimpleOqlExpression()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] { new Fraction(5), new Fraction(6), new Fraction(7),
new Fraction(6), new Fraction(7), new Fraction(8), new Fraction(7), new Fraction(8), new Fraction(9) },
result[0]);
}
public void testSimpleOql() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate(
"(from 1->including(2)->including(3) as a, 4->including(5)->including(6) as b where true).count");
assertEquals(1, result.length);
assertNOEquals(new Fraction(9), result[0]);
}
public void testSimpleExpression() throws SecurityException, IllegalArgumentException,
RecognitionException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("123");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(123), ((NativeObject) result[0]).getNativeObject());
}
public void testFunctionExpression() throws SecurityException, IllegalArgumentException,
RecognitionException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main
.evaluate("function(String s):Number { return s.length(); }(\"abc\")");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(3), ((NativeObject) result[0]).getNativeObject());
}
public void testTypeOfStringLiteral() throws SecurityException, IllegalArgumentException,
RecognitionException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main
.evaluate("function(String s):Number { return \"kaputt\".length(); }(\"a\")");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(6), ((NativeObject) result[0]).getNativeObject());
}
public void testEmptyParameterListOnFunctionSignature() throws SecurityException,
IllegalArgumentException, RecognitionException, NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("function():Number { return 1; }()");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[0]).getNativeObject());
}
public void testStatementSequence() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute("var s = \"abc\";", "s;").getResult();
assertEquals(2, result.length);
assertTrue(result[1] instanceof NativeObject);
assertEquals("abc", ((NativeObject) result[1]).getNativeObject());
}
public void testStatementSequenceWithExceptionInBetween() throws Exception,
IllegalArgumentException, RecognitionException {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result;
result = main.execute("var s = \"abc\";").getResult();
result = main.execute("s;").getResult();
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals("abc", ((NativeObject) result[0]).getNativeObject());
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> resultAndErrors = main.execute("s.humba();");
assertTrue("Method humba() should not have been present in class String",
resultAndErrors.getErrors().length>0);
result = main.execute("var i = 123;").getResult();
result = main.execute("i;").getResult();
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(123), ((NativeObject) result[0]).getNativeObject());
}
public void testExecuteOfAnonymousFunction() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute("function(String s):Number { return s.length(); }(\"abc\")").getResult();
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(3), ((NativeObject) result[0]).getNativeObject());
}
public void testTypedVariableDeclaration() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"String s = \"abc\";", "s.length();").getResult();
assertEquals(2, result.length);
assertTrue(result[1] instanceof NativeObject);
assertEquals(new Fraction(3), ((NativeObject) result[1]).getNativeObject());
}
public void testGarbageAfterTarget() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> result = main.execute("String s = \"abc\" a b c");
assertTrue("Expected parse errors due to garbage at end of input", result.getErrors().length>0);
}
public void testUnresolvableClassName() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> result = main.execute("new Humba");
assertTrue("Expected parse errors due to garbage at end of input",
result.getErrors().length > 0);
}
public void testRedundantFunctionType() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute("function(String s):Number f = function(String s):Number { return s.length(); }",
"f(\"123\")").getResult();
assertEquals(2, result.length);
assertTrue(result[1] instanceof NativeObject);
assertEquals(new Fraction(3), ((NativeObject) result[1]).getNativeObject());
}
public void testApplyFunction() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"function(Number n):Number plus1 = function(Number n):Number { return n.plus(1); }",
"var apply=function(function(Number n):Number func, Number arg):Number { return func(arg); }",
"apply(plus1, 1)").getResult();
assertEquals(3, result.length);
assertTrue(result[2] instanceof NativeObject);
assertEquals(new Fraction(2), ((NativeObject) result[2]).getNativeObject());
}
public void testSimpleEntityToValueAssoc() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main
.execute(
"var p=new Person()",
"p.name=\"abc\"",
"p.name").getResult();
assertEquals(3, result.length);
assertTrue(result[2] instanceof NativeObject);
assertEquals("abc", ((NativeObject) result[2]).getNativeObject());
}
public void testValueClassEquality() throws Exception {
// equal street names should compare equal
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("value Address(street: \"a\") == "+
"value Address(street: \"a\")");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(true, ((NativeObject) result[0]).getNativeObject());
// different street names should compare unequal
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result2 = main.evaluate("value Address(street: \"a\") == "
+ "value Address(street: \"ab\")");
assertEquals(1, result2.length);
assertTrue(result2[0] instanceof NativeObject);
assertEquals(false, ((NativeObject) result2[0]).getNativeObject());
// equal street names but distinct (yet equal) City objects for the city
// property should compare unequal
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result3 = main.evaluate("value Address(street: \"a\", city: new City()) == "
+ "value Address(street: \"a\", city: new City())");
assertEquals(1, result3.length);
assertTrue(result3[0] instanceof NativeObject);
assertEquals(false, ((NativeObject) result3[0]).getNativeObject());
}
public void testValueClassEqualityWithEmbeddedEntity() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var c=new City()",
"var a1=value Address(street: \"a\", city: c)",
"var a2=value Address(street: \"a\", city: c)",
"a1==a2").getResult();
assertEquals(4, result.length);
assertTrue(result[3] instanceof NativeObject);
assertEquals(true, ((NativeObject) result[3]).getNativeObject());
}
public void testEntityEquality() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute("var c1=new City()",
"var c2=new City()",
"c1==c2",
"c1==c1").getResult();
assertEquals(4, result.length);
assertTrue(result[2] instanceof NativeObject);
assertEquals(false, ((NativeObject) result[2]).getNativeObject());
assertTrue(result[3] instanceof NativeObject);
assertEquals(true, ((NativeObject) result[3]).getNativeObject());
}
public void testObjectCountPrecedence() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("1.count");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[0]).getNativeObject());
}
public void testSimpleStringTemplate() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("new Templ().m(\"m\"->including(\"y \"))");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals("Hello my World!", ((NativeObject) result[0]).getNativeObject());
}
public void testRunletHttpServerAndBinding() throws Exception {
ResourceSet rs = RunletEvaluator.getResourceSet("ngpm.stdlib");
RunletInterpreter interpreter = new RunletInterpreter(rs, new RunletInMemoryRepository(
Activator.getDefault().getModelAdapter()));
final String testString = "123";
URL url = new URL("http://localhost:8234/trala?s="+testString);
HttpServer runletHTTPServer = HttpServer.create(new InetSocketAddress(8234), 8234);
RunletHTTPHandler handler = new RunletHTTPHandler(interpreter);
runletHTTPServer.createContext("/", handler);
runletHTTPServer.setExecutor(handler); // creates a default executor
runletHTTPServer.start();
InputStream is = url.openStream();
Reader r = new InputStreamReader(is);
StringBuilder sb = new StringBuilder();
int read = r.read();
while (read != -1) {
sb.append((char) read);
read = r.read();
}
r.close();
runletHTTPServer.stop(0);
assertEquals(testString, sb.toString());
}
public void testCompositionCheck() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var o1 = new Organization()",
"var o2 = new Organization()",
"var p = new Person()",
"o1.persons += p").getResult();
assertEquals(4, result.length);
try {
main.execute("o2.persons += p").getErrors();
fail("Expected exception due to illegal attempt to establish a second composite parent link");
} catch (RuntimeException e) {
assertTrue(e.getMessage().startsWith(
"java.lang.RuntimeException: Illegal attempt to establish a second composite parent link for composite child"));
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result2 = main.execute(
"o1.persons->iterate(Boolean b=false; pIter | b.or(pIter == p))")
.getResult();
assertEquals(1, result2.length);
assertEquals(true, ((NativeObject) result2[0]).getNativeObject());
}
}
public void testUniqueness() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var u = new UniquenessTest()",
"var p1 = new Person()",
"var p2 = new Person()",
"u.persons += p1",
"u.persons += p1",
"u.persons += p2",
"u.persons += p1",
"u.persons.count",
"u.numbers += 1",
"u.numbers += 1",
"u.numbers += 2",
"u.numbers += 3",
"u.numbers += 3",
"u.numbers.count").getResult();
assertEquals(14, result.length);
assertTrue(result[7] instanceof NativeObject);
assertEquals(new Fraction(2), ((NativeObject) result[7]).getNativeObject());
assertTrue(result[13] instanceof NativeObject);
assertEquals(new Fraction(3), ((NativeObject) result[13]).getNativeObject());
}
public void testScopeStabilityAcrossParseErrors() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var p = new Person()",
"p.name=\"Axel\"",
"var dim : : ,+=/| -> iterate(bla blubb trala; )",
"p.addresses->iterate(i|i.street.append(\"asf\"))",
"p.name").getResult();
assertEquals(5, result.length);
assertTrue(result[4] instanceof NativeObject);
assertEquals("Axel", ((NativeObject) result[4]).getNativeObject());
}
public void testValueLiteralWithTwoPropertyInits() throws Exception {
// equal street names should compare equal
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("value Address(street: \"a\", city: new City()).street == \"a\")");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(true, ((NativeObject) result[0]).getNativeObject());
}
public void testSaveLeavesValueLinkIntact() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var p = new Person()",
"p.name=\"Axel\"",
"p.name",
"store p",
"p.name").getResult();
assertEquals(5, result.length);
assertTrue(result[2] instanceof NativeObject);
assertEquals("Axel", ((NativeObject) result[2]).getNativeObject());
assertTrue(result[4] instanceof NativeObject);
assertEquals("Axel", ((NativeObject) result[4]).getNativeObject());
}
public void testDeleteWithSubsequentAll() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var p1 = new Person()",
"p1.name=\"Jan\"",
"var p2 = new Person()",
"p2.name=\"Axel\"",
"store p1",
"store p2",
"delete p1",
"all Person.count",
"all Person->iterate(p|p.name)").getResult();
assertEquals(9, result.length);
assertTrue(result[7] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[7]).getNativeObject());
assertTrue(result[8] instanceof NativeObject);
assertEquals("Axel", ((NativeObject) result[8]).getNativeObject());
}
public void testAddTransientCompositeChildToPersistentEntity() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var o = new Organization()",
"var p1 = new Person()",
"p1.name=\"Jan\"",
"var p2 = new Person()",
"p2.name=\"Axel\"",
"o.persons += p1",
"store o",
"o.persons += p2",
"o.persons.count").getResult();
assertEquals(9, result.length);
assertTrue(result[8] instanceof NativeObject);
assertEquals(new Fraction(2), ((NativeObject) result[8]).getNativeObject());
}
public void testDeleteFromComposition() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var o = new Organization()",
"var p1 = new Person()",
"p1.name=\"Jan\"",
"var p2 = new Person()",
"p2.name=\"Axel\"",
"o.persons += p1",
"store o",
"all Person.count", // expect 1, namely "Jan"
"all Person->iterate(p|p.name)",
"o.persons += p2", // p2 should become persistent through composition
"all Person.count", // therefore here we expect 2
"delete p1",
"all Person.count",
"o.persons.count").getResult();
assertEquals(14, result.length);
assertTrue(result[7] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[7]).getNativeObject());
assertTrue(result[8] instanceof NativeObject);
assertEquals("Jan", ((NativeObject) result[8]).getNativeObject());
assertTrue(result[10] instanceof NativeObject);
assertEquals(new Fraction(2), ((NativeObject) result[10]).getNativeObject());
assertTrue(result[12] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[12]).getNativeObject());
assertTrue(result[13] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[13]).getNativeObject());
}
public void testNativeValueVariableAsArgument() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"var p1 = new Person()",
"var s = \"a\"",
"s = s.append(\"b\")",
"p1.name = s",
"p1.name").getResult();
assertEquals(5, result.length);
assertTrue(result[4] instanceof NativeObject);
assertEquals("ab", ((NativeObject) result[4]).getNativeObject());
}
public void testSimpleCellSet() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.execute(
"new CellSetTest().m(\"Mannheim\", \"John\")",
"new CellSetTest().m(\"Heidelberg\", \"Elton\")").getResult();
assertEquals(2, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals(new Fraction(2), ((NativeObject) result[0]).getNativeObject());
assertTrue(result[1] instanceof NativeObject);
assertEquals(new Fraction(1), ((NativeObject) result[1]).getNativeObject());
}
public void testSimpleFunctionFromMethod() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> result = main
.execute(
"var f = \"abc\"::substring",
"f(0,2)",
"f(1,3)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result2 = result.getResult();
assertEquals(3, result2.length);
assertTrue(result2[1].iterator().next() instanceof NativeObject);
assertEquals("ab", ((NativeObject) result2[1].iterator().next()).getNativeObject());
assertTrue(result2[2].iterator().next() instanceof NativeObject);
assertEquals("bc", ((NativeObject) result2[2].iterator().next()).getNativeObject());
}
public void testTypeAdapterAndSimplePolymorphism() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> result = main
.execute(
"Organization o = new Organization()",
"var at1 = new AdapterTest1()",
"at1.polymorphismTest(o)",
"o = at1",
"at1.polymorphismTest(at1)");
String[] errors = result.getErrors();
assertTrue(errors == null || errors.length == 0);
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result2 = result.getResult();
assertEquals(5, result2.length);
assertTrue(result2[2].iterator().next() instanceof NativeObject);
assertEquals(true, ((NativeObject) result2[2].iterator().next()).getNativeObject());
assertTrue(result2[4].iterator().next() instanceof NativeObject);
assertEquals(false, ((NativeObject) result2[4].iterator().next()).getNativeObject());
}
public void testSimpleReplaceExpression() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main
.evaluate("new ReplaceTest().n(\"Trala\").b.c.s");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
assertEquals("Trala", ((NativeObject) result[0]).getNativeObject());
}
public void testSimpleDateExpression() throws Exception {
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = main.evaluate("2008-10-15T10:12:55");
assertEquals(1, result.length);
assertTrue(result[0] instanceof NativeObject);
Date date = DateParser.parse("2008-10-15T10:12:55");
assertEquals(date, ((NativeObject) result[0]).getNativeObject());
}
public void testConstantNamedValue() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"const i = 5",
"i = 6");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertTrue(errors.length > 0);
}
public void testDistinctNamedValueNames() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var a = 5",
"const a = 10");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length); // expecting one exception for the second statement and no output
assertEquals(2, errors.length); // runtime exception ("Cannot enter the same value twice") and
} // constraint violation (DistinctNamedValueNames)
public void testSimpleObjectParameterizedClass() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var opc=value OPC1|123|()",
"opc.n()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(2, result.length);
assertEquals(0, errors.length);
assertNOEquals(new Fraction(123), result[1]);
}
public void testHeadAndTail() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"Number[] n = 1",
"n = n->including(2)",
"n = n->including(3)",
"n->head()",
"n->tail()",
"n->tail()->head()",
"n->tail()->tail()->head()",
"n->tail()->tail()->tail()",
"n->tail()->tail()->tail()->head()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
//String[] errors = executeResult.getErrors();
assertEquals(9, result.length);
//FIXME: too many constraint violations for now: assertEquals(0, errors.length);
assertNOEquals(new Fraction(1), result[3]);
assertNOEquals(new Fraction(2), result[5]);
assertNOEquals(new Fraction(3), result[6]);
assertTrue(result[7].isEmpty());
assertTrue(result[8].isEmpty());
}
public void testSelectIterator() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new Iterators().sel(1->including(2)->including(3), function(Number n):Boolean { return n.greaterThan(2); })");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertEquals(1, result[0].size());
assertNOEquals(new Fraction(3), result[0].iterator().next());
}
public void testOptionalParametersForMethod() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"value DefaultParametersTest().s(\"a\", \"b\")",
"value DefaultParametersTest().s(\"a\", \"b\", \"c\")",
"value DefaultParametersTest().s(\"a\", \"b\", \"c\", \"d\")");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(3, result.length);
assertEquals(0, errors.length);
assertNOEquals("ababcdef", result[0]);
assertNOEquals("abcdef", result[1]);
assertNOEquals("abcd", result[2]);
}
public void testOptionalParameterForFunction() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"function(Number 1..1 n, Number 1..1 b=1):Number f=function(Number 1..1 n, Number 1..1 b=1):Number { return n.plus(b); }",
"f(2, 2)",
"f(2)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(3, result.length);
assertEquals(0, errors.length);
assertNOEquals(new Fraction(4), result[1]);
assertNOEquals(new Fraction(3), result[2]);
}
public void testAggregateExpression() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var m1 = value Measure(precise:true,date:value MonthAndYear(month:2,year:2009),val:100)",
"var m2 = value Measure(precise:true,date:value MonthAndYear(month:2,year:2009),val:200)",
"var m3 = value Measure(precise:false,date:value MonthAndYear(month:2,year:2009),val:300)",
"var ms = m1->including(m2)->including(m3)",
"m1.measuresByYear(ms,true,2009)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(5, result.length);
assertEquals(0, errors.length);
assertNOEquals(new Fraction(300), result[4]);
}
public void testTernary() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"true?1:2",
"false?1:2",
"2.greaterThan(1)?\"a\":\"b\"",
"1.greaterThan(1)?\"a\":\"b\"");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertNOEquals(new Fraction(1), result[0]);
assertNOEquals(new Fraction(2), result[1]);
assertNOEquals("a", result[2]);
assertNOEquals("b", result[3]);
assertEquals(4, result.length);
assertEquals(0, errors.length);
}
public void testDimensionExpression() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new CellSetTest().getCellSet()->dim(new CellSetTest().createOrganizations().persons, name)",
"new CellSetTest().getCellSet()->dim(new CellSetTest().createOrganizations().persons, cityName)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
// String[] errors = executeResult.getErrors();
assertEquals(2, result.length);
// assertEquals(0, errors.length); // TODO fix model; currently there seem to be three errors...
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new String[] { "Elton", "John", "Curt" }, result[0]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new String[] { "Heidelberg", "Mannheim", "Dallas" }, result[1]);
}
/**
* Creates a set of organizations, stores and commits it which starts a new snapshot.
* From the "historic" snapshot reads the organizations and passes its contained
* persons to a cell set for aggregation. During this, the comparison with the string
* value objects "Mannheim" and "John" will have to compare using {@link RunletObject#logicallyEquals(RunletObject)}
* instead of {@link Object#equals(Object)} so as to ignore that these string values come from the
* current snapshot while the values to compare against come from the historic snapshot.
*/
public void testCellSetOverHistoricData() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var cst=new CellSetTest()",
"var orgs=cst.createOrganizations()",
"store orgs",
"var ss1=commit",
"new CellSetTest().getCellSet()(all[ss1] Organization.persons, \"Mannheim\", \"John\")");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
assertEquals(5, result.length);
assertNOEquals(new Fraction(2), result[4]);
}
public void testDimensionExpressionAcrossSnapshots() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var p1=new Person()",
"var c1=new City()",
"c1.name=\"Mannheim\"",
"p1.addresses+=value Address(street: \"abc\", city: c1)",
"store p1",
"p1.name=\"Axel\"",
"var ss1=commit",
"var p2=new Person()",
"p2.name=\"Jan\"",
"var c2=new City()",
"c2.name=\"Heidelberg\"",
"p2.addresses+=value Address(street: \"Rohrbacher Str.\", city: c2)",
"store p2",
"var ss2=commit",
"Person[] ps=all[ss1] Person->including(all[ss2] Person)",
"ps.count",
"new CellSetTest().getCellSet()->dim(ps, cityName)",
"new CellSetTest().getCellSet()->dim(ps, cityName).count");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
assertEquals(18, result.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new String[] { "Mannheim", "Heidelberg" }, result[16]);
assertNOEquals(new Fraction(2), result[17]);
}
public void testMethodCallOnMultiObjectWithEmptyObjectInside() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var o=new Organization()",
"var p1=new Person()",
"p1.name=\"Nick\"",
"var p2=new Person()",
"p2.name=\"Axel\"",
"o.persons+=p1",
"o.persons+=p2",
"o.persons.count",
"o.persons",
"o.persons.name",
"var p3=new Person()",
"o.persons+=p3",
"o.persons.name", // produces a multi-object with one EmptyObject inside
"o.persons.name.length()"); // tests a call on a multi-object with empty object inside
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(14, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] { new Fraction(4), new Fraction(4)}, result[13]);
}
public void testOrderedAssoc1() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var o=new OrderedAssocTest()",
"o.orderedNumbers+=1",
"o.orderedNumbers+=2",
"o.orderedNumbers+=3",
"o.orderedNumbers+=4",
"o.orderedNumbers",
"o.orderedNumbers = o.orderedNumbers->including[2](3.5)",
"o.orderedNumbers",
"o.orderedNumbers-=3",
"o.orderedNumbers",
"o.orderedNumbers+=4",
"o.orderedNumbers");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
// String[] errors = executeResult.getErrors();
assertEquals(12, result.length);
// assertEquals(0, errors.length); // TODO reanimate error check when models are fixed
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4)},
result[5]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(1), new Fraction(2), new Fraction(7, 2), new Fraction(3), new Fraction(4)},
result[7]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(1), new Fraction(2), new Fraction(7, 2), new Fraction(4)},
result[9]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] {
new Fraction(1), new Fraction(2), new Fraction(7, 2), new Fraction(4), new Fraction(4)},
result[11]);
}
public void testSelectionExpression() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new SelectionTest().filterSmallElements(1->including(2), 2)",
"new SelectionTest().filterSmallElements(1->including(2), 3)",
"new SelectionTest().filterSmallElements(1->including(2), 1)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(3, result.length);
assertEquals(0, errors.length); // output multiplicities problems
assertNOEquals(new Fraction(1), result[0].iterator().next());
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] { new Fraction(1), new Fraction(2) }, result[1]);
assertEquals(0, result[2].size());
}
public void testSelectionAtIndex() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new SelectionTest().getAtIndices(1->including(2), 2)",
"new SelectionTest().getAtIndices(1->including(2), 1)",
"new SelectionTest().getAtIndices(1->including(2), 1->including(0))");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(3, result.length);
assertEquals(0, errors.length);
assertEquals(1, result[0].size()); // should result in a multi-object with one empty object
assertEquals(0, result[0].iterator().next().size()); // should result in a multi-object with one empty object
assertNOEquals(new Fraction(2), result[1].iterator().next());
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(new Fraction[] { new Fraction(2), new Fraction(1) }, result[2]);
}
public void testSelectionWithUnorderedIndices() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"String[] s = \"abc\"->including(\"def\")->including(\"ghi\")->including(\"jkl\")",
"Number* n = 2->including(1)",
"s[n]",
"s[2->including(1)]");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(4, result.length);
assertEquals(0, errors.length);
Iterator<RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>> iter = result[2].iterator();
assertNOEquals("def", iter.next());
assertNOEquals("ghi", iter.next());
iter = result[3].iterator();
assertNOEquals("ghi", iter.next());
assertNOEquals("def", iter.next());
}
public void testIteratorTyping() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new IteratorTest().m()");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertNOEquals("Axel", result[0]);
}
public void testSelectionWithMultiObjects() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new SelectionTest().filterNestedMultiplicityElements(2)",
"new SelectionTest().filterNestedMultiplicityElements(3)");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(2, result.length);
assertEquals(0, errors.length);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(
new Fraction[] { new Fraction(1) }, result[0]);
assertMultiObjectOfNativeObjectsEqualsIgnoringOrdering(
new Fraction[] { new Fraction(1), new Fraction(1), new Fraction(2) },
result[1]);
}
public void testCheckForEmptyObject() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"Number * empty",
"Number * notEmpty",
"notEmpty = notEmpty->including(1)",
"var equal1 = empty == notEmpty",
"var equal2 = notEmpty == empty");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(5, result.length);
assertEquals(0, errors.length);
assertNOEquals(false, result[3]);
assertNOEquals(false, result[4]);
}
public void testContentEquality() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var c1=new City()",
"var c2=new City()",
"c1.name=\"abc\"",
"c2.name=\"abc\"",
"c1 <=> c2",
"c1.name=\"def\"",
"c1 <=> c2");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(7, result.length);
assertEquals(0, errors.length);
assertNOEquals(true, result[4]);
assertNOEquals(false, result[6]);
}
public void testContentEqualityOnMultiObjects() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"var c = new City()",
"c.name = \"Karl-Marx-Stadt\"",
"store c",
"var ss1 = commit",
"c.name = \"Chemnitz\"",
"var ss2 = commit",
"all[ss1] City == all[ss2] City",
"all[ss1] City <=> all[ss2] City");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(8, result.length);
assertEquals(0, errors.length);
assertNOEquals(true, result[6]);
assertNOEquals(false, result[7]);
}
/**
* This test case was created because temporarily we have/had the problem of being
* unable to create a proper respective model in the evaluator because of issues with
* unresolved reference handling. This test case, however, relies on a readily parsed
* (with hacks and manual interventions) test model that uses entity creation with
* property initializers.
*/
public void testEntityCreationWithInitializersInClass() throws Exception {
ExecuteResult<AssociationEnd, TypeDefinition, ClassTypeDefinition> executeResult = main.execute(
"new City().m().name");
RunletObject<AssociationEnd, TypeDefinition, ClassTypeDefinition>[] result = executeResult.getResult();
String[] errors = executeResult.getErrors();
assertEquals(1, result.length);
assertEquals(0, errors.length);
assertNOEquals("Karl-Marx-Stadt", result[0]);
}
}