package com.sap.furcas.ide.editor.contentassist; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.junit.Ignore; import org.junit.Test; import com.sap.furcas.metamodel.FURCAS.TCS.Alternative; 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.ConditionalElement; import com.sap.furcas.metamodel.FURCAS.TCS.CreateAsPArg; import com.sap.furcas.metamodel.FURCAS.TCS.FunctionCall; import com.sap.furcas.metamodel.FURCAS.TCS.FunctionTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.LiteralRef; import com.sap.furcas.metamodel.FURCAS.TCS.Property; import com.sap.furcas.metamodel.FURCAS.TCS.RefersToPArg; import com.sap.furcas.metamodel.FURCAS.TCS.SeparatorPArg; import com.sap.furcas.metamodel.FURCAS.TCS.Sequence; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceElement; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceInAlternative; import com.sap.furcas.metamodel.FURCAS.TCS.Template; import com.sap.furcas.parser.tcs.TCSParserFactory; import com.sap.furcas.runtime.tcs.PropertyArgumentUtil; import com.sap.furcas.runtime.tcs.TcsUtil; import com.sap.furcas.runtime.tcs.testbase.TCSFixtureTestBase; public class TestCtsCompletionCalculator extends TCSFixtureTestBase { @Test public void testContainsRefersToArg() { RefersToPArg refersToArg = modelFactory.createRefersToPArg(); CreateAsPArg createAsArg = modelFactory.createCreateAsPArg(); Property withRefersToArg = modelFactory.createProperty(); withRefersToArg.getPropertyArgs().add(refersToArg); Property withoutRefersToArg = modelFactory.createProperty(); withoutRefersToArg.getPropertyArgs().add(createAsArg); assertEquals(true, PropertyArgumentUtil.containsRefersToArg(withRefersToArg)); assertEquals(false, PropertyArgumentUtil.containsRefersToArg(withoutRefersToArg)); } @Test public void testGetPossibleAtomicFollowsMain1Lit() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); // main2Cond then branch expected.add(main2CondThenLit); // main2Cond else branch expected.add(null); // main3Prop, as main2Cond else branch is null expected.add(main3Prop); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main1Lit, null, null, null, false, null)); } @Test public void testGetPossibleAtomicFollowsMain2CondThenLit() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main3Prop); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main2CondThenLit, null, null, null, false, null)); } @Test public void testGetPossibleAtomicFollowsMain3Prop() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main4AltCase1Lit); expected.add(main4AltCase2Lit); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main3Prop, null, null, null, false, null)); } @Ignore("Failing after the EMF migration. Failing for unknown reasons") @Test public void testGetPossibleAtomicFollowsMain4AltCase1Lit() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); // from CustomSeparator expected.add(null); // multivalued property can be null expected.add(null); // only mode2 expected.add(functionTemplateTemplateLitMode2); expected.add(funcTemplateLit); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main4AltCase1Lit, null, classTemplateMap, null, false, null)); } @Ignore("Failing after the EMF migration. Failing for unknown reasons") @Test public void testGetPossibleAtomicFollowsMain5BlockProp() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); // add main5BlockProp Tokens, as it is a multi-valued Property // also add null, as no value is possible expected.add(null); // only mode2 expected.add(functionTemplateTemplateLitMode2); expected.add(funcTemplateLit); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main5BlockProp, null, classTemplateMap, null, false, null)); } @Test public void testGetPossibleAtomicFollowsFuncTemplateLitInMain6Call() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main7Lit); Stack<FunctionCall> parentFunctionCallStack = new Stack<FunctionCall>(); parentFunctionCallStack.push(main6Call); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(funcTemplateLit, parentFunctionCallStack, null, null, false, null)); } @Test public void testGetPossibleAtomicFollowsMain7Lit() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(funcTemplateLit); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(main7Lit, null, null, null, false, null)); } @Test public void testGetPossibleAtomicFollowsFuncTemplateLitInMain8Call() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main9Lit); Stack<FunctionCall> parentFunctionCallStack = new Stack<FunctionCall>(); parentFunctionCallStack.push(main8Call); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(funcTemplateLit, parentFunctionCallStack, null, null, false, null)); } @Test public void testGetPossibleAtomicFollowsNull() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); assertEquals(expected, CtsCompletionCalculator.getPossibleAtomicFollows(null, null, null, null, false, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain1Lit() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main1Lit); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main1Lit, null, visitedTemplates, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain2Cond() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main2CondThenLit); expected.add(null); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main2Cond, null, visitedTemplates, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain3Prop() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main3Prop); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main3Prop, null, visitedTemplates, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain4Alt() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(main4AltCase1Lit); expected.add(main4AltCase2Lit); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main4Alt, null, visitedTemplates, null)); } @Ignore("Failing after the EMF migration. Failing for unknown reasons") @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain5Block() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); // multivalued property can be null expected.add(null); // only mode2 expected.add(functionTemplateTemplateLitMode2); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main5Block, classTemplateMap, visitedTemplates, null)); } @Test(expected = IllegalArgumentException.class) public void testGetPossibleFirstAtomicSequenceElementsSequenceElementMain5BlockNullClassTemplateMap() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(functionTemplateTemplateLitMode1); expected.add(functionTemplateTemplateLitMode2); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(main5Block, null, visitedTemplates, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequenceElementNull() { List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(null); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements((SequenceElement) null, null, visitedTemplates, null)); } @Test public void testGetPossibleFirstAtomicSequenceElementsSequence() { Sequence s = modelFactory.createSequence(); ConditionalElement condA = modelFactory.createConditionalElement(); Sequence condASeq = modelFactory.createSequence(); LiteralRef condASeqLit = modelFactory.createLiteralRef(); condASeq.getElements().add(condASeqLit); condA.setThenSequence(condASeq); ConditionalElement condB = modelFactory.createConditionalElement(); Sequence condBSeq = modelFactory.createSequence(); LiteralRef condBSeqLit = modelFactory.createLiteralRef(); condBSeq.getElements().add(condBSeqLit); condB.setThenSequence(condBSeq); s.getElements().add(condA); s.getElements().add(condB); List<SequenceElement> expected = new ArrayList<SequenceElement>(); expected.add(condASeqLit); expected.add(null); expected.add(condBSeqLit); expected.add(null); Set<Template> visitedTemplates = new HashSet<Template>(); assertEquals(expected, CtsCompletionCalculator.getPossibleFirstAtomicSequenceElements(s, null, visitedTemplates, null)); } @Test public void testGetFirstSequenceElement() { assertEquals(main1Lit, TcsUtil.getFirstSequenceElement(mainSeq)); assertEquals(main2CondThenLit, TcsUtil.getFirstSequenceElement(main2CondThenSeq)); // no elements Sequence testSeq = modelFactory.createSequence(); assertEquals(null, TcsUtil.getFirstSequenceElement(testSeq)); // sequence null assertEquals(null, TcsUtil.getFirstSequenceElement(null)); } @Test public void testIsLastSequenceElement() { // null should never be last assertEquals(false, TcsUtil.isLastSequenceElement(null)); assertEquals(false, TcsUtil.isLastSequenceElement(main1Lit)); assertEquals(false, TcsUtil.isLastSequenceElement(main4Alt)); assertEquals(true, TcsUtil.isLastSequenceElement(main9Lit)); assertEquals(true, TcsUtil.isLastSequenceElement(main2CondThenLit)); } @Test public void testGetNextSequenceElement() { assertEquals(main2Cond, TcsUtil.getNextSequenceElement(main1Lit)); assertEquals(main5Block, TcsUtil.getNextSequenceElement(main4Alt)); // last element assertEquals(null, TcsUtil.getNextSequenceElement(main9Lit)); assertEquals(null, TcsUtil.getNextSequenceElement(main2CondThenLit)); // parent null LiteralRef testElem = modelFactory.createLiteralRef(); assertEquals(null, TcsUtil.getNextSequenceElement(testElem)); assertEquals(null, TcsUtil.getNextSequenceElement(null)); } @Test public void testGetParentSequenceElementBlock() { Block block = modelFactory.createBlock(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); block.setBlockSequence(sequence); assertEquals(block, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetParentSequenceElementConditionalThen() { ConditionalElement cond = modelFactory.createConditionalElement(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); cond.setThenSequence(sequence); assertEquals(cond, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetParentSequenceElementConditionalElse() { ConditionalElement cond = modelFactory.createConditionalElement(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); cond.setElseSequence(sequence); assertEquals(cond, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetParentSequenceElementAlternative() { Alternative alt = modelFactory.createAlternative(); SequenceInAlternative sequence = modelFactory.createSequenceInAlternative(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); alt.getSequences().add(sequence); assertEquals(alt, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetParentSequenceElementPropery() { Property prop = modelFactory.createProperty(); SeparatorPArg sepArg = modelFactory.createSeparatorPArg(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); sepArg.setSeparatorSequence(sequence); prop.getPropertyArgs().add(sepArg); assertEquals(prop, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetParentSequenceElementFunctionTemplate() { FunctionCall call = modelFactory.createFunctionCall(); FunctionTemplate template = modelFactory.createFunctionTemplate(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); template.setFunctionSequence(sequence); call.setCalledFunction(template); Stack<FunctionCall> parentFunctionCallStack = new Stack<FunctionCall>(); parentFunctionCallStack.push(call); assertEquals(call, TcsUtil.getParentSequenceElement(property, parentFunctionCallStack, null, classTemplateMap)); } @Test(expected = IllegalArgumentException.class) public void testGetParentSequenceElementFunctionTemplateNull() { FunctionCall call = modelFactory.createFunctionCall(); FunctionTemplate template = modelFactory.createFunctionTemplate(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); template.setFunctionSequence(sequence); call.setCalledFunction(template); assertEquals(call, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test(expected = IllegalArgumentException.class) public void testGetParentSequenceElementFunctionTemplateInvalidParentTemplate() { FunctionCall call = modelFactory.createFunctionCall(); FunctionCall invalidCall = modelFactory.createFunctionCall(); FunctionTemplate template = modelFactory.createFunctionTemplate(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); template.setFunctionSequence(sequence); call.setCalledFunction(template); Stack<FunctionCall> parentFunctionCallStack = new Stack<FunctionCall>(); parentFunctionCallStack.push(invalidCall); assertEquals(call, TcsUtil.getParentSequenceElement(property, parentFunctionCallStack, null, classTemplateMap)); } @Test public void testGetParentSequenceElementClassTemplate() { ClassTemplate template = modelFactory.createClassTemplate(); Sequence sequence = modelFactory.createSequence(); Property property = modelFactory.createProperty(); sequence.getElements().add(property); template.setTemplateSequence(sequence); assertEquals(null, TcsUtil.getParentSequenceElement(property, null, null, classTemplateMap)); } @Test public void testGetMainClassTemplate() { ConcreteSyntax syntax = modelFactory.createConcreteSyntax(); syntax.getTemplates().add(main); syntax.getTemplates().add(functionTemplateTemplateMode1); syntax.getTemplates().add(functionTemplateTemplateMode2); assertEquals(main, TcsUtil.getMainClassTemplate(syntax)); } @Test public void testCreateClassTemplateMap() { ResourceSet resourceSet = new ResourceSetImpl(); TCSParserFactory factory = new TCSParserFactory(); ConcreteSyntax tcsSyntax = (ConcreteSyntax) resourceSet.getEObject(URI.createURI(factory.getSyntaxUUID()), /*load*/ true); Map<List<String>, Map<String, ClassTemplate>> templateMap = TcsUtil.createClassTemplateMap(tcsSyntax); List<String> key = new ArrayList<String>(); key.add("FURCAS"); // package key.add("TCS"); // package key.add("ConcreteSyntax"); // typename assertNotNull(templateMap.get(key)); // mode is null assertNotNull(templateMap.get(key).get(null)); } @Test(expected = IllegalArgumentException.class) public void testCreateClassTemplateMapNullSyntax() { TcsUtil.createClassTemplateMap(null); } @Test public void testIsMultiValued() { Property multi1Prop = modelFactory.createProperty(); EStructuralFeature multi1Struc = EcoreFactory.eINSTANCE.createEReference(); multi1Struc.setLowerBound(0); multi1Struc.setUpperBound(-1); multi1Struc.setOrdered(false); multi1Struc.setUnique(false); setStrucfeature(multi1Prop, multi1Struc); assertEquals(true, TcsUtil.isMultiValued(multi1Prop)); Property multi2Prop = modelFactory.createProperty(); EStructuralFeature multi2Struc = EcoreFactory.eINSTANCE.createEAttribute(); multi2Struc.setLowerBound(0); multi2Struc.setUpperBound(2); multi2Struc.setOrdered(false); multi2Struc.setUnique(false); setStrucfeature(multi2Prop, multi2Struc); assertEquals(true, TcsUtil.isMultiValued(multi2Prop)); Property singleProp = modelFactory.createProperty(); EStructuralFeature singleStruc = EcoreFactory.eINSTANCE.createEReference(); singleStruc.setLowerBound(0); singleStruc.setUpperBound(1); singleStruc.setOrdered(false); singleStruc.setUnique(false); setStrucfeature(singleProp, singleStruc); assertEquals(false, TcsUtil.isMultiValued(singleProp)); } }