package com.sap.furcas.parser.tcs.scenario; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Iterator; import org.junit.BeforeClass; import org.junit.Test; import com.sap.furcas.parsergenerator.TCSSyntaxContainerBean; import com.sap.furcas.runtime.parser.ParserFacade; import com.sap.furcas.runtime.parser.exceptions.UnknownProductionRuleException; import com.sap.furcas.runtime.parser.testbase.GeneratedParserBasedTest; import com.sap.furcas.runtime.parser.testbase.GeneratedParserTestConfiguration; import com.sap.furcas.runtime.parser.testbase.stubs.StubModelAdapter; import com.sap.furcas.runtime.parser.testbase.stubs.StubModelElement; import com.sap.furcas.runtime.parser.testbase.stubs.StubParsingHelper; import com.sap.furcas.test.fixture.ScenarioFixtureData; /** * Simple Test for the custom Expression language */ public class TestPeople extends GeneratedParserBasedTest { private static final String LANGUAGE = "People"; private static final File TCS = ScenarioFixtureData.PEOPLE_TCS; private static final File[] METAMODELS = { ScenarioFixtureData.PEOPLE_METAMODEL }; private static StubParsingHelper parsingHelper; @BeforeClass public static void setupParser() throws Exception { GeneratedParserTestConfiguration testConfig = new GeneratedParserTestConfiguration(LANGUAGE, TCS, METAMODELS); TCSSyntaxContainerBean syntaxBean = parseSyntax(testConfig); ParserFacade facade = generateParserForLanguage(syntaxBean, testConfig, new ClassLookupImpl()); parsingHelper = new StubParsingHelper(facade); } @Test public void testSampleDirect() throws Exception { String world1 = "world {\n" + " Germany [ \n" + " Karlsruhe (\n" + " \"John Doe\" @ Berlin\n" + " )\n" + " representative: \"Erwin Meier\" ,\n" + " Berlin(\n" + " \"Erwin Meier\" @ Berlin\n" + " (" + " mother:\"Ute Meier\"\n" + // " father:\"Michael Meier\"" + " )\n" + " spouse: \"Ute Meier\"" + " ),\n" + " Koeln(\n" + " \"Ute Meier\" @ Koeln\n" + // " \"Michael Meier\" @ Berlin\n" + " )\n" + " ]\n" + " capital: Berlin\n" + "}\n"; StubModelAdapter stubModelHandler = parseString(world1, 0); Collection<StubModelElement> nations = stubModelHandler.getElementsOfType("People::Nation"); Collection<StubModelElement> persons = stubModelHandler.getElementsOfType("People::Person"); Collection<StubModelElement> cities = stubModelHandler.getElementsOfType("People::City"); assertEquals(1, nations.size()); assertEquals(3, cities.size()); assertEquals(3, persons.size()); StubModelElement nation1 = nations.iterator().next(); assertEquals("Germany", nation1.get("name")); Iterator<StubModelElement> cityIt = cities.iterator(); StubModelElement city1 = cityIt.next(); StubModelElement city2 = cityIt.next(); StubModelElement city3 = cityIt.next(); StubModelElement karlsruhe; StubModelElement berlin; StubModelElement koeln; if (city1.get("name").equals("Berlin")) { berlin = city1; if (city2.get("name").equals("Karlsruhe")) { karlsruhe = city2; koeln = city3; } else { karlsruhe = city3; koeln = city2; } } else if (city1.get("name").equals("Karlsruhe")) { karlsruhe = city1; if (city2.get("name").equals("Berlin")) { berlin = city2; koeln = city3; } else { berlin = city3; koeln = city2; } } else { koeln = city1; if (city2.get("name").equals("Berlin")) { berlin = city2; karlsruhe = city3; } else { berlin = city3; karlsruhe = city2; } } StubModelElement person1 = (StubModelElement) karlsruhe.get("persons"); assertEquals("John Doe", person1.get("name")); StubModelElement person2 = (StubModelElement) berlin.get("persons"); assertEquals("Erwin Meier", person2.get("name")); assertEquals(koeln.get("persons"), person2.get("parents")); assertEquals(koeln.get("persons"), person2.get("spouse")); assertEquals("Berlin", berlin.get("name")); assertEquals(berlin, nation1.get("capital")); assertEquals("Karlsruhe", karlsruhe.get("name")); assertEquals(person2, karlsruhe.get("representative")); // stubmodel does not deal with multivalued properties assertEquals(person1, (karlsruhe.get("persons"))); assertEquals(berlin, person1.get("embassy")); assertEquals(berlin, person1.get("embassy2")); assertEquals(berlin, person1.get("currentlyIn")); // default values from syntax assertEquals(new Integer(42), person1.get("age")); assertEquals(new Boolean(true), person1.get("male")); assertEquals(new Double(1.83), person1.get("height")); assertEquals("Viper", person1.get("codeName")); } @Test public void testPostFixOperator() throws Exception { String world1 = "heaven {\n" + " Germany [ \n" + " Karlsruhe (\n" + " \"John Doe\" @ Berlin\n" + " )\n" + " ]\n" + " capital: Karlsruhe\n" + "}\n" + "--This is a comment\n" + "defs: \"John Doe\"*\n"; StubModelAdapter stubModelHandler = parseString(world1, 0); Collection<StubModelElement> worlds = stubModelHandler.getElementsOfType("People::World"); Collection<StubModelElement> nations = stubModelHandler.getElementsOfType("People::Nation"); Collection<StubModelElement> persons = stubModelHandler.getElementsOfType("People::Person"); Collection<StubModelElement> cities = stubModelHandler.getElementsOfType("People::City"); Collection<StubModelElement> defs = stubModelHandler.getElementsOfType("People::ConcretePersonDefinition"); Collection<StubModelElement> nesteddefs = stubModelHandler.getElementsOfType("People::NestedPersonDefinition"); assertEquals(1, worlds.size()); assertEquals(1, nations.size()); assertEquals(1, cities.size()); assertEquals(1, persons.size()); assertEquals(1, defs.size()); assertEquals(1, nesteddefs.size()); StubModelElement world = worlds.iterator().next(); StubModelElement nation1 = nations.iterator().next(); assertEquals("Germany", nation1.get("name")); StubModelElement person1 = persons.iterator().next(); assertEquals("John Doe", person1.get("name")); StubModelElement def = defs.iterator().next(); assertEquals(person1, def.get("person")); StubModelElement nestedDef = nesteddefs.iterator().next(); assertEquals(nestedDef, world.get("definitions")); assertEquals(def, nestedDef.get("nestedPersonDefinition")); assertEquals("*", nestedDef.get("op")); } // Override ModelAdapter to allow setting of inverse references when setting nation.cities: also set city.nation protected StubModelAdapter parseString(String sample, int expectedErrors) throws IOException, UnknownProductionRuleException { StubModelAdapter stubModelHandler = new StubModelAdapter() { @Override public void set(Object ame, String prop, Object value) { super.set(ame, prop, value); if (prop.equals("cities") && value != null) { ((StubModelElement) value).set("nation", ame); } } @Override public Object setReferenceWithOCLQuery(Object modelElement, String propertyName, Object keyValue, String mqlQuery, Object contextObject, Object currentForeachElement) { Object result = null; if (propertyName.equals("representative")) { StubModelElement capital = ((StubModelElement) ((StubModelElement) contextObject).get("capital")); if (capital != null) { result = capital.get("persons"); ((StubModelElement) modelElement).set("representative", result); } } else if (propertyName.equals("embassy2") && ((StubModelElement) modelElement).get("currentlyIn") != null && ((StubModelElement) ((StubModelElement) modelElement).get("currentlyIn")).get("nation") != null) { result = ((StubModelElement) ((StubModelElement) ((StubModelElement) modelElement).get("currentlyIn")) .get("nation")).get("capital"); ((StubModelElement) modelElement).set("embassy2", result); } else if (propertyName.equals("spouse")) { for (StubModelElement person : getElementsOfType("People::Person")) { if (person.get("name").equals(keyValue)) { result = person; ((StubModelElement) modelElement).set("spouse", result); break; } } } return result; } }; InputStream charStream = new ByteArrayInputStream(sample.getBytes()); parsingHelper.parseStream(charStream, expectedErrors, stubModelHandler); return stubModelHandler; } }