/** * */ package com.sap.furcas.modeladaptation.emf.lookup; import static com.sap.furcas.test.testutils.StringListHelper.list; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.ocl.ecore.EcorePackage; import org.eclipse.ocl.ecore.opposites.DefaultOppositeEndFinder; import org.eclipse.ocl.ecore.opposites.OppositeEndFinder; import org.junit.Test; import com.sap.furcas.emf.stubs.EcoreAnyStub; import com.sap.furcas.metamodel.FURCAS.TCS.Template; import com.sap.furcas.runtime.common.exceptions.MetaModelLookupException; import com.sap.furcas.runtime.common.exceptions.NameResolutionFailedException; import com.sap.furcas.runtime.common.interfaces.MultiplicityBean; import com.sap.furcas.runtime.common.interfaces.ResolvedNameAndReferenceBean; import com.sap.furcas.test.testutils.ResolutionBeanHelper; /** * Tests the abstract AbstractMoinLookup class by creating a stub subclass and testing that. * Special care need to me taken to test for features that are structural features, Associations, or StructureTypes. */ public class TestAbstractEcoreMetaModelLookup { @Test public void testGetFeatureClassnameNull() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); Object featureClassname = lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature"); assertNull(featureClassname); } @Test public void testGetFeatureClassnameFeature() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); Object featureClassname = lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature"); assertNull(featureClassname); // create classifier stub EcoreAnyStub classi = new EcoreAnyStub(); classi.lookupElementExtendedKey = "feature"; lookup.classifier = classi; // create feature stub EcoreAnyStub feature = new EcoreAnyStub(); classi.lookupElementExtended = feature; EcoreAnyStub featureType = new EcoreAnyStub(); featureType.name = "featureType"; feature.type = featureType; featureClassname = lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature"); assertNotNull(featureClassname); assertEquals(ResolutionBeanHelper.refM("package", "featureType"), featureClassname); } @Test public void testGetMultiplicityFeature() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); EcoreAnyStub strucType = new EcoreAnyStub(); strucType.lookupElementExtendedKey = "feature"; // create feature stub EcoreAnyStub field = new EcoreAnyStub(); field.upper = 1; field.lower = 1; strucType.lookupElementExtended = field; lookup.classifier = strucType; MultiplicityBean bean = new MultiplicityBean(); bean.setUpperBound(1); bean.setLowerBound(1); assertEquals(bean, lookup.getMultiplicity(ResolutionBeanHelper.refM("package", "testType"), "feature")); } @Test public void testHasFeatureFeature() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); assertNull(lookup.getMultiplicity(ResolutionBeanHelper.refM("package", "testType"), "feature")); EcoreAnyStub classi = new EcoreAnyStub(); classi.lookupElementExtendedKey = "feature"; lookup.classifier = classi; EcoreAnyStub feature = new EcoreAnyStub(); classi.lookupElementExtended = feature; assertNotNull(lookup.getMultiplicity(ResolutionBeanHelper.refM("package", "testType"), "feature")); } @Test public void testGetFeature() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); assertNull(lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature")); EcoreAnyStub classi = new EcoreAnyStub(); classi.lookupElementExtendedKey = "feature"; lookup.classifier = classi; // still expect null, as we did not set feature in the stub assertNull(lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature")); EcoreAnyStub feature = new EcoreAnyStub(); classi.lookupElementExtended = feature; EcoreAnyStub featureType = new EcoreAnyStub(); featureType.name = "featureType"; feature.type = featureType; assertNotNull(lookup.getFeatureClassReference(ResolutionBeanHelper.refM("package", "testType"), "feature")); } @Test public void testIsClassName() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); assertNull(lookup.resolveReference(list("package", "testType"))); EcoreAnyStub classi = new EcoreAnyStub(); classi.name = "testType"; lookup.classifier = classi; assertNotNull(lookup.resolveReference(list("package", "testType"))); } @Test public void testQualifyName() throws Exception { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); /*** Test with no results **/ List<ResolvedNameAndReferenceBean<EObject>> result = lookup.qualifyName("typeName"); assertEquals(0, result.size()); /*** Test with one results **/ EcoreAnyStub classi = new EcoreAnyStub(); // EcoreAnyStub will add package to qualified Name classi.name = "Test"; lookup.qualifiedClassifiers.add(classi); result = lookup.qualifyName("typeName"); assertEquals(1, result.size()); assertEquals(ResolutionBeanHelper.refM("package", "Test"), result.get(0)); /*** Test with many results **/ classi = new EcoreAnyStub(); // EcoreAnyStub will add package to qualified Name classi.name = "Test2"; lookup.qualifiedClassifiers.add(classi); result = lookup.qualifyName("typeName"); assertEquals(2, result.size()); assertTrue(result.contains(ResolutionBeanHelper.refM("package", "Test"))); assertTrue(result.contains(ResolutionBeanHelper.refM("package", "Test2"))); } @Test public void testGetEnumLiterals() throws MetaModelLookupException { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); EList<EEnumLiteral> literals = new BasicEList<EEnumLiteral>(); List<String> labels = new ArrayList<String>(); EcoreAnyStub literalStub = new EcoreAnyStub(); literalStub.enumLiteralString = "test1"; labels.add(literalStub.enumLiteralString); literals.add(literalStub); literalStub = new EcoreAnyStub(); literalStub.enumLiteralString = "test2"; labels.add(literalStub.enumLiteralString); literals.add(literalStub); EcoreAnyStub enumStub = new EcoreAnyStub(); enumStub.enumLiterals = literals; lookup.classifier = enumStub; List<String> result = lookup.getEnumLiterals(ResolutionBeanHelper.refM("package", "EnumName")); assertEquals(labels, result); } @Test public void testInstanceOfSame() throws MetaModelLookupException { // override getClassifier to return different stuff for sub and supertype TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); final EcoreAnyStub subTypeClass = new EcoreAnyStub(); lookup.classifier = subTypeClass; // test is independent of passed Strings assertTrue(lookup.isSubTypeOf(ResolutionBeanHelper.refM("foo"), ResolutionBeanHelper.refM("bar"))); } @Test public void testInstanceOf() throws MetaModelLookupException { final List<String> subTypeName = list("package", "subtype"); final List<String> superTypeName = list("package", "supertype"); ResolvedNameAndReferenceBean<EObject> superRefBean = new ResolvedNameAndReferenceBean<EObject>(superTypeName, null); ResolvedNameAndReferenceBean<EObject> subRefBean = new ResolvedNameAndReferenceBean<EObject>(subTypeName, null); final EcoreAnyStub subTypeClass = new EcoreAnyStub(); final EcoreAnyStub superTypeClass = new EcoreAnyStub(); EList<EClass> supers = new BasicEList<EClass>(); supers.add(new EcoreAnyStub()); supers.add(superTypeClass); subTypeClass.supertypes = supers; // override getClassifier to return different stuff for sub and supertype TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup() { @Override protected EClassifier findClassifiersByQualifiedName(List<String> typeNameQ) throws MetaModelLookupException { if (typeNameQ.equals(subTypeName)) { return subTypeClass; } else if (typeNameQ.equals(superTypeName)) { return superTypeClass; } else { return null; } } }; assertTrue(lookup.isSubTypeOf(subRefBean, superRefBean)); } /** * This tests the lookup of references through generics used e.g., in the OCL and OCLEcore metamodels * For example, ecore::EnumLiteralExp inherits from EnumLiteralExp<C, LE> binding the generic types * as follows: EnumLiteralExp<EClassifier, EEnumLiteral> which leads to the reference "referredEnumLiteral" * being bound to type EEnumLiteral. This binding has to be resolved by the metalookup. Currently, * {@link AbstractEcoreMetaModelLookup#getEType(EObject, org.eclipse.emf.ecore.EStructuralFeature)} is * responsible for resolving the generic type stuff. * * @throws MetaModelLookupException */ @Test public void testGenericReferenceTypeResolvingParameterizedReference() throws MetaModelLookupException { TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); ResolvedNameAndReferenceBean<EObject> reference = ResolutionBeanHelper.refM( EcorePackage.eINSTANCE.getEnumLiteralExp(), "ocl", "ecore", "EnumLiteralExp"); ResolvedNameAndReferenceBean<EObject> featureClassReference = lookup.getFeatureClassReference(reference, "referredEnumLiteral"); assertEquals(org.eclipse.emf.ecore.EcorePackage.eINSTANCE.getEEnumLiteral(), featureClassReference.getReference()); } // /** // * This tests the lookup of references through generics used e.g., in the OCL and OCLEcore metamodels // * this time for parameterized reference types: // * ecore::VariableExp has a reference referredVariable which is of Type Variable<C, PM>. As // * ecore::VariableExp has a generic supertype VariableExp<EClassifier, EParameter> these parameters // * should also be bound to the type of the referredVariable reference leading to the reference type // * of Variable<EClassifier, EParameter>. This case should also be handled by // * {@link AbstractEcoreMetaModelLookup#getEType(EObject, org.eclipse.emf.ecore.EStructuralFeature)}. // * // * @throws MetaModelLookupException // */ // @Test // public void testGenericReferenceTypeResolvingParameterizedReferenceType() throws MetaModelLookupException { // TestableAbstractEcoreMetaModelLookup lookup = new TestableAbstractEcoreMetaModelLookup(); // ResolvedNameAndReferenceBean<EObject> reference = ResolutionBeanHelper.refM( // EcorePackage.eINSTANCE.getEnumLiteralExp(), "ocl", "ecore", "VariableExp"); // // ResolvedNameAndReferenceBean<EObject> featureClassReference = // lookup.getFeatureClassReference(reference, "referredVariable"); // assertEquals(org.eclipse.emf.ecore.EcorePackage.eINSTANCE.getEEnumLiteral(), // featureClassReference.getReference()); // } private class TestableAbstractEcoreMetaModelLookup extends AbstractEcoreMetaModelLookup { public EList<EClassifier> qualifiedClassifiers = new BasicEList<EClassifier>(); public EClassifier classifier; @Override protected EClassifier findClassifiersByQualifiedName(List<String> typeNameQ) throws MetaModelLookupException { return classifier; } @Override protected EList<EClassifier> findClassifiersByUnqualifiedName(String typeName) throws MetaModelLookupException { return qualifiedClassifiers; } @Override public EList<Diagnostic> validateOclQuery(Template template, String queryToValidate) { return new BasicEList<Diagnostic>(); } @Override public List<ResolvedNameAndReferenceBean<EObject>> getDirectSubTypes(ResolvedNameAndReferenceBean<EObject> typeName) throws MetaModelLookupException, NameResolutionFailedException { fail("Not implemented"); return null; } @Override public List<Diagnostic> validateOclQuery(EObject parsingContext, String oclQuery) { return new BasicEList<Diagnostic>(); } @Override public EObject getOclReturnType(EObject parsingContext, String oclQuery) throws MetaModelLookupException { return new EcoreAnyStub(); } @Override protected OppositeEndFinder getOppositeEndFinder() { return DefaultOppositeEndFinder.getInstance(); } @Override public Set<URI> getMetaModelURIs() { return Collections.emptySet(); } } }