blob: bd8e6c93e44a7c9b3a3fb342a49f4f8d447412a9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.uml.tests;
import java.util.Collections;
import java.util.Iterator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.PropertyCallExp;
import org.eclipse.ocl.expressions.TypeExp;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Property;
/**
* Tests support for operation constraints (pre/post/body).
*
* @author Christian W. Damus (cdamus)
*/
@SuppressWarnings("nls")
public class InvariantConstraintsTest extends AbstractTestSuite {
/**
* Tests a very simple invariant, with a package and classifier context
* not using any "self" variable.
*/
public void test_simpleInvariant() {
parseConstraint(
"package ocltest context Fruit " +
"inv: color <> Color::black " +
"endpackage");
}
/**
* Tests a very simple invariant, with a package and classifier context
* using the "self" variable.
*/
public void test_simpleInvariantWithSelf() {
parseConstraint(
"package ocltest context Fruit " +
"inv: self.color <> Color::black " +
"endpackage");
}
/**
* Test a let expression.
*/
public void test_simpleInvariantWithLet() {
parseConstraint(
"package ocltest context Fruit " +
"inv: let myColor : Color = self.color in myColor <> Color::black " +
"endpackage");
}
/**
* Tests that local variables correctly hide attributes of the context
* classifier.
*/
public void test_variablesHidingAttributes() {
parseConstraint(
"package ocltest context Fruit " +
"inv: let color : Boolean = (not self.color.oclIsUndefined()) in " +
" color implies self.color <> Color::black " +
"endpackage");
}
/**
* Tests that when a property name coincides with a type name, we correctly
* distinguish references to the type from references to the property.
*/
public void test_propertyNameCoincidesWithTypeName_140347() {
expectModified = true;
Property myFruit = apple.createOwnedAttribute(
"Fruit", fruit);
try {
OCLExpression<Classifier> expr = parseConstraint(
"package ocltest context Apple " +
"inv: self.Fruit <> self implies self.Fruit.oclIsKindOf(Fruit) " +
"endpackage");
int propertyCalls = 0;
int typeCalls = 0;
for (Iterator<?> iter = EcoreUtil.getAllContents(Collections.singleton(expr)); iter.hasNext();) {
Object next = iter.next();
if (next instanceof PropertyCallExp<?, ?>) {
@SuppressWarnings("unchecked")
PropertyCallExp<Classifier, Property> pc =
(PropertyCallExp<Classifier, Property>) next;
if ("Fruit".equals(pc.getReferredProperty().getName())) {
propertyCalls++;
}
} else if (next instanceof TypeExp<?>) {
@SuppressWarnings("unchecked")
TypeExp<Classifier> te = (TypeExp<Classifier>) next;
if ("Fruit".equals(te.getReferredType().getName())) {
typeCalls++;
}
}
}
assertEquals("property calls", 2, propertyCalls);
assertEquals("type calls", 1, typeCalls);
} finally {
apple.getOwnedAttributes().remove(myFruit);
}
}
/**
* Tests that type conformance accounts for interface realizations.
*/
public void test_interfaceRealization() {
// this constraint tests the Environment.getRelationship() method
// for conformance of classifiers with implemented interfaces.
// Note that it is necessary to cast in order to
// access features of the interface because they are not inherited
// in UML
parseConstraint(
"package ocltest context Fruit " +
"inv only_tasty_fruit: self.oclAsType(Edible).isTasty implies " +
" Edible.allInstances()->excluding(self)->forAll(e | not e.isTasty) " +
"endpackage");
}
/**
* Tests resolution of qualified classifier names for nested classifiers.
*/
public void test_nestedClassifiers() {
expectModified = true;
Class seed = (Class) apple.createNestedClassifier("Seed", uml.getClass_());
seed.createOwnedAttribute("fruit", apple);
try {
// try different usages of the qualified class name
parseConstraint(
"package ocltest context Fruit" +
" inv: Apple::Seed.allInstances()->forAll(fruit.color <> Color::black)" +
" endpackage");
parseConstraint(
"package ocltest context Apple::Seed" +
" inv: not fruit.oclIsUndefined()" +
" endpackage");
parseConstraint(
"context ocltest::Apple::Seed" +
" inv: fruit.color <> Color::black");
parseDef(
"package ocltest context Apple::Seed" +
" def: getColor() : Color = fruit.color" +
" endpackage");
parseConstraint(
"package ocltest context Apple::Seed::getColor() : Color" +
" pre: not fruit.oclIsUndefined()" +
" endpackage");
} finally {
seed.destroy();
}
}
}