/*******************************************************************************
 * 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());
		}
	}
}
