/******************************************************************************* * Copyright (c) 2011 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation ******************************************************************************/ package com.sap.furcas.prettyprinter; import static com.sap.furcas.prettyprinter.SyntaxCreationHelper.createKeyword; import static com.sap.furcas.prettyprinter.SyntaxCreationHelper.createSequence; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import org.eclipse.emf.ecore.EObject; import org.junit.Test; import com.sap.furcas.emf.stubs.EcoreAnyStub; import com.sap.furcas.metamodel.FURCAS.TCS.Alternative; import com.sap.furcas.metamodel.FURCAS.TCS.ClassTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.InjectorActionsBlock; import com.sap.furcas.metamodel.FURCAS.TCS.LiteralRef; import com.sap.furcas.metamodel.FURCAS.TCS.LookupPropertyInit; import com.sap.furcas.metamodel.FURCAS.TCS.PrimitivePropertyInit; import com.sap.furcas.metamodel.FURCAS.TCS.PropertyInit; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceElement; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceInAlternative; import com.sap.furcas.metamodel.FURCAS.TCS.TCSFactory; import com.sap.furcas.metamodel.FURCAS.textblocks.TextBlock; import com.sap.furcas.parser.tcs.TCSParserFactory; import com.sap.furcas.prettyprinter.context.InitialPrintContext; import com.sap.furcas.prettyprinter.context.PrintContext; import com.sap.furcas.prettyprinter.context.PrintResult; import com.sap.furcas.prettyprinter.exceptions.PropertyInitMismatchException; import com.sap.furcas.prettyprinter.exceptions.SyntaxMismatchException; import com.sap.furcas.prettyprinter.policy.DefaultPrintPolicy; import com.sap.furcas.runtime.tcs.TcsUtil; import com.sap.furcas.runtime.textblocks.TbDebugUtil; import com.sap.furcas.runtime.textblocks.validation.TbValidationUtil; /** * @author Stephan Erb * */ public class TestTemplateHandler { private static TCSFactory tcsFactory = TCSFactory.eINSTANCE; private static TextBlocksFactory tbfactory = new TextBlocksFactory(new TCSParserFactory()); private static Formatter formatter = new Formatter(tbfactory); /** * Serialize a empty ClassTemplate leading to the creation of an empty TextBlock */ @Test public void testSerializeClassTemplate() throws Exception { ClassTemplate template = tcsFactory.createClassTemplate(); template.setTemplateSequence(createSequence()); TemplateHandler handler = createTemplateHandler(); PrintResult result = handler.serializeContextTemplate(new EcoreAnyStub(), template, /*seqElem*/ null, new InitialPrintContext(), new DefaultPrintPolicy()); assertEquals("Expect one block", 1, result.getNodes().size()); TextBlock textBlock = (TextBlock) result.getNodes().get(0); assertEquals(0, textBlock.getOffset()); assertEquals(0, textBlock.getLength()); assertSame(template, textBlock.getType()); TbValidationUtil.assertTextBlockConsistencyRecursive(textBlock); } /** * Serialize a ClassTemplate which consists of two keywords, leading to the * creation of a non-empty TextBlock. */ @Test public void testSerializeClassTemplateWithContent() throws Exception { LiteralRef litRef1 = createKeyword("first"); LiteralRef litRef2 = createKeyword("second"); ClassTemplate template = tcsFactory.createClassTemplate(); template.setTemplateSequence(createSequence(litRef1, litRef2)); TemplateHandler handler = createTemplateHandler(); PrintResult result = handler.serializeContextTemplate(new EcoreAnyStub(), template, /*seqElem*/ null, new InitialPrintContext(), new DefaultPrintPolicy()); assertEquals("Expect one block", 1, result.getNodes().size()); TextBlock textBlock = (TextBlock) result.getNodes().get(0); // Check for correct overall text assertEquals("first second", TbDebugUtil.getDocumentNodeAsPlainString(textBlock)); // Check for correct offset/length handling assertEquals(0, textBlock.getOffset()); assertEquals("first second".length(), textBlock.getLength()); TbValidationUtil.assertTextBlockConsistencyRecursive(textBlock); } private TemplateHandler createTemplateHandler() { TemplateHandler handler = new TemplateHandler(tbfactory, formatter, /*syntax lookuk*/ null); handler.setSequenceHandler(new SequenceHandler(tbfactory, /*templateFinder*/ null, handler, /*oclEvaluator*/ null, /*validator*/ null, formatter)); return handler; } /** * Serialize two nested alternative with two sequences containing property inits: * [[ * [[ {{propInit1}} | {{propInit2}} ]] * | * [[ {{propInit3}} | {{propInit3}} ]] * ]] * * Assert that the create textblock is correct, in the sense that the correct * property inits are considered executed. This is to make sure that the * {@link TextBlock#getParentAltChoices()} contains the right values. */ @Test public void testTemplateWithAlternatives() throws Exception { PropertyInit propInit1 = tcsFactory.createLookupPropertyInit(); PropertyInit propInit2 = tcsFactory.createLookupPropertyInit(); PropertyInit propInit3 = tcsFactory.createPrimitivePropertyInit(); // the one that we consider executed PropertyInit propInit4 = tcsFactory.createLookupPropertyInit(); Alternative firstInnerAlt = createAlternativeWithTwoChoicesContaining(createBlock(propInit1), createBlock(propInit2)); Alternative secondInnerAlt = createAlternativeWithTwoChoicesContaining(createBlock(propInit3), createBlock(propInit4)); Alternative outerAlt = createAlternativeWithTwoChoicesContaining(firstInnerAlt, secondInnerAlt); ClassTemplate template = tcsFactory.createClassTemplate(); template.setTemplateSequence(createSequence(outerAlt)); // Create a specific validator that considers: // PrimitivePropertyInit executed/matching // LookupPropertyInits not executed/invalid // SequenceElementValidator validator = new SequenceElementValidator(/*oclEvaluator*/ null) { @Override public void validateLookupPropertyInit(EObject modelElement, LookupPropertyInit propInit, PrintContext context) throws SyntaxMismatchException { throw new PropertyInitMismatchException("actual", "expected", propInit); } @Override public void validatePrimitivePropertyInit(Object element, PrimitivePropertyInit propInit) throws SyntaxMismatchException { } }; TemplateHandler handler = new TemplateHandler(tbfactory, formatter, /*syntax lookuk*/ null); handler.setSequenceHandler(new SequenceHandler(tbfactory, /*templateFinder*/ null, handler, /*oclEvaluator*/ null, validator, formatter)); PrintContext context = new InitialPrintContext(); PrintResult result = handler.serializeContextTemplate(new EcoreAnyStub(), template, /*seqElem*/ null, context, new DefaultPrintPolicy()); assertEquals("Expect one block", 1, result.getNodes().size()); TextBlock textBlock = (TextBlock) result.getNodes().get(0); // Prop inits have no syntactic contribution assertEquals(0, textBlock.getOffset()); assertEquals(0, textBlock.getLength()); assertSame(template, textBlock.getType()); // Check the actual execution state assertFalse(TcsUtil.wasExecuted(template, textBlock.getParentAltChoices(), propInit1.getInjectorActionsBlock())); assertFalse(TcsUtil.wasExecuted(template, textBlock.getParentAltChoices(), propInit2.getInjectorActionsBlock())); assertTrue(TcsUtil.wasExecuted(template, textBlock.getParentAltChoices(), propInit3.getInjectorActionsBlock())); assertFalse(TcsUtil.wasExecuted(template, textBlock.getParentAltChoices(), propInit4.getInjectorActionsBlock())); TbValidationUtil.assertTextBlockConsistencyRecursive(textBlock); } private SequenceElement createBlock(PropertyInit propInit1) { InjectorActionsBlock block = tcsFactory.createInjectorActionsBlock(); block.getInjectorActions().add(propInit1); return block; } private Alternative createAlternativeWithTwoChoicesContaining(SequenceElement inFirst, SequenceElement inSecond) { Alternative alternative = tcsFactory.createAlternative(); SequenceInAlternative firstChoice = tcsFactory.createSequenceInAlternative(); SequenceInAlternative secondChoice = tcsFactory.createSequenceInAlternative(); alternative.getSequences().add(firstChoice); alternative.getSequences().add(secondChoice); firstChoice.getElements().add(inFirst); secondChoice.getElements().add(inSecond); return alternative; } }