/*
* Copyright (c) 2007, 2008 Borland Software Corporation
*
* 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
* Artem Tikhomirov (Borland) - [230418] non-containment contexts; refactoring
*/
package org.eclipse.gmf.tests.validate;
import junit.framework.TestCase;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.internal.validate.Annotations;
import org.eclipse.gmf.internal.validate.StatusCodes;
import org.eclipse.gmf.validate.GMFValidator;
public abstract class MetaExpressionDefTestBase extends TestCase {
protected EClass constraintMetaClass;
protected EStructuralFeature languageAttr;
protected EStructuralFeature bodyAttr;
protected EReference constraintRefFeatureCtx;
protected EReference constraintRefWithOCLCtx;
protected EClass containerClass;
protected EStructuralFeature ctxClassRef;
protected EStructuralFeature ctxTypeRef;
protected final String metaDefinitionAnnotationKey;
/**
* @param name
*/
MetaExpressionDefTestBase(String name, String metaDefKey) {
super(name);
metaDefinitionAnnotationKey = metaDefKey;
}
@Override
protected void setUp() throws Exception {
super.setUp();
EPackage model = DynamicModelHelper.createMetaModel();
this.containerClass = DynamicModelHelper.createMetaClass(model);
this.ctxClassRef = DynamicModelHelper.createFeature(containerClass, EcorePackage.eINSTANCE.getEClass());
this.ctxTypeRef = DynamicModelHelper.createFeature(containerClass, EcorePackage.eINSTANCE.getEDataType());
this.constraintMetaClass = DynamicModelHelper.createMetaClass(model);
this.languageAttr = DynamicModelHelper.createFeature(constraintMetaClass, EcorePackage.eINSTANCE.getEString());
this.bodyAttr = DynamicModelHelper.createFeature(constraintMetaClass, EcorePackage.eINSTANCE.getEString());
// create valuespec|constraint meta-definition
EAnnotation eAnnotation = AnnotationUtil.createAnnotation(constraintMetaClass, Annotations.CONSTRAINTS_META_URI);
eAnnotation.getDetails().put(Annotations.Meta.DEF_KEY, metaDefinitionAnnotationKey);
EcoreUtil.setAnnotation(languageAttr, Annotations.CONSTRAINTS_META_URI, Annotations.Meta.DEF_KEY, Annotations.Meta.LANG);
EcoreUtil.setAnnotation(bodyAttr, Annotations.CONSTRAINTS_META_URI, Annotations.Meta.DEF_KEY, Annotations.Meta.BODY);
// create reference Container->Constraint
this.constraintRefFeatureCtx = (EReference)DynamicModelHelper.createFeature(containerClass, constraintMetaClass);
this.constraintRefFeatureCtx.setContainment(true);
AnnotationUtil.addContextDefAnnotation(constraintRefFeatureCtx, ctxClassRef.getName());
this.constraintRefWithOCLCtx = (EReference)DynamicModelHelper.createFeature(containerClass, constraintMetaClass);
this.constraintRefWithOCLCtx.setContainment(true);
AnnotationUtil.addContextDefAnnotation(constraintRefWithOCLCtx, ctxTypeRef.getName());
}
public void testValidOCLConstraint() throws Exception {
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
constraintInstance.eSet(bodyAttr, "eParameters->size() > 0"); //$NON-NLS-1$
bindToNewContextInstance(constraintInstance);
Diagnostic status = GMFValidator.validate(constraintInstance);
assertEquals(Diagnostic.OK, status.getSeverity());
}
public void testNoContextAvailable() throws Exception {
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
constraintInstance.eSet(bodyAttr, "true"); //$NON-NLS-1$
EObject owner = bindToNewContextInstance(constraintInstance);
owner.eUnset(ctxClassRef); // clear context reference
Diagnostic status = GMFValidator.validate(owner);
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.NO_VALUESPEC_CONTEXT_AVAILABLE);
}
public void testInvalidBody() throws Exception {
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
constraintInstance.eSet(bodyAttr, "true..."); //$NON-NLS-1$
bindToNewContextInstance(constraintInstance);
Diagnostic status = GMFValidator.validate(bindToNewContextInstance(constraintInstance));
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.INVALID_CONSTRAINT_EXPRESSION);
}
public void testWrongContextTypeDef() throws Exception {
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
constraintInstance.eSet(bodyAttr, "true"); //$NON-NLS-1$
EObject owner = bindToNewContextInstance(constraintInstance);
ctxClassRef.setEType(containerClass);
Diagnostic status = GMFValidator.validate(owner);
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.NO_VALUESPEC_CONTEXT_AVAILABLE);
}
public void testRegExpLikeConstraint() throws Exception {
_testValidRegExpConstraint(Annotations.REGEXP_KEY);
_testValidRegExpConstraint(Annotations.NEG_REGEXP_KEY);
}
private void _testValidRegExpConstraint(String regexpLang) throws Exception {
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, regexpLang);
constraintInstance.eSet(bodyAttr, "[.]"); //$NON-NLS-1$
// first test EClass as in-proper context for regexp evaluation
EObject owner = bindToNewContextInstance(constraintInstance);
Diagnostic status = GMFValidator.validate(owner);
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.INVALID_CONSTRAINT_EXPRESSION);
// patch context to EString to allow regexp evaluation
EObject containerInstance = EcoreUtil.create(containerClass);
containerInstance.eSet(ctxTypeRef, EcorePackage.eINSTANCE.getEString());
// rebind to String type context
containerInstance.eSet(constraintRefWithOCLCtx, constraintInstance);
status = GMFValidator.validate(containerInstance);
assertEquals(Diagnostic.OK, status.getSeverity());
}
public void testDefinitionInheritance() throws Exception {
// Subclass the Constraint metaclass
EClass intermConstraintSubClass = DynamicModelHelper.createMetaClass(constraintMetaClass.getEPackage());
intermConstraintSubClass.getESuperTypes().add(constraintMetaClass);
EClass finalConstraintSubClass = DynamicModelHelper.createMetaClass(constraintMetaClass.getEPackage());
finalConstraintSubClass.getESuperTypes().add(intermConstraintSubClass);
EObject constraintInstance = EcoreUtil.create(finalConstraintSubClass);
EObject owner = bindToNewContextInstance(constraintInstance);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
constraintInstance.eSet(bodyAttr, "true..."); //$NON-NLS-1$
Diagnostic status = GMFValidator.validate(owner);
// check invalid definition was captured
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.INVALID_CONSTRAINT_EXPRESSION);
// check it's correct now
constraintInstance.eSet(bodyAttr, "true"); //$NON-NLS-1$
status = GMFValidator.validate(owner);
assertEquals(Diagnostic.OK, status.getSeverity());
}
public void testMissingBodyAnnotation() throws Exception {
bodyAttr.getEAnnotations().clear();
EObject constraintInstance = EcoreUtil.create(constraintMetaClass);
constraintInstance.eSet(languageAttr, Annotations.OCL_KEY);
Diagnostic status = GMFValidator.validate(bindToNewContextInstance(constraintInstance));
assertEquals(Diagnostic.ERROR, status.getSeverity());
assertEquals(AnnotationUtil.getChildDiagnostic(status).getCode(), StatusCodes.MISSING_VALUESPEC_BODY_ANNOTATION);
}
protected EObject bindToNewContextInstance(EObject constraintInstance) {
EObject ownerInstance = EcoreUtil.create(containerClass);
ownerInstance.eSet(ctxClassRef, EcorePackage.eINSTANCE.getEOperation());
ownerInstance.eSet(constraintRefFeatureCtx, constraintInstance);
return ownerInstance;
}
}