/*
* Copyright (c) 2006, 2010 Borland Software Corporation 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:
* dvorak - initial API and implementation
*/
package org.eclipse.gmf.tests.validate;
import junit.framework.TestCase;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
import org.eclipse.gmf.internal.validate.expressions.EnvironmentProvider;
import org.eclipse.gmf.internal.validate.expressions.ExpressionProviderRegistry;
import org.eclipse.gmf.internal.validate.expressions.IEvaluationEnvironment;
import org.eclipse.gmf.internal.validate.expressions.IModelExpression;
import org.eclipse.gmf.internal.validate.expressions.IModelExpressionProvider;
import org.eclipse.gmf.internal.validate.expressions.IParseEnvironment;
import org.eclipse.gmf.tests.EPath;
import org.eclipse.gmf.tests.Plugin;
import org.eclipse.gmf.tests.setup.LinksSessionSetup;
public class OCLExpressionAdapterTest extends TestCase {
EClassifier context;
IModelExpressionProvider provider;
EPath modelAccess;
public OCLExpressionAdapterTest(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.context = EcorePackage.eINSTANCE.getEClass();
this.provider = ExpressionProviderRegistry.getInstance().getProvider("ocl"); //$NON-NLS-1$
assertNotNull("OCL expression provider must be available", provider); //$NON-NLS-1$
this.modelAccess = EPath.createEcorePathFromModel(Plugin.createURI(LinksSessionSetup.modelURI));
}
public void testEnvVariables() throws Exception {
EClassifier oclIntegerType = provider.createExpression("'aString'", context).getResultType();
EClassifier oclBooleanType = provider.createExpression("true", context).getResultType();
IParseEnvironment env = EnvironmentProvider.createParseEnv();
env.setVariable("intVar", oclIntegerType);
env.setVariable("boolVar", oclBooleanType);
Integer intVal = new Integer(1);
Boolean boolVal = new Boolean(true);
IEvaluationEnvironment evalEnv = EnvironmentProvider.createEvaluationEnv();
evalEnv.setVariable("intVar", intVal);
evalEnv.setVariable("boolVar", boolVal);
EObject contextInstance = EcorePackage.eINSTANCE.getEClass();
assertSame(intVal, provider.createExpression("intVar", context, env).evaluate(contextInstance, evalEnv));
assertSame(boolVal, provider.createExpression("boolVar", context, env).evaluate(contextInstance, evalEnv));
}
public void testAssignReferenceMany() throws Exception {
EReference ref = modelAccess.findReference("//Root/elements"); //$NON-NLS-1$
assertTrue(expression("null.oclAsType(links::Node)").isAssignableToElement(ref)); //$NON-NLS-1$
assertTrue(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//Node"))); //$NON-NLS-1$
assertTrue(expression("null.oclAsType(links::LinkContainer)").isAssignableToElement(ref)); //$NON-NLS-1$
assertTrue(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//LinkContainer"))); //$NON-NLS-1$
assertTrue(expression("Bag { null.oclAsType(links::LinkContainer) }").isAssignableToElement(ref)); //$NON-NLS-1$
assertFalse(expression("null.oclAsType(links::Root)").isAssignableToElement(ref)); //$NON-NLS-1$
assertFalse(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//Root"))); //$NON-NLS-1$
}
public void testAssignReferenceSingle() throws Exception {
EReference ref = modelAccess.findReference("//Link/target"); //$NON-NLS-1$
assertTrue(expression("null.oclAsType(links::Node)").isAssignableToElement(ref)); //$NON-NLS-1$
assertTrue(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//Node"))); //$NON-NLS-1$
assertTrue(expression("null.oclAsType(links::LinkContainer)").isAssignableToElement(ref)); //$NON-NLS-1$
assertTrue(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//LinkContainer"))); //$NON-NLS-1$
assertFalse(expression("null.oclAsType(links::Root)").isAssignableToElement(ref)); //$NON-NLS-1$
assertFalse(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//Root"))); //$NON-NLS-1$
assertFalse(expression("Bag{null.oclAsType(links::Root)}").isAssignableToElement(ref)); //$NON-NLS-1$
assertFalse(ref.getEReferenceType().isSuperTypeOf(modelAccess.findClass("//Root"))); //$NON-NLS-1$
}
/*
* !!! Note: This testcase uses intentionally Type literals in order to cover usage
* of OCL TypeType as meta-types in assignment to ecore metamodel elements.
*/
public void testOCL_TypeType() throws Exception {
EAttribute feature = createAttr(EcorePackage.eINSTANCE.getEClassifier());
assertTrue(expression("links::TestEnum").isAssignableToElement(feature)); //$NON-NLS-1$
assertFalse(expression("links::TestEnum::LIT1").isAssignableToElement(feature)); //$NON-NLS-1$
assertTrue(expression("ecore::EInt").isAssignableToElement(feature)); //$NON-NLS-1$
assertFalse("Collection can't be assigned to scalar", expression("Bag{ecore::EInt}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
feature.setUpperBound(-1); // set isMany = true
assertTrue("Scalar should allowed to intialize feature[0..*]", expression("ecore::EInt").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue(expression("Bag{ecore::EInt, ecore::EInt}").isAssignableToElement(feature)); //$NON-NLS-1$
assertTrue(expression("Bag{links::TestEnum}").isAssignableToElement(feature)); //$NON-NLS-1$
EReference ref = createRef(EcorePackage.eINSTANCE.getEClass());
assertFalse(expression("ecore::EInt").isAssignableToElement(ref)); //$NON-NLS-1$
assertTrue(expression("links::Node").isAssignableToElement(ref)); //$NON-NLS-1$
ref.setUpperBound(-1); // set isMany = true
assertTrue(expression("Bag{links::Node}").isAssignableToElement(ref)); //$NON-NLS-1$
assertFalse(expression("Bag{ecore::EInt}").isAssignableToElement(ref)); //$NON-NLS-1$
}
public void testOCLTypes() throws Exception {
EAttribute feature = createAttr(EcorePackage.eINSTANCE.getEDouble());
assertTrue("Integer should be taken as Real", expression("self->size()").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue(expression("1.5").isAssignableToElement(feature)); //$NON-NLS-1$
assertFalse("Cardinality mismatch", expression("Sequence{10}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
feature.setUpperBound(-1); // set isMany = true
// test many = true for all OCL CollectionTypes
// any CollectionType should be compatible for assignement to a feature [isMany = true]
assertTrue("Bag must be compatible to feature [0..*]", expression("Bag{self->size()/*int*/}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue("Sequence must be compatible to feature [0..*]", expression("Sequence{self->size()/*int*/}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue("Set must be compatible to feature [0..*]", expression("Set{self->size()/*int*/}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue("OrderedSet must be compatible to feature [0..*]", expression("OrderedSet{self->size()/*int*/}").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
// checking mixing different types with common super type
assertTrue("OrderedSet must be compatible to feature [0..*]", expression("Bag{ 10, 5.33 }").isAssignableToElement(feature)); //$NON-NLS-1$ //$NON-NLS-2$
// check Real not conformant to Integer
EAttribute intFeature = createAttr(EcorePackage.eINSTANCE.getEInt());
assertFalse("Real can't be assigned to Integer", expression("1.55").isAssignableToElement(intFeature)); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue(expression("15").isAssignableToElement(intFeature)); //$NON-NLS-1$
}
public void testPrimitivesConversion() throws Exception {
assertTrue(expression("true").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEBoolean()))); //$NON-NLS-1$
assertTrue(expression("true").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEBooleanObject()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEInt()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEIntegerObject()))); //$NON-NLS-1$
// EMFT OCL does not support Byte/byte types
// assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEByte()))); //$NON-NLS-1$
// assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEByteObject()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEShort()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEShortObject()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getELong()))); //$NON-NLS-1$
assertTrue(expression("1").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getELongObject()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEInt()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEIntegerObject()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEShort()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEShortObject()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getELong()))); //$NON-NLS-1$
assertFalse(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getELongObject()))); //$NON-NLS-1$
assertTrue(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEFloat()))); //$NON-NLS-1$
assertTrue(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEFloatObject()))); //$NON-NLS-1$
assertTrue(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEDouble()))); //$NON-NLS-1$
assertTrue(expression("1.5").isAssignableToElement(createAttr(EcorePackage.eINSTANCE.getEDoubleObject()))); //$NON-NLS-1$
}
public void testEnumerationLiteral() throws Exception {
EAttribute attr = modelAccess.findAttribute("//LinkContainer/enumAttr_Init"); //$NON-NLS-1$
assertTrue(expression("links::TestEnum::LIT1").isAssignableToElement(attr)); //$NON-NLS-1$
assertFalse(expression("links::TestEnum").isAssignableToElement(attr)); //$NON-NLS-1$
EAttribute manyEnumsAttr = createAttr(modelAccess.lookup("//TestEnum", EClassifier.class)); //$NON-NLS-1$
manyEnumsAttr.setUpperBound(-1);
assertTrue(expression("Bag{links::TestEnum::LIT0, links::TestEnum::LIT1}").isAssignableToElement(manyEnumsAttr)); //$NON-NLS-1$
assertFalse(expression("Bag{links::TestEnum}").isAssignableToElement(manyEnumsAttr)); //$NON-NLS-1$
}
IModelExpression expression(String body) throws Exception {
EPackage.Registry reg = new EPackageRegistryImpl();
reg.putAll(EPackage.Registry.INSTANCE);
EPackage model = modelAccess.lookup("/", EPackage.class); //$NON-NLS-1$
reg.put(model.getNsURI(), model);
IParseEnvironment env = EnvironmentProvider.createParseEnv();
env.setImportRegistry(reg);
IModelExpression expression = provider.createExpression(body, context, env);
assertTrue("Invalid body: " + expression.getStatus().getMessage(), expression.getStatus().isOK()); //$NON-NLS-1$
return expression;
}
EAttribute createAttr(EClassifier eType) {
assertNotNull("non-null type required ", eType); //$NON-NLS-1$
EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
attribute.setName("myFeature_" + eType.getName()); //$NON-NLS-1$
attribute.setEType(eType);
return attribute;
}
EReference createRef(EClass eType) {
assertNotNull("non-null type required ", eType); //$NON-NLS-1$
EReference ref = EcoreFactory.eINSTANCE.createEReference();
ref.setName("myFeature_" + eType.getName()); //$NON-NLS-1$
ref.setEType(eType);
return ref;
}
}