/**
*
*/
package com.sap.furcas.runtime.parser.incremental;
import static com.sap.furcas.runtime.common.util.FileResourceHelper.getResourceSetAsScope;
import static com.sap.furcas.runtime.common.util.FileResourceHelper.loadResourceSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.antlr.runtime.Lexer;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.sap.furcas.metamodel.FURCAS.TCS.Block;
import com.sap.furcas.metamodel.FURCAS.TCS.ClassTemplate;
import com.sap.furcas.metamodel.FURCAS.TCS.ConcreteSyntax;
import com.sap.furcas.metamodel.FURCAS.TCS.LiteralRef;
import com.sap.furcas.metamodel.FURCAS.TCS.PrimitiveTemplate;
import com.sap.furcas.metamodel.FURCAS.TCS.Template;
import com.sap.furcas.metamodel.FURCAS.textblocks.AbstractToken;
import com.sap.furcas.metamodel.FURCAS.textblocks.TextBlock;
import com.sap.furcas.parser.tcs.TCSParserFactory;
import com.sap.furcas.runtime.parser.ParserFactory;
import com.sap.furcas.runtime.parser.impl.ObservableInjectingParser;
import com.sap.furcas.runtime.parser.testbase.MockPartitionAssignmentHandler;
import com.sap.furcas.runtime.textblocks.model.TextBlocksModel;
import com.sap.furcas.runtime.textblocks.modifcation.TbChangeUtil;
import com.sap.furcas.runtime.textblocks.testutils.EMFTextBlocksModelElementFactory;
import com.sap.furcas.runtime.textblocks.testutils.TestSourceTextBlockCreator;
import com.sap.furcas.runtime.textblocks.testutils.TextBlocksModelElementFactory;
import com.sap.furcas.test.fixture.ScenarioFixtureData;
import com.sap.furcas.test.testutils.ResourceTestHelper;
import com.sap.ide.cts.parser.incremental.IncrementalParserFacade;
public class TestParsingObserverWithTcsSyntax {
private IncrementalParserFacade incrementalParserFacade;
private TextBlocksModelElementFactory modelFactory;
private Resource transientParsingResource;
private ResourceSet resourceSet;
private void setupParserFor(final Set<URI> metamodels) throws Exception {
resourceSet = ResourceTestHelper.createResourceSet();
transientParsingResource = ResourceTestHelper.createTransientResource(resourceSet);
ParserFactory<? extends ObservableInjectingParser, ? extends Lexer> parserFactory = new TCSParserFactory() {
/**
* We must be able to reference the metamodels to which the different TCS
* languages that we parse refer to.
*/
@Override
public Set<URI> getAdditionalQueryScope() {
return metamodels;
}
};
incrementalParserFacade = new IncrementalParserFacade(parserFactory, resourceSet,
new MockPartitionAssignmentHandler(transientParsingResource));
ECrossReferenceAdapter crossRefAdapter = new ECrossReferenceAdapter();
resourceSet.eAdapters().add(crossRefAdapter);
crossRefAdapter.setTarget(resourceSet);
}
@Before
public void setup() {
modelFactory = new EMFTextBlocksModelElementFactory();
}
@After
public void cleanup() throws Exception {
transientParsingResource.delete(/*options*/ null);
}
@Test
public void testParseTcsItself() throws Exception {
File[] metamodels = { ScenarioFixtureData.TCS_OBSOLETE_METAMODEL };
ResourceSet metamodelResources = loadResourceSet(metamodels);
setupParserFor(getResourceSetAsScope(metamodelResources));
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, getTcsFileContent(ScenarioFixtureData.TCS_OBSOLETE_TCS));
TextBlock currentVersionTb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = currentVersionTb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("TCSObsolete", syntax.getName());
assertEquals(78, syntax.getTemplates().size());
assertNotNull(currentVersionTb); // future version
assertEquals(152, currentVersionTb.getSubNodes().size());
}
@Test
public void testParseBibText() throws Exception {
File[] metamodels = { ScenarioFixtureData.BIBTEXT1_METAMODEL, ScenarioFixtureData.BIBTEXT_METAMODEL };
ResourceSet metamodelResources = loadResourceSet(metamodels);
setupParserFor(getResourceSetAsScope(metamodelResources));
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, getTcsFileContent(ScenarioFixtureData.BIBTEXT_TCS));
TextBlock currentVersionTb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = currentVersionTb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("Bibtext", syntax.getName());
assertEquals(7, syntax.getTemplates().size());
assertNotNull(currentVersionTb); // future version
assertEquals(81, currentVersionTb.getSubNodes().size());
}
@Test
public void testMinimalSyntax() throws Exception {
HashSet<URI> metamodels = new HashSet<URI>();
metamodels.addAll(ResourceTestHelper.createFURCASReferenceScope());
setupParserFor(metamodels);
String syntaxString = "syntax test{}";
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, syntaxString);
TextBlock tb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = tb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("test", syntax.getName());
assertEquals(0, syntax.getTemplates().size());
}
@Test
public void testMinimalSyntaxWithMain() throws Exception {
HashSet<URI> metamodels = new HashSet<URI>();
metamodels.addAll(ResourceTestHelper.createFURCASReferenceScope());
setupParserFor(metamodels);
String syntaxString = "syntax test{template ClassTemplate main :\"foo\";}";
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, syntaxString);
TextBlock tb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = tb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("test", syntax.getName());
assertEquals(1, syntax.getTemplates().size());
Template fooTemplate = syntax.getTemplates().get(0);
assertTrue(fooTemplate instanceof ClassTemplate);
assertEquals("ClassTemplate", fooTemplate.getMetaReference().getName());
}
@Test
public void testMinimalSyntaxWith2PrimitiveTemps() throws Exception {
HashSet<URI> metamodels = new HashSet<URI>();
metamodels.addAll(ResourceTestHelper.createEcoreReferenceScope());
setupParserFor(metamodels);
String syntaxString = "syntax test{\r\n"
+ " primitiveTemplate identifier for EString using NAME:value=\"%token%\";\r\n"
+ " primitiveTemplate name for EString using NAME:value=\"%token%\";\r\n" + "}";
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, syntaxString);
TextBlock tb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = tb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("test", syntax.getName());
assertEquals(2, syntax.getTemplates().size());
Template fooTemplate = syntax.getTemplates().get(0);
assertEquals("identifier", ((PrimitiveTemplate) fooTemplate).getTemplateName());
Template barTemplate = syntax.getTemplates().get(1);
assertEquals("name", ((PrimitiveTemplate) barTemplate).getTemplateName());
}
@Test
public void testMinimalSyntaxWithMainAndBlanks() throws Exception {
HashSet<URI> metamodels = new HashSet<URI>();
metamodels.addAll(ResourceTestHelper.createEcoreReferenceScope());
setupParserFor(metamodels);
String syntaxString = "\r\n \r\n\tsyntax test {\r\n \r\n \r\n template ecore::EClass main \r\n : \"foo\"\r\n ;}";
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, syntaxString);
TextBlock tb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = tb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("test", syntax.getName());
assertEquals(1, syntax.getTemplates().size());
Template fooTemplate = syntax.getTemplates().get(0);
assertTrue(fooTemplate instanceof ClassTemplate);
assertEquals("EClass", fooTemplate.getMetaReference().getName());
}
@Test
public void testParseATL() throws Exception {
File[] metamodels = { ScenarioFixtureData.ATL_METAMODEL };
ResourceSet metamodelResources = loadResourceSet(metamodels);
setupParserFor(getResourceSetAsScope(metamodelResources));
File syntaxDefFile = ScenarioFixtureData.ATL_TCS;
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
TextBlocksModel tbModel = new TextBlocksModel(root);
tbModel.replace(0, 0, getTcsFileContent(syntaxDefFile));
TextBlock currentVersionTb = incrementalParserFacade.parseIncrementally(root);
Object syntaxObject = currentVersionTb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = (ConcreteSyntax) syntaxObject;
assertEquals("ATL", syntax.getName());
assertEquals(85, syntax.getTemplates().size());
assertNotNull(currentVersionTb); // future version
assertEquals(176, currentVersionTb.getSubNodes().size());
}
/**
* Tests whether a reference where the reference by value was replaced is
* correctly set to thw new value;
*/
@Test
public void testParseBibTextReplaceReference() throws Exception {
File[] metamodels = { ScenarioFixtureData.BIBTEXT1_METAMODEL, ScenarioFixtureData.BIBTEXT_METAMODEL };
ResourceSet metamodelResources = loadResourceSet(metamodels);
setupParserFor(getResourceSetAsScope(metamodelResources));
AbstractToken content = modelFactory.createToken("");
TextBlock root = TestSourceTextBlockCreator.initialiseTextBlocksWithContentToken(modelFactory, content);
transientParsingResource.getContents().add(root);
TextBlocksModel tbModel = new TextBlocksModel(root);
String tcsContent = getTcsFileContent(ScenarioFixtureData.BIBTEXT_TCS);
tbModel.replace(0, 0, tcsContent);
TextBlock currentVersionTb = incrementalParserFacade.parseIncrementally(root);
ConcreteSyntax syntaxObject = (ConcreteSyntax) currentVersionTb.getCorrespondingModelElements().iterator().next();
// assert no exception
assertNotNull(syntaxObject);
ConcreteSyntax syntax = syntaxObject;
assertEquals("Bibtext", syntax.getName());
assertEquals(7, syntax.getTemplates().size());
Template article = syntaxObject.getTemplates().get(3);
assertNotNull(currentVersionTb); // future version
assertEquals(81, currentVersionTb.getSubNodes().size());
TbChangeUtil.cleanUp(currentVersionTb);
// replace a reference that referred to the "." token with one that
// refers to the "{" token
tbModel = new TextBlocksModel(currentVersionTb);
tbModel.replace(tcsContent.indexOf(","), 1, "{");
TextBlock currentVersionTbNew = incrementalParserFacade.parseIncrementally(currentVersionTb);
// textBlock shouldn't have changed
assertEquals(currentVersionTb, currentVersionTb);
ConcreteSyntax syntaxObject2 = (ConcreteSyntax) currentVersionTbNew.getCorrespondingModelElements().iterator().next();
// syntax element shouldn't have changed
assertEquals(syntaxObject, syntaxObject2);
ClassTemplate article2 = (ClassTemplate) syntaxObject2.getTemplates().get(3);
assertEquals(article, article2);
Block b = (Block) article2.getTemplateSequence().getElements().get(2);
LiteralRef lit = (LiteralRef) b.getBlockSequence().getElements().get(1);
assertEquals("{", lit.getReferredLiteral().getValue());
}
private String getTcsFileContent(File syntaxDefFile) {
String content = null;
if (syntaxDefFile != null) {
try {
FileInputStream inputStream = new FileInputStream(syntaxDefFile);
StringBuilder out = new StringBuilder();
byte[] b = new byte[4096];
for (int n; (n = inputStream.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
content = out.toString();
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return content;
}
}