blob: 919272aed2a006a309b45cb6319a887846e240d7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2009 IBM 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:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.uml.tests;
import java.util.List;
import org.eclipse.ocl.helper.Choice;
import org.eclipse.ocl.helper.ChoiceKind;
import org.eclipse.ocl.helper.ConstraintKind;
/**
* Tests for message expressions.
*
* @author Christian W. Damus (cdamus)
*/
@SuppressWarnings("nls")
public class MessagesTest
extends AbstractTestSuite {
/**
* Tests the parsing of the hasSent ("^") expression for operations.
*/
public void test_hasSent_operation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// test query operation calls without any arguments
helper.createPostcondition("self^preferredColor()");
// test non-query operation calls without any arguments
helper.createPostcondition("self ^ newFruit()");
// test operation calls with one argument. Incidentally put a more
// interesting expression as the target
helper.createPostcondition(
"Apple.allInstances()->any(true) ^ripen(Color::yellow)");
// test operation calls with multiple arguments
helper.createPostcondition(
"Fruit.allInstances()->forAll(f | self^setColor(f, Color::red))");
// test operation signature conformance matching
helper.createPostcondition(
"Apple.allInstances()->forAll(a | self^setColor(a, Color::red))");
// test operation signature conformance matching with null object type
helper.createPostcondition(
"Apple.allInstances()->forAll(a | self^setColor(null, Color::red))");
// test operation signature conformance matching with null data type
helper.createPostcondition(
"Apple.allInstances()->forAll(a | self^setColor(a, null))");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the validation of the hasSent ("^") expression for operations.
*/
public void test_hasSent_operation_validation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// non-existent operation
helper.createPostcondition("self^label('foo')");
fail("Should have failed to parse unknown operation");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
try {
// non-conformant argument
helper.createPostcondition("self^setColor(self, 'red')");
fail("Should have failed to parse non-conformant arg");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests parsing of the hasSent ("^") expression with unspecified value
* expressions for operations.
*/
public void test_hasSent_operation_unspecifiedValue() {
helper.setOperationContext(fruit, fruit_ripen);
try {
helper.createPostcondition(
"Apple.allInstances()->any(true)^ripen(? : Color)");
helper.createPostcondition(
"Fruit.allInstances()->forAll(f | self^setColor(? : Fruit, ? : Color))");
helper.createPostcondition(
"Apple.allInstances()->any(true)^ripen(?)");
helper.createPostcondition(
"Fruit.allInstances()->forAll(f | self^setColor(?, ?))");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests validation of the hasSent ("^") expression with unspecified value
* expressions for operations.
*/
public void test_hasSent_operation_unspecifiedValue_validation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// non-existent operation
helper.createPostcondition("self^label(?)");
fail("Should have failed to parse unknown operation");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
try {
// non-conformant argument
helper.createPostcondition("self^setColor(self, ? : String)");
fail("Should have failed to parse non-conformant arg");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests the parsing of the sentMessages ("^^") expression for operations.
*/
public void test_sentMessages_operation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// test query operation calls without any arguments
helper.createPostcondition(
"self^^preferredColor()->notEmpty()");
// test non-query operation calls without any arguments
helper.createPostcondition("self^^newFruit()->first().oclIsKindOf(OclMessage)");
// test operation calls with one argument. Incidentally put a more
// interesting expression as the target
helper.createPostcondition(
"Apple.allInstances()->any(true)^^ripen(Color::yellow)->notEmpty()");
// test operation calls with multiple arguments
helper.createPostcondition(
"Fruit.allInstances()->collect(f | self^^setColor(f, Color::red))->notEmpty()");
// test operation signature conformance matching
helper.createPostcondition(
"Apple.allInstances()->collect(a | self^^setColor(a, Color::red))->notEmpty()");
// test operation signature conformance matching with null object type
helper.createPostcondition(
"Apple.allInstances()->collect(a | self^^setColor(null, Color::red))->notEmpty()");
// test operation signature conformance matching with null data type
helper.createPostcondition(
"Apple.allInstances()->collect(a | self^^setColor(a, null))->notEmpty()");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the parsing of OclMessage expressions for operations.
*/
public void test_message_access_operation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// test type conformance
helper.createPostcondition(
"let msgs : Sequence(OclMessage) = self^^preferredColor() in " +
"msgs->forAll(m | m.hasReturned() and m.isOperationCall() and not m.isSignalSent())");
// test non-query operation calls without any arguments
helper.createPostcondition("self^^newFruit()->first().oclIsKindOf(OclMessage)");
// test operation calls with one argument. Incidentally put a more
// interesting expression as the target
helper.createPostcondition(
"Apple.allInstances()->any(true)^^ripen(Color::yellow)->notEmpty()");
// types of the OclMessage properties are determined by the actual
// operation type, not by the MessageExp arguments
helper.createPostcondition(
"let msgs : Collection(OclMessage) = Fruit.allInstances()->collect(f | self^^setColor(?, ?)) in " +
"msgs->forAll(m | m.fruit.color = Color::black implies m.newColor = Color::black)");
// return values
helper.createPostcondition(
"let msgs : Collection(OclMessage) = Fruit.allInstances()->collect(f | self^^newFruit()) in " +
"msgs->forAll(m | m.hasReturned() implies m.result().color = Color::green)");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the validation of the setMessages ("^^") expression for operations.
*/
public void test_sentMessages_operation_validation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// non-existent operation
helper.createPostcondition("self^^label('foo')->notEmpty()");
fail("Should have failed to parse unknown operation");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
try {
// non-conformant argument
helper.createPostcondition("self^^setColor(self, 'red')->notEmpty()");
fail("Should have failed to parse non-conformant arg");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests the parsing of the hasSent ("^") expression for signals.
*/
public void test_hasSent_signal() {
helper.setOperationContext(apple, fruit_ripen);
try {
helper.createPostcondition("self^Drop(3, self.stem)");
helper.createPostcondition("self ^ Drop(? : Real, ? : Stem)");
helper.createPostcondition("self ^Drop(? : Integer, ?)");
helper.createPostcondition("self^Drop(?, ?)");
helper.createPostcondition(
"Apple.allInstances()->any(true)^Drop(3, stem)");
helper.createPostcondition(
"Apple.allInstances()->exists(a | a^Drop(3, stem))");
helper.createPostcondition(
"Fruit.allInstances()->forAll(f | f^Drop(?, ?) implies self^Drop(?, ?))");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the validation of the hasSent ("^") expression for signals.
*/
public void test_hasSent_signal_validation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// non-existent signal
helper.createPostcondition("self^Rot(3, stem)");
fail("Should have failed to parse unknown signal");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
try {
// non-conformant argument
helper.createPostcondition("self^Drop('red', ?)");
fail("Should have failed to parse non-conformant arg");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests the parsing of the sentMessages ("^^") expression for signals.
*/
public void test_sentMessages_signal() {
helper.setOperationContext(fruit, fruit_ripen);
try {
helper.createPostcondition(
"self^^Drop(3, self.oclAsType(Apple).stem)->notEmpty()");
helper.createPostcondition("self^^Drop(?, ?)->first().oclIsKindOf(OclMessage)");
helper.createPostcondition(
"Apple.allInstances()->any(true)^^Drop(3, ?)->notEmpty()");
helper.createPostcondition(
"Apple.allInstances()->collect(a | self^^Drop(null, ? : Stem))->notEmpty()");
helper.createPostcondition(
"Apple.allInstances()->collect(a | self^^Drop(3, null))->notEmpty()");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the parsing of OclMessage expressions for signals.
*/
public void test_message_access_signal() {
helper.setOperationContext(apple, fruit_ripen);
try {
helper.createPostcondition(
"let msgs : Sequence(OclMessage) = self^^Drop(?, ?) in " +
"msgs->forAll(m | m.isSignalSent() and not m.isOperationCall())");
helper.createPostcondition("self^^Drop(?, ?)->first().oclIsKindOf(OclMessage)");
helper.createPostcondition(
"let msgs : Collection(OclMessage) = Fruit.allInstances()->collect(f | self^^Drop(?, ?)) in " +
"msgs->forAll(m | m.delay > 0 and stem <> self.stem)");
} catch (Exception e) {
fail("Failed to parse: " + e.getLocalizedMessage());
}
}
/**
* Tests the validation of the setMessages ("^^") expression for signals.
*/
public void test_sentMessages_signal_validation() {
helper.setOperationContext(fruit, fruit_ripen);
try {
// non-existent signal
helper.createPostcondition("self^^Rot('now')->notEmpty()");
fail("Should have failed to parse unknown signal");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
try {
// non-conformant argument
helper.createPostcondition("self^^Drop(self, ?)->notEmpty()");
fail("Should have failed to parse non-conformant arg");
} catch (Exception e) {
// success
System.out.println("Got expected error: " + e.getLocalizedMessage());
}
}
/**
* Tests the presentation of operation call choices.
*/
public void test_contentAssist_operations() {
helper.setOperationContext(fruit, fruit_ripen);
try {
List<Choice> choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"self^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.OPERATION, "newFruit");
assertChoice(choices, ChoiceKind.OPERATION, "setColor");
assertNotChoice(choices, ChoiceKind.OPERATION, "oclIsKindOf");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION, "self^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.OPERATION, "newFruit");
assertChoice(choices, ChoiceKind.OPERATION, "setColor");
assertNotChoice(choices, ChoiceKind.OPERATION, "oclIsKindOf");
// doesn't parse
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION, "self^^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.VARIABLE, "color");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"Apple.allInstances()->any(true)^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.OPERATION, "newFruit");
assertChoice(choices, ChoiceKind.OPERATION, "setColor");
assertChoice(choices, ChoiceKind.OPERATION, "label");
assertNotChoice(choices, ChoiceKind.OPERATION, "oclIsKindOf");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"Apple.allInstances()->collect(a : Apple | a^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.OPERATION, "newFruit");
assertChoice(choices, ChoiceKind.OPERATION, "setColor");
assertChoice(choices, ChoiceKind.OPERATION, "label");
assertNotChoice(choices, ChoiceKind.OPERATION, "oclIsKindOf");
} catch (Exception e) {
fail("Parse failed: " + e.getLocalizedMessage());
}
}
/**
* Tests the presentation of signal send choices.
*/
public void test_contentAssist_signals() {
helper.setOperationContext(fruit, fruit_ripen);
try {
List<Choice> choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"self^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.SIGNAL, "Drop");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION, "self^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.SIGNAL, "Drop");
// doesn't parse
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION, "self^^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.VARIABLE, "color");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"Apple.allInstances()->any(true)^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.SIGNAL, "Drop");
choices = helper.getSyntaxHelp(
ConstraintKind.POSTCONDITION,
"Apple.allInstances()->collect(a : Apple | a^^");
assertNotNull(choices);
assertChoice(choices, ChoiceKind.SIGNAL, "Drop");
} catch (Exception e) {
fail("Parse failed: " + e.getLocalizedMessage());
}
}
}