|
@@ -0,0 +1,237 @@
|
|
|
+/**
|
|
|
+ * Copyright (c) 2015 committers of YAKINDU 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:
|
|
|
+ * committers of YAKINDU - initial API and implementation
|
|
|
+ *
|
|
|
+*/
|
|
|
+package org.yakindu.sct.model.stext.test;
|
|
|
+
|
|
|
+import static org.junit.Assert.fail;
|
|
|
+
|
|
|
+import java.util.Arrays;
|
|
|
+
|
|
|
+import org.junit.Test;
|
|
|
+import org.junit.runner.RunWith;
|
|
|
+import org.junit.runners.Parameterized;
|
|
|
+import org.junit.runners.Parameterized.Parameters;
|
|
|
+import org.yakindu.base.expressions.expressions.Expression;
|
|
|
+import org.yakindu.sct.model.stext.expressions.STextExpressionParser.LinkingException;
|
|
|
+import org.yakindu.sct.model.stext.scoping.ContextPredicateProvider;
|
|
|
+import org.yakindu.sct.model.stext.stext.LocalReaction;
|
|
|
+import org.yakindu.sct.model.stext.stext.ReactionEffect;
|
|
|
+import org.yakindu.sct.model.stext.stext.ReactionTrigger;
|
|
|
+import org.yakindu.sct.model.stext.stext.VariableDefinition;
|
|
|
+import org.yakindu.sct.model.stext.test.util.AbstractSTextTest;
|
|
|
+import org.yakindu.sct.model.stext.test.util.STextInjectorProvider;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author andreas muelder - Initial contribution and API
|
|
|
+ * @author Johannes Dicks - Add tests covering {@link ContextPredicateProvider}
|
|
|
+ */
|
|
|
+@RunWith(Parameterized.class)
|
|
|
+public class STextScopeProviderTest extends AbstractSTextTest {
|
|
|
+
|
|
|
+ public static final String INTERNAL_SCOPE = "" + //
|
|
|
+ "internal: " + //
|
|
|
+ " in event e1 : void" + //
|
|
|
+ " in event e2 : void" + //
|
|
|
+ " var myInt : integer" + //
|
|
|
+ " var myBool : boolean" + //
|
|
|
+ " operation myOpp(param1 : integer) : void" + //
|
|
|
+ " operation myOpp3() : integer" + //
|
|
|
+ " operation myOpp4() : boolean" + //
|
|
|
+ " operation myOpp5() : integer";
|
|
|
+
|
|
|
+ public static final String INTERFACE_SCOPE = "" + //
|
|
|
+ "interface Interface1:" + //
|
|
|
+ " in event e3 : void" + //
|
|
|
+ " in event e4 : void" + //
|
|
|
+ " var myInt2 : integer" + //
|
|
|
+ " var myBool2 : boolean" + //
|
|
|
+ " operation myOpp2(param1 : integer) : void";
|
|
|
+
|
|
|
+ public static final String INTERFACE_SCOPE_AND_INTERNAL_SCOPE = INTERNAL_SCOPE + "\n" + INTERFACE_SCOPE;
|
|
|
+
|
|
|
+ private String statement;
|
|
|
+ private String ruleName;
|
|
|
+ private String scopes;
|
|
|
+ private boolean isLinkable;
|
|
|
+
|
|
|
+ public STextScopeProviderTest(String statement, String ruleName, String scopes, Boolean isLinkable) {
|
|
|
+ this.statement = statement;
|
|
|
+ this.ruleName = ruleName;
|
|
|
+ this.scopes = scopes;
|
|
|
+ this.isLinkable = isLinkable;
|
|
|
+
|
|
|
+ STextInjectorProvider provider = new STextInjectorProvider();
|
|
|
+ provider.getInjector().injectMembers(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void test() {
|
|
|
+ try {
|
|
|
+ parseExpression(statement, ruleName, scopes);
|
|
|
+ if (!isLinkable)
|
|
|
+ fail(String.format(
|
|
|
+ "Expected not to be linkable [parse '%s' in rule '%s' for scope '%s' expected linkable = '%s']",
|
|
|
+ statement, ruleName, scopes, isLinkable));
|
|
|
+ } catch (LinkingException e) {
|
|
|
+ if (isLinkable)
|
|
|
+ throw new RuntimeException("Expected linkable but : "+e.getMessage(),e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @see {@link ContextPredicateProvider#filter}
|
|
|
+ */
|
|
|
+ @Parameters(name = "{index}: parse {0} in rule {1} expected linkable = {3}")
|
|
|
+ public static Iterable<Object[]> data1() {
|
|
|
+ return Arrays
|
|
|
+ .asList(new Object[][]{//
|
|
|
+ /* testGuardScopingSuccess */
|
|
|
+ {"[e1]", ReactionTrigger.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"[Interface1.e3]", ReactionTrigger.class.getSimpleName(), INTERFACE_SCOPE, true}, //
|
|
|
+ {"[e1 && e2]", ReactionTrigger.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"[e1 && Interface1.e3]", ReactionTrigger.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"[Interface1.e4 && Interface1.e3]", ReactionTrigger.class.getSimpleName(), INTERFACE_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(ASSIGNMENT_EXPRESSION),
|
|
|
+ * VARIABLES_OPERATIONS_EVENTS_ENUMERATORS)
|
|
|
+ */
|
|
|
+ {"myInt = 0", ReactionEffect.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt = Interface1.myInt2", ReactionEffect.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt = myOpp3()", ReactionEffect.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myBool = e1", ReactionEffect.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(CONDITIONAL_EXPRESSION),
|
|
|
+ * VARIABLES_AND_OPERATIONS)
|
|
|
+ */
|
|
|
+ {"myBool ? myOpp(1) : myOpp(2)", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp4() ? myInt : myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myBool ? e1 : myOpp(2)", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(LOGICAL_OR_EXPRESSION),
|
|
|
+ * VARIABLES_OPERATIONS_EVENTS_ENUMERATORS)
|
|
|
+ */
|
|
|
+ {"myInt || Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt || myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt || e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(LOGICAL_AND_EXPRESSION),
|
|
|
+ * VARIABLES_OPERATIONS_EVENTS_ENUMERATORS)
|
|
|
+ */
|
|
|
+ {"myInt && Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt && myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt && e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(BITWISE_XOR_EXPRESSION), VARIABLES)
|
|
|
+ */
|
|
|
+ {"myInt ^ Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 ^ e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myOpp1(1) ^ myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(BITWISE_OR_EXPRESSION), VARIABLES)
|
|
|
+ */
|
|
|
+ {"myInt | Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 | e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myOpp1(1) | myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(BITWISE_AND_EXPRESSION), VARIABLES)
|
|
|
+ */
|
|
|
+ {"myInt & Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 & e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myOpp1(1) & myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(SHIFT_EXPRESSION), VARIABLES)
|
|
|
+ */
|
|
|
+ {"myInt << Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt >> Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 >> e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"e1 >> e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myOpp1(1) >> myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myOpp1(1) << myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(LOGICAL_NOT_EXPRESSION),
|
|
|
+ * VARIABLES_OPERATIONS_EVENTS_ENUMERATORS)
|
|
|
+ */
|
|
|
+ {"!Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"!myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"!e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(LOGICAL_RELATION_EXPRESSION),
|
|
|
+ * VARIABLES_OPERATIONS_EVENTS_ENUMERATORS)
|
|
|
+ */
|
|
|
+ {"myInt < Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt < myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt < e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt > Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt > myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt > e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt <= Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt <= myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt <= e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt >= Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt >= myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt >= e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt == Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt == myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt == e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt != Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt != myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt != e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(NUMERICAL_ADD_SUBTRACT_EXPRESSION),
|
|
|
+ * VARIABLES_AND_OPERATIONS)
|
|
|
+ */
|
|
|
+ {"myInt + Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt - Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp3() + myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt - myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp3() + myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp3() - myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 + e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"e1 - e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(NUMERICAL_MULTIPLY_DIVIDE_EXPRESSION),
|
|
|
+ * VARIABLES_AND_OPERATIONS)
|
|
|
+ */
|
|
|
+ {"myInt * Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt / Interface1.myInt2", Expression.class.getSimpleName(), INTERFACE_SCOPE_AND_INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp3() * myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myInt / myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp3() * myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"e1 * e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"e1 / e2", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(NUMERICAL_UNARY_EXPRESSION),
|
|
|
+ * VARIABLES_AND_OPERATIONS)
|
|
|
+ */
|
|
|
+ {"-myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"+myInt", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"-myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"+myOpp3()", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"-e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"+e1", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(EVENT_VALUE_REFERENCE_EXPRESSION), EVENTS)
|
|
|
+ */
|
|
|
+ {"valueof(e2)", Expression.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"valueof(myInt)", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"valueof(myOpp3())", Expression.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /*
|
|
|
+ * filter.put(key(VARIABLE_DEFINITION, TYPED_ELEMENT__TYPE),
|
|
|
+ * TYPES)
|
|
|
+ */
|
|
|
+ {"var x : integer", VariableDefinition.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"var x : e1", VariableDefinition.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ /* filter.put(key(REGULAR_EVENT_SPEC), EVENTS) */
|
|
|
+ {"e1 / myInt = 0", LocalReaction.class.getSimpleName(), INTERNAL_SCOPE, true}, //
|
|
|
+ {"myOpp(4) / myInt = 10", LocalReaction.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ {"myInt / myInt = 10", LocalReaction.class.getSimpleName(), INTERNAL_SCOPE, false}, //
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|