/**
* Copyright (c) 2012 itemis AG 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:
* itemis AG - initial API and implementation
*
*/
package org.yakindu.sct.model.stext.test.validation;
import static org.eclipse.xtext.junit4.validation.AssertableDiagnostics.errorCode;
import static org.eclipse.xtext.junit4.validation.AssertableDiagnostics.errorMsg;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.yakindu.sct.test.models.AbstractTestModelsUtil.VALIDATION_TESTMODEL_DIR;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.validation.AssertableDiagnostics;
import org.eclipse.xtext.validation.Check;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.yakindu.base.expressions.expressions.Expression;
import org.yakindu.base.types.Operation;
import org.yakindu.sct.model.sgraph.Entry;
import org.yakindu.sct.model.sgraph.Exit;
import org.yakindu.sct.model.sgraph.Scope;
import org.yakindu.sct.model.sgraph.State;
import org.yakindu.sct.model.sgraph.Statechart;
import org.yakindu.sct.model.sgraph.Transition;
import org.yakindu.sct.model.sgraph.Trigger;
import org.yakindu.sct.model.stext.inferrer.STextTypeInferrer;
import org.yakindu.sct.model.stext.stext.InterfaceScope;
import org.yakindu.sct.model.stext.stext.InternalScope;
import org.yakindu.sct.model.stext.stext.ReactionEffect;
import org.yakindu.sct.model.stext.stext.ReactionTrigger;
import org.yakindu.sct.model.stext.stext.StatechartSpecification;
import org.yakindu.sct.model.stext.stext.TransitionSpecification;
import org.yakindu.sct.model.stext.stext.impl.StextFactoryImpl;
import org.yakindu.sct.model.stext.test.util.STextInjectorProvider;
import org.yakindu.sct.model.stext.validation.STextJavaValidator;
import org.yakindu.sct.model.stext.validation.STextValidationMessages;
import org.yakindu.sct.test.models.AbstractTestModelsUtil;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* @author andreas muelder - Initial contribution and API
*
*/
@RunWith(XtextRunner.class)
@InjectWith(STextInjectorProvider.class)
public class STextJavaValidatorTest extends AbstractSTextValidationTest implements STextValidationMessages {
/**
* @see STextJavaValidator#checkVariableDefinition(org.yakindu.sct.model.stext.stext.VariableDefinition)
*/
@Test
public void checkVariableDefinition() {
Scope context = (Scope) parseExpression("interface if : var i : void",
InterfaceScope.class.getSimpleName());
AssertableDiagnostics validationResult = tester.validate(context);
validationResult.assertErrorContains(STextTypeInferrer.VARIABLE_VOID_TYPE);
}
/**b
* @see STextJavaValidator#checkAssignmentExpression(org.yakindu.sct.model.stext.stext.AssignmentExpression)
*/
@Test
public void checkAssignmentExpression() {
String context = "interface: var i : integer = 42 var j : integer =23";
EObject expression = super.parseExpression("i += (i+=3) +4", Expression.class.getSimpleName(), context);
AssertableDiagnostics validationResult = tester.validate(expression);
validationResult.assertErrorContains(STextJavaValidator.ASSIGNMENT_EXPRESSION);
expression = super.parseExpression("i += (j+=3) +4", Expression.class.getSimpleName(), context);
validationResult = tester.validate(expression);
validationResult.assertOK();
}
@Test
public void checkTimeEventSpecValueExpression() {
EObject expression = super.parseExpression("after true s", ReactionTrigger.class.getSimpleName());
AssertableDiagnostics validationResult = tester.validate(expression);
validationResult.assertErrorContains(STextJavaValidator.TIME_EXPRESSION);
}
@Test
public void checkReactionEffectActionExpression() {
// covered by inferrer tests
}
@Test
public void checkLeftHandAssignment() {
String scope =
"interface if : operation myOperation() : boolean event Event1 : boolean var myVar : boolean";
EObject model = super.parseExpression("3 = 3", Expression.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
// Check for referenced elements in interface
model = super.parseExpression("if.myOperation() = true", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
model = super.parseExpression("if.Event1 = true", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
model = super.parseExpression("if.myVar = true", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
// check for internal referenced elements
scope = "internal : operation myOperation() : integer event Event1 : integer var myVar : integer";
model = super.parseExpression("myOperation() = 5", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
model = super.parseExpression("Event1 = true", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertErrorContains(STextJavaValidator.LEFT_HAND_ASSIGNMENT);
model = super.parseExpression("myVar = 5", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
}
/**
* @see STextJavaValidator#checkOperationArguments_FeatureCall(org.yakindu.sct.model.stext.stext.FeatureCall)
*/
@Test
public void checkOperationArguments_FeatureCall() {
String scope = "interface if : operation myOperation(param1 : integer, param2: boolean";
EObject model = super.parseExpression("if.myOperation(5,true)", Expression.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertOK();
}
/**
* @see STextJavaValidator#checkOperationArguments_TypedElementReferenceExpression(TypedElementReferenceExpression)
*/
@Test
public void checkOperationArguments_TypedElementReferenceExpression() {
String scope = "internal: operation myOperation(param1 : integer, param2: boolean)";
EObject model = super.parseExpression("myOperation(5,true)", Expression.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertOK();
}
/**
* @see STextJavaValidator#checkVarArgParameterIsLast(Operation)
*/
@Test
public void checkVarArgParameterIsLast(){
String scope = "internal: operation myOperation(param1... : integer)"
+ "operation myOperation2(param0 : string, param1 ... : integer)";
EObject model = super.parseExpression(scope, InternalScope.class.getSimpleName());
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation()", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation(5)", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation(5,5,5)", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation2('')", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation2('',5)", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation2('',5,5,5)", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("myOperation2('','')", Expression.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertErrorContains("Incompatible types string and integer.");
scope = "internal: operation myOperation(param1... : integer, param2...: integer)";
model = super.parseExpression(scope, InternalScope.class.getSimpleName());
validationResult = tester.validate(model);
validationResult.assertError(STextJavaValidator.VAR_ARGS_LAST_CODE);
scope = "internal: operation myOperation2(param1 ... : integer, param0 : string)";
model = super.parseExpression(scope, InternalScope.class.getSimpleName());
validationResult = tester.validate(model);
validationResult.assertError(STextJavaValidator.VAR_ARGS_LAST_CODE);
}
/**
* @see STextJavaValidator#checkAnnotationArguments(org.yakindu.sct.model.stext.stext.AnnotationDefinition)
*/
@Test
@Ignore("Library Scope is not visible during tests")
public void checkAnnotationArguments() {
String scope = "@Execution()";
EObject model = super.parseExpression(scope, StatechartSpecification.class.getSimpleName());
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertError(STextJavaValidator.WRONG_NUMBER_OF_ARGUMENTS_CODE);;
scope = "@Execution(EVENT_DRIVEN)";
model = super.parseExpression(scope, StatechartSpecification.class.getSimpleName());
validationResult = tester.validate(model);
validationResult.assertOK();
}
/**
* @see STextJavaValidator#checkAnnotationTarget(org.yakindu.base.types.AnnotatableElement)
*/
@Test
public void checkAnnotationTarget(){
//TODO: Implement me when default annotation for target is available
}
/**
* @see STextJavaValidator#checkGuardHasBooleanExpression(org.yakindu.sct.model.stext.stext.ReactionTrigger)
*/
@Test
public void checkGuard() {
EObject expression = super.parseExpression("[3 * 3]", ReactionTrigger.class.getSimpleName());
AssertableDiagnostics validationResult = tester.validate(expression);
validationResult.assertErrorContains(STextJavaValidator.GUARD_EXPRESSION);
String scope = "internal: var myInt : integer var myBool : boolean = true";
expression = super.parseExpression("[myInt <= 5 || !myBool ]", ReactionTrigger.class.getSimpleName(), scope);
validationResult = tester.validate(expression);
validationResult.assertOK();
}
@Test
public void checkNoAssignmentInGuard() {
String scope = "internal: var myInt : integer var myBool : boolean = true";
EObject expression = super.parseExpression("[myBool = false]", ReactionTrigger.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(expression);
validationResult.assertErrorContains(STextJavaValidator.GUARD_CONTAINS_ASSIGNMENT);
expression = super.parseExpression("[myInt = 5]", ReactionTrigger.class.getSimpleName(), scope);
validationResult = tester.validate(expression);
Iterator<Diagnostic> diag = validationResult.getAllDiagnostics().iterator();
while (diag.hasNext()) {
Diagnostic d = diag.next();
if (d.getMessage().equals(GUARD_EXPRESSION)) {
assertEquals(STextJavaValidator.GUARD_EXPRESSION, d.getMessage());
} else {
assertEquals(STextJavaValidator.GUARD_CONTAINS_ASSIGNMENT, d.getMessage());
}
}
}
/**
* @see STextJavaValidator#checkFeatureCall(org.yakindu.sct.model.stext.stext.FeatureCall)
* @see STextJavaValidator#checkFeatureCall(TypedElementReferenceExpression)
*/
@Test
public void checkFeatureCall() {
String scope = "interface if : in event a : integer";
EObject model = super.parseExpression("if.a / raise if.a:1",
TransitionSpecification.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertOK();
}
/**
*
* @see STextJavaValidator#checkReactionTrigger(org.yakindu.sct.model.stext.stext.ReactionTrigger)
*/
@Test
public void checkReactionTrigger() {
// ENTRY, EXIT not allowed in transitions
String scope = "internal : event a : integer var myVar : integer";
EObject model = super.parseExpression("entry / myVar = 5", TransitionSpecification.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertError(ENTRY_EXIT_TRIGGER_NOT_ALLOWED);
model = super.parseExpression("exit / myVar = 5", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertError(ENTRY_EXIT_TRIGGER_NOT_ALLOWED);
model = super.parseExpression("oncycle / myVar = 5", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("always / myVar = 5", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertOK();
}
@Test
public void checkReactionTriggerRegularEvent(){
String scope = "interface : in event e var x : integer var y : integer operation op():integer";
EObject model = super.parseExpression("e", TransitionSpecification.class.getSimpleName(), scope);
AssertableDiagnostics validationResult = tester.validate(model);
validationResult.assertOK();
model = super.parseExpression("x", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertError(TRIGGER_IS_NO_EVENT);
model = super.parseExpression("e, x", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertError(TRIGGER_IS_NO_EVENT);
model = super.parseExpression("op()", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertError(TRIGGER_IS_NO_EVENT);
model = super.parseExpression("x, y", TransitionSpecification.class.getSimpleName(), scope);
validationResult = tester.validate(model);
validationResult.assertAll(errorMsg("Trigger 'x' is no event."), errorMsg("Trigger 'y' is no event."));
}
/**
* @see STextJavaValidator#checkReactionEffectActions(org.yakindu.sct.model.stext.stext.ReactionEffect)
*/
@Test
public void checkReactionEffectActions() {
String s1 = "internal : var a : integer event e operation o () : void";
String s2 = "interface if : var a : integer in event e operation o()";
EObject model = super.parseExpression("a", ReactionEffect.class.getSimpleName(), s1);
AssertableDiagnostics result = tester.validate(model);
result.assertError(FEATURE_CALL_HAS_NO_EFFECT);
model = super.parseExpression("1+3", ReactionEffect.class.getSimpleName(), s1);
result = tester.validate(model);
result.assertError(FEATURE_CALL_HAS_NO_EFFECT);
model = super.parseExpression("valueof(e)", ReactionEffect.class.getSimpleName(), s1);
result = tester.validate(model);
result.assertError(FEATURE_CALL_HAS_NO_EFFECT);
model = super.parseExpression("o()", ReactionEffect.class.getSimpleName(), s1);
result = tester.validate(model);
result.assertOK();
model = super.parseExpression("if.a", ReactionEffect.class.getSimpleName(), s2);
result = tester.validate(model);
result.assertError(FEATURE_CALL_HAS_NO_EFFECT);
model = super.parseExpression("valueof(if.e)", ReactionEffect.class.getSimpleName(), s2);
result = tester.validate(model);
result.assertError(FEATURE_CALL_HAS_NO_EFFECT);
model = super.parseExpression("if.o", ReactionEffect.class.getSimpleName(), s2);
result = tester.validate(model);
result.assertOK();
}
/**
* @see STextJavaValidator#checkEventDefinition(org.yakindu.sct.model.stext.stext.EventDefinition)
*/
@Test
public void checkEventDefinition() {
// No local declarations in interface scope
EObject model = super.parseExpression("interface MyInterface: event Event1",
InterfaceScope.class.getSimpleName());
AssertableDiagnostics result = tester.validate(model);
result.assertErrorContains(LOCAL_DECLARATIONS);
// No in declarations in internal scope
model = super.parseExpression("internal: in event Event1", InternalScope.class.getSimpleName());
result = tester.validate(model);
result.assertDiagnosticsCount(1);
result.assertErrorContains(STextJavaValidator.IN_OUT_DECLARATIONS);
// No out declarations in internal scope
model = super.parseExpression("internal: out event Event1", InternalScope.class.getSimpleName());
result = tester.validate(model);
result.assertDiagnosticsCount(1);
result.assertErrorContains(IN_OUT_DECLARATIONS);
}
/**
* @see STextJavaValidator#checkInterfaceScope(Statechart)
*/
@Test
public void checkInterfaceScope() {
EObject model = super.parseExpression("interface: in event event1 interface: in event event2",
StatechartSpecification.class.getSimpleName());
AssertableDiagnostics result = tester.validate(model);
result.assertDiagnosticsCount(2);
result.assertAll(errorCode(ONLY_ONE_INTERFACE), errorCode(ONLY_ONE_INTERFACE));
}
/**
* @see STextJavaValidator#checkChoiceWithoutDefaultTransition(org.yakindu.sct.model.sgraph.Choice)
*/
@Test
public void checkChoiceWithoutDefaultTransition() {
// TODO
}
/**
* @see STextJavaValidator#checkUnresolvableProxies(Statechart)
*/
@Test
public void checkUnresolvableProxies() {
// Nothing to do
}
/**
* @see STextJavaValidator#checkcheckSyntaxErrors(Statechart)
*/
@Test
public void checkSyntaxErrors() {
// Nothing to do
}
@Test
public void checkExpression() {
// Nothing to do
}
@Test
public void checkContextElement(){
//Nothing to do -> this is covered by ContextPredicateProviderTest
}
@Test
public void checkValueOfNoEvent(){
String decl = "interface: in event e1:integer var x:integer operation op():integer interface i: in event e2:integer var y:integer";
EObject model = super.parseExpression("valueof(e1)", Expression.class.getSimpleName(), decl);
AssertableDiagnostics result = tester.validate(model);
result.assertOK();
model = super.parseExpression("valueof(i.e2)", Expression.class.getSimpleName(), decl);
result = tester.validate(model);
result.assertOK();
model = super.parseExpression("valueof(x)", Expression.class.getSimpleName(), decl);
result = tester.validate(model);
result.assertError(VALUE_OF_REQUIRES_EVENT);
model = super.parseExpression("valueof(i.y)", Expression.class.getSimpleName(), decl);
result = tester.validate(model);
result.assertError(VALUE_OF_REQUIRES_EVENT);
model = super.parseExpression("valueof(op())", Expression.class.getSimpleName(), decl);
result = tester.validate(model);
result.assertError(VALUE_OF_REQUIRES_EVENT);
}
/**
* checks tht each @Check method of {@link STextJavaValidator} has a @Test
* method in this class with the same name
*/
@Test
public void testAllChecksHaveTests() throws Exception {
Iterable<Method> methods = Lists.newArrayList(STextJavaValidator.class.getDeclaredMethods());
methods = Iterables.filter(methods, new Predicate<Method>() {
public boolean apply(Method input) {
return input.getAnnotation(Check.class) != null;
}
});
for (Method checkMethod : methods) {
Method testMethod = getClass().getMethod(checkMethod.getName());
assertNotNull("Missing @Test Annotation for method " + checkMethod.getName(),
testMethod.getAnnotation(Test.class));
}
}
@Test
public void checkUnusedEntry() {
statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedEntryPoint.sct");
Iterator<EObject> iter = statechart.eAllContents();
while (iter.hasNext()) {
EObject element = iter.next();
if (element instanceof Entry) {
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
}
assertIssueCount(diagnostics, 1);
assertWarning(diagnostics, ENTRY_UNUSED);
}
@Test
public void checkTopLeveEntryIsDefaultEntry() {
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TopLevelEntryIsDefaultEntryError.sct");
doValidateAllContents(Entry.class);
assertIssueCount(diagnostics, 1);
assertError(diagnostics, TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY);
resetDiagnostics();
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TopLevelEntryIsDefaultEntryWarn.sct");
doValidateAllContents(Entry.class);
assertIssueCount(diagnostics, 1);
assertWarning(diagnostics, TOP_LEVEL_REGION_ENTRY_HAVE_TO_BE_A_DEFAULT_ENTRY);
}
@Test
public void checkUnusedExit() {
statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedExitPoint.sct");
doValidateAllContents(Exit.class);
assertIssueCount(diagnostics, 1);
assertError(diagnostics, EXIT_UNUSED);
resetDiagnostics();
statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedDefaultExitPoint.sct");
doValidateAllContents(Exit.class);
assertIssueCount(diagnostics, 1);
assertError(diagnostics, EXIT_DEFAULT_UNUSED);
}
protected void doValidateAllContents(Class<? extends EObject> clazz) {
Iterator<EObject> iter = statechart.eAllContents();
while (iter.hasNext()) {
EObject element = iter.next();
if (clazz.isInstance(element)) {
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
}
}
protected void assertAllTransitionsAreValid(Class<? extends EObject> clazz) {
Iterator<EObject> iter;
iter = statechart.eAllContents();
while (iter.hasNext()) {
EObject element = iter.next();
if (clazz.isInstance(element)) {
assertTrue(validator.validate(element, diagnostics, new HashMap<Object, Object>()));
}
}
}
@Test
public void checkTransitionPropertySpec() {
// Test source state isn't composite
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TransitionEntrySpecNotComposite.sct");
doValidateAllContents(Transition.class);
// Test target state isn't composite
assertIssueCount(diagnostics, 2);
assertWarning(diagnostics, TRANSITION_ENTRY_SPEC_NOT_COMPOSITE);
resetDiagnostics();
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TransitionExitSpecNotComposite.sct");
assertAllTransitionsAreValid(Transition.class);
assertIssueCount(diagnostics, 1);
assertWarning(diagnostics, TRANSITION_EXIT_SPEC_NOT_COMPOSITE);
// Test exit spec is used on multiple transition siblings.
resetDiagnostics();
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TransitionExitSpecOnMultipleSiblings.sct");
assertAllTransitionsAreValid(Transition.class);
assertIssueCount(diagnostics, 4);
assertWarning(diagnostics, TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS);
// Test transition unbound named exit point spec.
resetDiagnostics();
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "TransitionNotExistingNamedExitPoint.sct");
doValidateAllContents(Transition.class);
assertIssueCount(diagnostics, 1);
assertError(diagnostics, TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT);
}
@Test
public void checkUnboundEntryPoints() {
statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnboundDefaultEntryPoints.sct");
Iterator<EObject> iter = statechart.eAllContents();
// create and add triggers to all transitions to prevent to trigger
// additional warnings
// (see Check in SGrapJavaValidator transitionsWithNoGuard)
Trigger trigger = StextFactoryImpl.init().createDefaultTrigger();
while (iter.hasNext()) {
EObject element = iter.next();
if (element instanceof Transition) {
((Transition) element).setTrigger(trigger);
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
if (element instanceof State) {
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
}
assertIssueCount(diagnostics, 4);
assertError(diagnostics, TRANSITION_UNBOUND_DEFAULT_ENTRY_POINT);
assertError(diagnostics, REGION_UNBOUND_DEFAULT_ENTRY_POINT);
resetDiagnostics();
statechart = AbstractTestModelsUtil.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnboundEntryPoints02.sct");
iter = statechart.eAllContents();
while (iter.hasNext()) {
EObject element = iter.next();
if (element instanceof Transition) {
((Transition) element).setTrigger(trigger);
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
if (element instanceof State) {
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
}
assertIssueCount(diagnostics, 4);
}
@Test
public void checkExitPointSpecWithTrigger() {
statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "NoTriggerOnTransitionWithExitPointSpec.sct");
Iterator<EObject> iter = statechart.eAllContents();
while (iter.hasNext()) {
EObject element = iter.next();
if (element instanceof Transition) {
validator.validate(element, diagnostics, new HashMap<Object, Object>());
}
}
assertIssueCount(diagnostics, 2);
assertError(diagnostics, EXITPOINTSPEC_WITH_TRIGGER);
}
@Test
public void checkAssignmentToFinalVariable() {
Statechart statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "AssignmentToValue.sct");
Diagnostic diagnostics = Diagnostician.INSTANCE.validate(statechart);
assertIssueCount(diagnostics, 2);
assertError(diagnostics, ASSIGNMENT_TO_VALUE);
}
@Test
public void checkValueDefinitionExpression() {
Statechart statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "ConstWithVariable.sct");
Diagnostic diagnostics = Diagnostician.INSTANCE.validate(statechart);
assertIssueCount(diagnostics, 3); //
assertError(diagnostics, REFERENCE_TO_VARIABLE);
assertError(diagnostics, CONST_MUST_HAVE_VALUE_MSG);
}
@Test
public void checkValueReferenedBeforeDefined() {
Statechart statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "ReferenceBeforeDefined.sct");
Diagnostic diagnostics = Diagnostician.INSTANCE.validate(statechart);
assertIssueCount(diagnostics, 2);
assertError(diagnostics, REFERENCE_CONSTANT_BEFORE_DEFINED);
}
@Test
public void checkUnusedVariablesInInternalScope() {
Statechart statechart = AbstractTestModelsUtil
.loadStatechart(VALIDATION_TESTMODEL_DIR + "UnusedInternalDeclarations.sct");
Diagnostic diagnostics = Diagnostician.INSTANCE.validate(statechart);
assertIssueCount(diagnostics, 3);
assertWarning(diagnostics, INTERNAL_DECLARATION_UNUSED);
}
@Test
public void transitionsWithNoTrigger() {
}
}